Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dts-plugin): optimize dev behavior #3424

Merged
merged 21 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a1f037a
fix(dts-plugin): only consume types in dev
2heal1 Jan 6, 2025
f4982f6
feat(dts-plugin): support pass headers when request types url
2heal1 Jan 6, 2025
bd366f5
fix: no emitAsset twice
2heal1 Jan 6, 2025
de42237
fix(dts-plugin): catch EEXIST error
2heal1 Jan 8, 2025
eff9da7
fix(dts-plugin): add debounce for emitDevFiles
2heal1 Jan 8, 2025
3a41985
fix: hash add hash
2heal1 Jan 8, 2025
fed84e7
fix(dts-plugin): generateTypes should after consumeTypes finished
2heal1 Jan 8, 2025
f773237
chore: execut callback if normalizedConsumeTypes is false
2heal1 Jan 8, 2025
1801215
fix(enhanced): no push ModuleFederationPlugin self
2heal1 Jan 8, 2025
29bedb3
fix(dts-plugin): dev plugin should apply after fetchPromise resolved
2heal1 Jan 8, 2025
ce96460
fix(dts-plugin): dev plugin should apply after generateTypesPromise r…
2heal1 Jan 9, 2025
b1bf0ae
fix(dts-plugin): set outputDir default value
2heal1 Jan 9, 2025
c229227
fix(dts-plugin): throw error while downloading types archive hit hist…
2heal1 Jan 9, 2025
380a848
chore: response may not have headers
2heal1 Jan 9, 2025
f7c7d0b
chore: remove useless code
2heal1 Jan 9, 2025
258b87f
chore(dts-plugin): change extractRemoteTypes default value as false
2heal1 Jan 9, 2025
2c90ce5
chore: revert
2heal1 Jan 9, 2025
b3bc730
chore: add log
2heal1 Jan 10, 2025
8b0da40
chore: add log
2heal1 Jan 10, 2025
c9658c9
fix(dts-plugin): use remoteTarPath first to fetch hot types
2heal1 Jan 13, 2025
120fc23
chore: remove useless changeset
2heal1 Jan 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/afraid-students-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/dts-plugin': patch
---

feat(dts-plugin): support pass headers when request types url
5 changes: 5 additions & 0 deletions .changeset/large-dogs-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/dts-plugin': patch
---

fix(dts-plugin): set outputDir default value
5 changes: 5 additions & 0 deletions .changeset/light-islands-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/dts-plugin': patch
---

fix(dts-plugin): use remoteTarPath first to fetch hot types
5 changes: 5 additions & 0 deletions .changeset/nine-toes-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/dts-plugin': patch
---

fix(dts-plugin): only consume types in dev
5 changes: 5 additions & 0 deletions .changeset/rare-cobras-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/dts-plugin': patch
---

fix(dts-plugin): throw error while downloading types archive hit historyApiFallback
5 changes: 5 additions & 0 deletions .changeset/sour-dolls-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/dts-plugin': patch
---

fix(dts-plugin): generateTypes should after consumeTypes finished
5 changes: 5 additions & 0 deletions .changeset/swift-deers-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/enhanced': patch
---

fix(enhanced): no push ModuleFederationPlugin self
5 changes: 5 additions & 0 deletions .changeset/tame-numbers-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/dts-plugin': patch
---

