Skip to content

Commit 35d925b

Browse files
authored
fix(dts-plugin): support remoteTypeUrls option which allow user to specify the remote types url (#3532)
1 parent cbd5b7e commit 35d925b

File tree

17 files changed

+210
-64
lines changed

17 files changed

+210
-64
lines changed

.changeset/clean-pets-kick.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@module-federation/dts-plugin': patch
3+
'@module-federation/sdk': patch
4+
---
5+
6+
feat(dts-plugin): support remoteTypeUrls option which allow user to specify the remote types url

.changeset/curly-bears-marry.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@module-federation/sdk": patch
3+
"@module-federation/dts-plugin": patch
4+
---
5+
6+
fix(dts-plugin): support parse @scope@manifest-url.json entry

.github/workflows/e2e-modern-ssr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
run: |
4848
lsof -ti tcp:3050,3051,3052,3053,3054,3055,3056 | xargs -r kill &&
4949
pnpm run app:modern:dev &
50-
sleep 1 &&
50+
sleep 30 &&
5151
npx wait-on http://127.0.0.1:3050/ &&
5252
npx wait-on http://127.0.0.1:3051/ &&
5353
npx wait-on http://127.0.0.1:3052/ &&

apps/website-new/docs/en/configure/dts.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ When configuring `generateTypes` to `true`, the following configuration will be
4848
{
4949
"generateAPITypes": true,
5050
"abortOnError": false,
51-
"extractThirdParty": true,
52-
"extractRemoteTypes": true,
51+
"extractThirdParty": false,
52+
"extractRemoteTypes": false,
5353
"compileInChildProcess": true
5454
}
5555
```

apps/website-new/docs/zh/configure/dts.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ interface DtsRemoteOptions {
4747
{
4848
"generateAPITypes": true,
4949
"abortOnError": false,
50-
"extractThirdParty": true,
51-
"extractRemoteTypes": true,
50+
"extractThirdParty": false,
51+
"extractRemoteTypes": false,
5252
"compileInChildProcess": true
5353
}
5454
```

packages/dts-plugin/src/core/configurations/hostPlugin.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ describe('hostPlugin', () => {
4141
abortOnError: true,
4242
consumeAPITypes: false,
4343
runtimePkgs: [],
44+
remoteTypeUrls: {},
4445
});
4546

4647
expect(mapRemotesToDownload).toStrictEqual({
@@ -66,6 +67,7 @@ describe('hostPlugin', () => {
6667
abortOnError: true,
6768
consumeAPITypes: false,
6869
runtimePkgs: [],
70+
remoteTypeUrls: {},
6971
};
7072

7173
const { hostOptions, mapRemotesToDownload } =

packages/dts-plugin/src/core/configurations/hostPlugin.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
MANIFEST_EXT,
32
parseEntry,
43
ENCODE_NAME_PREFIX,
54
decodeName,
@@ -18,6 +17,7 @@ const defaultOptions = {
1817
abortOnError: true,
1918
consumeAPITypes: false,
2019
runtimePkgs: [],
20+
remoteTypeUrls: {},
2121
} satisfies Partial<HostOptions>;
2222

2323
const buildZipUrl = (hostOptions: Required<HostOptions>, url: string) => {
@@ -45,6 +45,7 @@ export const retrieveRemoteInfo = (options: {
4545
remote: string;
4646
}): RemoteInfo => {
4747
const { hostOptions, remoteAlias, remote } = options;
48+
const { remoteTypeUrls } = hostOptions;
4849
let decodedRemote = remote;
4950
if (decodedRemote.startsWith(ENCODE_NAME_PREFIX)) {
5051
decodedRemote = decodeName(decodedRemote, ENCODE_NAME_PREFIX);
@@ -59,13 +60,26 @@ export const retrieveRemoteInfo = (options: {
5960
? decodedRemote
6061
: '';
6162

62-
const zipUrl = url ? buildZipUrl(hostOptions, url) : '';
63+
let zipUrl = '';
64+
let apiTypeUrl = '';
65+
const name = parsedInfo.name || remoteAlias;
66+
if (typeof remoteTypeUrls === 'object' && remoteTypeUrls[name]) {
67+
zipUrl = remoteTypeUrls[name].zip;
68+
apiTypeUrl = remoteTypeUrls[name].api;
69+
}
70+
if (!zipUrl && url) {
71+
zipUrl = buildZipUrl(hostOptions, url);
72+
}
73+
74+
if (!apiTypeUrl && zipUrl) {
75+
apiTypeUrl = buildApiTypeUrl(zipUrl);
76+
}
6377

6478
return {
65-
name: parsedInfo.name || remoteAlias,
79+
name,
6680
url: url,
6781
zipUrl,
68-
apiTypeUrl: buildApiTypeUrl(zipUrl),
82+
apiTypeUrl,
6983
alias: remoteAlias,
7084
};
7185
};

packages/dts-plugin/src/core/lib/DTSManager.ts

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import ansiColors from 'ansi-colors';
21
import path from 'path';
32
import { rm } from 'fs/promises';
43
import fs from 'fs';
4+
import fse from 'fs-extra';
55
import {
66
MANIFEST_EXT,
77
Manifest,
@@ -103,21 +103,35 @@ class DTSManager {
103103

104104
const mfTypesPath = retrieveMfTypesPath(tsConfig, remoteOptions);
105105

106-
if (hasRemotes) {
107-
const tempHostOptions = {
108-
moduleFederationConfig: remoteOptions.moduleFederationConfig,
109-
typesFolder: path.join(mfTypesPath, 'node_modules'),
110-
remoteTypesFolder:
111-
remoteOptions?.hostRemoteTypesFolder || remoteOptions.typesFolder,
112-
deleteTypesFolder: true,
113-
context: remoteOptions.context,
114-
implementation: remoteOptions.implementation,
115-
abortOnError: false,
116-
};
117-
await this.consumeArchiveTypes(tempHostOptions);
106+
if (hasRemotes && this.options.host) {
107+
try {
108+
const { hostOptions } = retrieveHostConfig(this.options.host);
109+
const remoteTypesFolder = path.resolve(
110+
hostOptions.context,
111+
hostOptions.typesFolder,
112+
);
113+
114+
const targetDir = path.join(mfTypesPath, 'node_modules');
115+
if (fs.existsSync(remoteTypesFolder)) {
116+
const targetFolder = path.resolve(remoteOptions.context, targetDir);
117+
await fse.ensureDir(targetFolder);
118+
await fse.copy(remoteTypesFolder, targetFolder, { overwrite: true });
119+
}
120+
} catch (err) {
121+
if (this.options.host?.abortOnError === false) {
122+
fileLog(
123+
`Unable to copy remote types, ${err}`,
124+
'extractRemoteTypes',
125+
'error',
126+
);
127+
} else {
128+
throw err;
129+
}
130+
}
118131
}
119132
}
120133

134+
// it must execute after consumeTypes
121135
async generateTypes() {
122136
try {
123137
const { options } = this;
@@ -134,6 +148,21 @@ class DTSManager {
134148
return;
135149
}
136150

151+
if (tsConfig.compilerOptions.tsBuildInfoFile) {
152+
try {
153+
const tsBuildInfoFile = path.resolve(
154+
remoteOptions.context,
155+
tsConfig.compilerOptions.tsBuildInfoFile,
156+
);
157+
const mfTypesPath = retrieveMfTypesPath(tsConfig, remoteOptions);
158+
if (!fs.existsSync(mfTypesPath)) {
159+
fs.rmSync(tsBuildInfoFile, { force: true });
160+
}
161+
} catch (e) {
162+
//noop
163+
}
164+
}
165+
137166
await this.extractRemoteTypes({
138167
remoteOptions,
139168
tsConfig,
@@ -150,7 +179,6 @@ class DTSManager {
150179
apiTypesPath = retrieveMfAPITypesPath(tsConfig, remoteOptions);
151180
fs.writeFileSync(apiTypesPath, apiTypes);
152181
}
153-
154182
try {
155183
if (remoteOptions.deleteTypesFolder) {
156184
await rm(retrieveMfTypesPath(tsConfig, remoteOptions), {
@@ -167,7 +195,7 @@ class DTSManager {
167195
} catch (error) {
168196
if (this.options.remote?.abortOnError === false) {
169197
if (this.options.displayErrorInTerminal) {
170-
logger.error(`Unable to compile federated types${error}`);
198+
logger.error(`Unable to compile federated types ${error}`);
171199
}
172200
} else {
173201
throw error;
@@ -182,6 +210,9 @@ class DTSManager {
182210
if (!remoteInfo.url.includes(MANIFEST_EXT)) {
183211
return remoteInfo as Required<RemoteInfo>;
184212
}
213+
if (remoteInfo.zipUrl) {
214+
return remoteInfo as Required<RemoteInfo>;
215+
}
185216
const url = remoteInfo.url;
186217
const res = await axiosGet(url);
187218
const manifestJson = res.data as unknown as Manifest;

packages/dts-plugin/src/core/lib/DtsWorker.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ export class DtsWorker {
1212
rpcWorker: RpcWorker<RpcMethod>;
1313
private _options: DtsWorkerOptions;
1414
private _res: Promise<any>;
15-
1615
constructor(options: DtsWorkerOptions) {
1716
this._options = cloneDeepOptions(options);
18-
1917
this.removeUnSerializationOptions();
2018
this.rpcWorker = createRpcWorker(
2119
path.resolve(__dirname, './fork-generate-dts.js'),

packages/dts-plugin/src/core/lib/utils.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,15 @@ export const isTSProject = (
124124

125125
export function cloneDeepOptions(options: DTSManagerOptions) {
126126
const excludeKeys = ['manifest', 'async'];
127-
return cloneDeepWith(options, (_value, key) => {
127+
128+
return cloneDeepWith(options, (value, key) => {
128129
// moduleFederationConfig.manifest may have un serialization options
129130
if (typeof key === 'string' && excludeKeys.includes(key)) {
130131
return false;
131132
}
133+
if (typeof value === 'function') {
134+
return false;
135+
}
132136
});
133137
}
134138

0 commit comments

Comments
 (0)