Skip to content

Commit bcd34da

Browse files
Merge 724bb74 into 0285f5f
2 parents 0285f5f + 724bb74 commit bcd34da

File tree

8 files changed

+385
-0
lines changed

8 files changed

+385
-0
lines changed

.changeset/late-cameras-shake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@module-federation/dts-plugin': patch
3+
---
4+
5+
Improve remote type declaration generation by creating virtual remote packages and wiring them through DTS manager flows for global declaration output.

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ describe('DTSManager advance usage', () => {
195195
{
196196
name: 'utils.d.ts',
197197
},
198+
{
199+
name: 'virtualRemotePackage.d.ts',
200+
},
198201
],
199202
name: 'lib',
200203
},

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ describe('DTSManager', () => {
148148
{
149149
name: 'utils.d.ts',
150150
},
151+
{
152+
name: 'virtualRemotePackage.d.ts',
153+
},
151154
],
152155
name: 'lib',
153156
},
@@ -272,6 +275,9 @@ describe('DTSManager', () => {
272275
{
273276
name: 'utils.d.ts',
274277
},
278+
{
279+
name: 'virtualRemotePackage.d.ts',
280+
},
275281
],
276282
name: 'lib',
277283
},
@@ -436,6 +442,9 @@ describe('DTSManager', () => {
436442
{
437443
name: 'utils.d.ts',
438444
},
445+
{
446+
name: 'virtualRemotePackage.d.ts',
447+
},
439448
],
440449
name: 'lib',
441450
},
@@ -579,6 +588,9 @@ describe('DTSManager', () => {
579588
{
580589
name: 'utils.d.ts',
581590
},
591+
{
592+
name: 'virtualRemotePackage.d.ts',
593+
},
582594
],
583595
name: 'lib',
584596
},

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
import { fileLog, logger } from '../../server';
3131
import { axiosGet, cloneDeepOptions, isDebugMode } from './utils';
3232
import { UpdateMode } from '../../server/constant';
33+
import { syncRemoteTypesPackage } from './virtualRemotePackage';
3334

3435
export const MODULE_DTS_MANAGER_IDENTIFIER = 'MF DTS Manager';
3536