fix(dts-plugin): dev plugin should apply after fetchPromise resolved
37 changes: 29 additions & 8 deletions packages/dts-plugin/src/core/lib/DTSManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class DTSManager {
logger.success('Federated types created correctly');
} catch (error) {
if (this.options.remote?.abortOnError === false) {
logger.error(`Unable to compile federated types, ${error}`);
logger.error(`Unable to compile federated types${error}`);
} else {
throw error;
}
Expand Down Expand Up @@ -263,10 +263,11 @@ class DTSManager {
const filePath = path.join(destinationPath, REMOTE_API_TYPES_FILE_NAME);
fs.writeFileSync(filePath, apiTypeFile);
this.loadedRemoteAPIAlias.add(remoteInfo.alias);
fileLog(`success`, 'downloadAPITypes', 'info');
} catch (err) {
fileLog(
`Unable to download "${remoteInfo.name}" api types, ${err}`,
'consumeTargetRemotes',
'downloadAPITypes',
'error',
);
}
Expand Down Expand Up @@ -420,17 +421,17 @@ class DTSManager {

async updateTypes(options: UpdateTypesOptions): Promise<void> {
try {
// can use remoteTarPath directly in the future
const {
remoteName,
updateMode,
remoteTarPath,
remoteInfo: updatedRemoteInfo,
once,
} = options;
const hostName = this.options?.host?.moduleFederationConfig?.name;
fileLog(
`updateTypes options:, ${JSON.stringify(options, null, 2)}`,
'consumeTypes',
`options: ${JSON.stringify(options, null, 2)};\nhostName: ${hostName}`,
'updateTypes',
'info',
);
if (updateMode === UpdateMode.POSITIVE && remoteName === hostName) {
Expand All @@ -454,19 +455,39 @@ class DTSManager {
const consumeTypes = async (
requiredRemoteInfo: Required<RemoteInfo>,
) => {
fileLog(`consumeTypes start`, 'updateTypes', 'info');
if (!requiredRemoteInfo.zipUrl) {
throw new Error(
`Can not get ${requiredRemoteInfo.name}'s types archive url!`,
);
}
const [_alias, destinationPath] = await this.consumeTargetRemotes(
hostOptions,
requiredRemoteInfo,
{
...requiredRemoteInfo,
// use remoteTarPath first
zipUrl: remoteTarPath || requiredRemoteInfo.zipUrl,
},
);
await this.downloadAPITypes(requiredRemoteInfo, destinationPath);
fileLog(`consumeTypes end`, 'updateTypes', 'info');
};

fileLog(
`loadedRemoteInfo: ${JSON.stringify(loadedRemoteInfo, null, 2)}`,
'updateTypes',
'info',
);
if (!loadedRemoteInfo) {
const remoteInfo = Object.values(mapRemotesToDownload).find(
(item) => {
return item.name === remoteName;
},
);
fileLog(
`remoteInfo: ${JSON.stringify(remoteInfo, null, 2)}`,
'updateTypes',
'info',
);
if (remoteInfo) {
if (!this.remoteAliasMap[remoteInfo.alias]) {
const requiredRemoteInfo =
Expand Down Expand Up @@ -496,7 +517,7 @@ class DTSManager {
null,
2,
)}`,
'consumeTypes',
'updateTypes',
'info',
);
await consumeDynamicRemoteTypes();
Expand Down
13 changes: 13 additions & 0 deletions packages/dts-plugin/src/core/lib/archiveHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ export const downloadTypesArchive = (hostOptions: Required<HostOptions>) => {
const response = await axiosGet(url, {
responseType: 'arraybuffer',
}).catch(downloadErrorLogger(destinationFolder, url));
if (
typeof response.headers?.['content-type'] === 'string' &&
response.headers['content-type'].includes('text/html')
) {
throw new Error(
`${url} receives invalid content-type: ${response.headers['content-type']}`,
);
}

try {
if (hostOptions.deleteTypesFolder) {
Expand All @@ -81,6 +89,11 @@ export const downloadTypesArchive = (hostOptions: Required<HostOptions>) => {

const zip = new AdmZip(Buffer.from(response.data));
zip.extractAllTo(destinationPath, true);
fileLog(
`zip.extractAllTo success destinationPath: ${destinationPath}; url: ${url}`,
'downloadTypesArchive',
'info',
);
return [destinationFolder, destinationPath];
} catch (error: any) {
fileLog(
Expand Down
3 changes: 0 additions & 3 deletions packages/dts-plugin/src/core/lib/typeScriptCompiler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,6 @@ describe('typeScriptCompiler', () => {
{
name: 'GenerateTypesPlugin.d.ts',
},
{
name: 'TypesPlugin.d.ts',
},
{
name: 'utils.d.ts',
},
Expand Down
2 changes: 1 addition & 1 deletion packages/dts-plugin/src/core/lib/typeScriptCompiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function writeTempTsConfig(
const createHash = (contents: string) => {
return crypto.createHash('md5').update(contents).digest('hex');
};
const hash = createHash(`${JSON.stringify(tsConfig)}${name}`);
const hash = createHash(`${JSON.stringify(tsConfig)}${name}${Date.now()}`);
const tempTsConfigJsonPath = resolve(
context,
'node_modules',
Expand Down
19 changes: 17 additions & 2 deletions packages/dts-plugin/src/core/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from 'path';
import axios, { type AxiosRequestConfig } from 'axios';
import http from 'http';
import https from 'https';
import { moduleFederationPlugin } from '@module-federation/sdk';
import { moduleFederationPlugin, getProcessEnv } from '@module-federation/sdk';
import ansiColors from 'ansi-colors';
import { retrieveRemoteConfig } from '../configurations/remotePlugin';
import { HostOptions } from '../interfaces/HostOptions';
Expand Down Expand Up @@ -132,8 +132,23 @@ export function cloneDeepOptions(options: DTSManagerOptions) {
});
}

const getEnvHeaders = (): Record<string, string> => {
const headersStr = getProcessEnv()['MF_ENV_HEADERS'] || '{}';

return {
...JSON.parse(headersStr),
};
};

export async function axiosGet(url: string, config?: AxiosRequestConfig) {
const httpAgent = new http.Agent({ family: 4 });
const httpsAgent = new https.Agent({ family: 4 });
return axios.get(url, { httpAgent, httpsAgent, ...config });
return axios.get(url, {
Dismissed Show dismissed Hide dismissed
httpAgent,
httpsAgent,
...{
headers: getEnvHeaders(),
},
...config,
});
}
21 changes: 19 additions & 2 deletions packages/dts-plugin/src/plugins/ConsumeTypesPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,33 @@ import {
type moduleFederationPlugin,
} from '@module-federation/sdk';
import { validateOptions, consumeTypes } from '../core/index';
import { isPrd } from './utils';

export class ConsumeTypesPlugin implements WebpackPluginInstance {
pluginOptions: moduleFederationPlugin.ModuleFederationPluginOptions;
dtsOptions: moduleFederationPlugin.PluginDtsOptions;
defaultOptions: moduleFederationPlugin.DtsHostOptions;
callback: () => void;

constructor(
pluginOptions: moduleFederationPlugin.ModuleFederationPluginOptions,
dtsOptions: moduleFederationPlugin.PluginDtsOptions,
defaultOptions: moduleFederationPlugin.DtsHostOptions,
callback: () => void,
) {
this.pluginOptions = pluginOptions;
this.dtsOptions = dtsOptions;
this.defaultOptions = defaultOptions;
this.callback = callback;
}

apply(compiler: Compiler) {
const { dtsOptions, defaultOptions, pluginOptions } = this;
const { dtsOptions, defaultOptions, pluginOptions, callback } = this;

if (isPrd()) {
callback();
return;
}

const normalizedConsumeTypes =
normalizeOptions<moduleFederationPlugin.DtsRemoteOptions>(
Expand All @@ -30,6 +40,7 @@ export class ConsumeTypesPlugin implements WebpackPluginInstance {
)(dtsOptions.consumeTypes);

if (!normalizedConsumeTypes) {
callback();
return;
}

Expand All @@ -46,6 +57,12 @@ export class ConsumeTypesPlugin implements WebpackPluginInstance {
validateOptions(finalOptions.host);

// only consume once , if remotes update types , DevPlugin will auto sync the latest types
consumeTypes(finalOptions);
consumeTypes(finalOptions)
.then(() => {
callback();
})
.catch(() => {
callback();
});
}
}
40 changes: 22 additions & 18 deletions packages/dts-plugin/src/plugins/DevPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'fs-extra';
import chalk from 'chalk';
import { type DevWorker, createDevWorker } from '../dev-worker';
import path from 'path';
import { createDevWorker } from '../dev-worker';
import {
moduleFederationPlugin,
normalizeOptions,
Expand All @@ -12,11 +12,12 @@ import {
getIPV4,
logger,
} from '../server';
import type { Compiler, WebpackPluginInstance } from 'webpack';
import path from 'path';
import { isDev } from './utils';
import { getCompilerOutputDir, isDev } from './utils';
import { isTSProject } from '../core/lib/utils';

import type { Compiler, WebpackPluginInstance } from 'webpack';
import type { DevWorker } from '../dev-worker';

enum PROCESS_EXIT_CODE {
SUCCESS = 0,
FAILURE = 1,
Expand All @@ -35,9 +36,14 @@ export class DevPlugin implements WebpackPluginInstance {
readonly name = 'MFDevPlugin';
private _options: moduleFederationPlugin.ModuleFederationPluginOptions;
private _devWorker?: DevWorker;
fetchTypesPromise: Promise<void>;

constructor(options: moduleFederationPlugin.ModuleFederationPluginOptions) {
constructor(
options: moduleFederationPlugin.ModuleFederationPluginOptions,
fetchTypesPromise: Promise<void>,
) {
this._options = options;
this.fetchTypesPromise = fetchTypesPromise;
}

static ensureLiveReloadEntry(
Expand Down Expand Up @@ -191,10 +197,7 @@ export class DevPlugin implements WebpackPluginInstance {
? undefined
: normalizedDtsOptions.implementation,
context: compiler.context,
outputDir: path.relative(
compiler.context,
compiler.outputPath || compiler.options.output.path,
),
outputDir: getCompilerOutputDir(compiler),
moduleFederationConfig: {
...this._options,
},
Expand Down Expand Up @@ -246,14 +249,15 @@ export class DevPlugin implements WebpackPluginInstance {
) {
remote.tsConfigPath = normalizedDtsOptions.tsConfigPath;
}

this._devWorker = createDevWorker({
name,
remote: remote,
host: host,
extraOptions: extraOptions,
disableLiveReload: normalizedDev.disableHotTypesReload,
disableHotTypesReload: normalizedDev.disableHotTypesReload,
this.fetchTypesPromise.then(() => {
this._devWorker = createDevWorker({
name,
remote: remote,
host: host,
extraOptions: extraOptions,
disableLiveReload: normalizedDev.disableHotTypesReload,
disableHotTypesReload: normalizedDev.disableHotTypesReload,
});
});

this._stopWhenSIGTERMOrSIGINT();
Expand Down
Loading
Loading