@@ -436,6 +437,21 @@ class DTSManager {
436437
const { downloadPromisesResult, hostOptions } =
437438
await this.consumeArchiveTypes(options.host);
438439

440+
await Promise.all(
441+
downloadPromisesResult.map(async (item) => {
442+
if (item.status === 'rejected' || !item.value) {
443+
return;
444+
}
445+
446+
const [alias, destinationPath] = item.value;
447+
await syncRemoteTypesPackage({
448+
context: hostOptions.context,
449+
remoteAlias: alias,
450+
remoteTypesFolder: destinationPath,
451+
});
452+
}),
453+
);
454+
439455
// download apiTypes
440456
if (hostOptions.consumeAPITypes) {
441457
await Promise.all(
@@ -523,6 +539,11 @@ class DTSManager {
523539
zipUrl: remoteTarPath || requiredRemoteInfo.zipUrl,
524540
},
525541
);
542+
await syncRemoteTypesPackage({
543+
context: hostOptions.context,
544+
remoteAlias: _alias,
545+
remoteTypesFolder: destinationPath,
546+
});
526547
const addNew = await this.downloadAPITypes(
527548
requiredRemoteInfo,
528549
destinationPath,

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ describe('generateTypesInChildProcess', () => {
160160
{
161161
name: 'utils.d.ts',
162162
},
163+
{
164+
name: 'virtualRemotePackage.d.ts',
165+
},
163166
],
164167
name: 'lib',
165168
},

packages/dts-plugin/src/core/lib/typeScriptCompiler.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,9 @@ describe('typeScriptCompiler', () => {
361361
{
362362
name: 'utils.d.ts',
363363
},
364+
{
365+
name: 'virtualRemotePackage.d.ts',
366+
},
364367
],
365368
name: 'lib',
366369
},
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import fs from 'fs';
2+
import { mkdtemp, writeFile } from 'fs/promises';
3+
import path from 'path';
4+
import { tmpdir } from 'os';
5+
import fse from 'fs-extra';
6+
import { afterEach, describe, expect, it } from 'vitest';
7+
8+
import { syncRemoteTypesPackage } from './virtualRemotePackage';
9+
10+
const createTempContext = async () => {
11+
const context = await mkdtemp(path.join(tmpdir(), 'mf-dts-virtual-package-'));
12+
await fse.ensureDir(path.join(context, 'node_modules'));
13+
return context;
14+
};
15+
16+
describe('syncRemoteTypesPackage', () => {
17+
const contexts: string[] = [];
18+
19+
afterEach(async () => {
20+
await Promise.all(contexts.map((context) => fse.remove(context)));
21+
contexts.length = 0;
22+
});
23+
24+
it('creates virtual package files for remote declarations', async () => {
25+
const context = await createTempContext();
26+
contexts.push(context);
27+
28+
const remoteAlias = 'remote1';
29+
const remoteTypesFolder = path.join(context, '@mf-types', remoteAlias);
30+
await fse.ensureDir(path.join(remoteTypesFolder, 'nested'));
31+
await fse.ensureDir(path.join(remoteTypesFolder, 'node_modules', 'react'));
32+
await writeFile(path.join(remoteTypesFolder, 'index.d.ts'), 'export {};');
33+
await writeFile(path.join(remoteTypesFolder, 'Button.d.ts'), 'export {};');
34+
await writeFile(
35+
path.join(remoteTypesFolder, 'nested', 'Card.d.ts'),
36+
'export {};',
37+
);
38+
await writeFile(
39+
path.join(remoteTypesFolder, 'node_modules', 'react', 'index.d.ts'),
40+
'export {};',
41+
);
42+
43+
const created = await syncRemoteTypesPackage({
44+
context,
45+
remoteAlias,
46+
remoteTypesFolder,
47+
});
48+
49+
expect(created).toBe(true);
50+
expect(
51+
fs.existsSync(
52+
path.join(context, 'node_modules', remoteAlias, 'index.d.ts'),
53+
),
54+
).toBe(true);
55+
expect(
56+
fs.existsSync(
57+
path.join(context, 'node_modules', remoteAlias, 'Button.d.ts'),
58+
),
59+
).toBe(true);
60+
expect(
61+
fs.existsSync(
62+
path.join(context, 'node_modules', remoteAlias, 'nested', 'Card.d.ts'),
63+
),
64+
).toBe(true);
65+
expect(
66+
fs.existsSync(
67+
path.join(
68+
context,
69+
'node_modules',
70+
remoteAlias,
71+
'node_modules',
72+
'react',
73+
'index.d.ts',
74+
),
75+
),
76+
).toBe(false);
77+
78+
const buttonDeclaration = await fse.readFile(
79+
path.join(context, 'node_modules', remoteAlias, 'Button.d.ts'),
80+
'utf-8',
81+
);
82+
expect(buttonDeclaration).toContain(
83+
"export * from '../../@mf-types/remote1/Button';",
84+
);
85+
});
86+
87+
it('skips overwriting existing non-managed packages', async () => {
88+
const context = await createTempContext();
89+
contexts.push(context);
90+
91+
const remoteAlias = 'remote2';
92+
const remoteTypesFolder = path.join(context, '@mf-types', remoteAlias);
93+
await fse.ensureDir(remoteTypesFolder);
94+
await writeFile(path.join(remoteTypesFolder, 'index.d.ts'), 'export {};');
95+
96+
const existingPackagePath = path.join(context, 'node_modules', remoteAlias);
97+
await fse.ensureDir(existingPackagePath);
98+
await writeFile(
99+
path.join(existingPackagePath, 'package.json'),
100+
JSON.stringify({ name: remoteAlias }),
101+
);
102+
103+
const created = await syncRemoteTypesPackage({
104+
context,
105+
remoteAlias,
106+
remoteTypesFolder,
107+
});
108+
109+
expect(created).toBe(false);
110+
expect(
111+
fs.existsSync(path.join(existingPackagePath, '.mf-types-generated')),
112+
).toBe(false);
113+
});
114+
115+
it('rebuilds previously generated virtual package', async () => {
116+
const context = await createTempContext();
117+
contexts.push(context);
118+
119+
const remoteAlias = 'remote3';
120+
const remoteTypesFolder = path.join(context, '@mf-types', remoteAlias);
121+
await fse.ensureDir(remoteTypesFolder);
122+
await writeFile(
123+
path.join(remoteTypesFolder, 'OldModule.d.ts'),
124+
'export {};',
125+
);
126+
127+
await syncRemoteTypesPackage({
128+
context,
129+
remoteAlias,
130+
remoteTypesFolder,
131+
});
132+
133+
await fse.remove(path.join(remoteTypesFolder, 'OldModule.d.ts'));
134+
await writeFile(
135+
path.join(remoteTypesFolder, 'NewModule.d.ts'),
136+
'export {};',
137+
);
138+
139+
const created = await syncRemoteTypesPackage({
140+
context,
141+
remoteAlias,
142+
remoteTypesFolder,
143+
});
144+
145+
expect(created).toBe(true);
146+
expect(
147+
fs.existsSync(
148+
path.join(context, 'node_modules', remoteAlias, 'OldModule.d.ts'),
149+
),
150+
).toBe(false);
151+
expect(
152+
fs.existsSync(
153+
path.join(context, 'node_modules', remoteAlias, 'NewModule.d.ts'),
154+
),
155+
).toBe(true);
156+
});
157+
});

0 commit comments

Comments
 (0)