Skip to content

Commit ef96c4d

Browse files
authored
feat(dts-plugin): support exclude extract specify third party dts (#3692)
1 parent 25a5e5b commit ef96c4d

File tree

9 files changed

+81
-16
lines changed

9 files changed

+81
-16
lines changed

.changeset/proud-rings-kiss.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@module-federation/third-party-dts-extractor': patch
3+
'@module-federation/dts-plugin': patch
4+
'@module-federation/sdk': patch
5+
---
6+
7+
feat(dts-plugin): support exclude extract specify third party dts

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ const readTsConfig = (
6161
context,
6262
additionalFilesToCompile,
6363
outputDir,
64-
moduleFederationConfig,
6564
}: Required<RemoteOptions>,
6665
mapComponentsToExpose: Record<string, string>,
6766
): TsConfigJson => {
@@ -116,9 +115,18 @@ const readTsConfig = (
116115
rawTsConfigJson.compilerOptions || {};
117116
rawTsConfigJson.compilerOptions = restCompilerOptions;
118117

118+
const outDirWithoutTypesFolder = resolve(
119+
context,
120+
outputDir || configContent.options.outDir || 'dist',
121+
);
122+
119123
const filesToCompile = [
120124
...Object.values(mapComponentsToExpose),
121-
...configContent.fileNames.filter((filename) => filename.endsWith('.d.ts')),
125+
...configContent.fileNames.filter(
126+
(filename) =>
127+
filename.endsWith('.d.ts') &&
128+
!filename.startsWith(outDirWithoutTypesFolder),
129+
),
122130
...additionalFilesToCompile,
123131
];
124132

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

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ import { ThirdPartyExtractor } from '@module-federation/third-party-dts-extracto
88
import { HostOptions, RemoteInfo } from '../interfaces/HostOptions';
99
import { RemoteOptions } from '../interfaces/RemoteOptions';
1010
import { downloadTypesArchive } from './archiveHandler';
11-
import {
12-
retrieveHostConfig,
13-
retrieveRemoteInfo,
14-
} from '../configurations/hostPlugin';
1511

1612
vi.mock('axios');
1713
vi.mock('fs/promises');
@@ -452,6 +448,7 @@ describe('DTSManager General Tests', () => {
452448
inferPkgDir: vi.fn(),
453449
collectPkgs: vi.fn(),
454450
copyDts: vi.fn().mockResolvedValue(undefined),
451+
exclude: [],
455452
}));
456453

457454
// Add the existing alias to the loadedRemoteAPIAlias set

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,9 @@ class DTSManager {
318318
);
319319
try {
320320
const existedFile = fs.readFileSync(apiTypeFileName, 'utf-8');
321-
const existedImports = new ThirdPartyExtractor('').collectTypeImports(
322-
existedFile,
323-
);
321+
const existedImports = new ThirdPartyExtractor({
322+
destDir: '',
323+
}).collectTypeImports(existedFile);
324324
existedImports.forEach((existedImport) => {
325325
const alias = existedImport
326326
.split('./')

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

+8-4
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,14 @@ export const compileTs = async (
177177
);
178178
try {
179179
const mfTypePath = retrieveMfTypesPath(tsConfig, remoteOptions);
180-
const thirdPartyExtractor = new ThirdPartyExtractor(
181-
resolve(mfTypePath, 'node_modules'),
182-
remoteOptions.context,
183-
);
180+
const thirdPartyExtractor = new ThirdPartyExtractor({
181+
destDir: resolve(mfTypePath, 'node_modules'),
182+
context: remoteOptions.context,
183+
exclude:
184+
typeof remoteOptions.extractThirdParty === 'object'
185+
? remoteOptions.extractThirdParty.exclude
186+
: undefined,
187+
});
184188
const execPromise = util.promisify(exec);
185189
const cmd = `npx ${remoteOptions.compilerInstance} --project ${tempTsConfigJsonPath}`;
186190
try {

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

+5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ export function cloneDeepOptions(options: DTSManagerOptions) {
133133
if (typeof value === 'function') {
134134
return false;
135135
}
136+
if (key === 'extractThirdParty' && Array.isArray(value)) {
137+
return value.map((item) => {
138+
return item.toString();
139+
});
140+
}
136141
});
137142
}
138143

packages/sdk/src/types/plugins/ModuleFederationPlugin.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,11 @@ export interface DtsRemoteOptions {
167167
compileInChildProcess?: boolean;
168168
compilerInstance?: 'tsc' | 'vue-tsc' | 'tspc' | string;
169169
generateAPITypes?: boolean;
170-
extractThirdParty?: boolean;
170+
extractThirdParty?:
171+
| boolean
172+
| {
173+
exclude?: Array<string | RegExp>;
174+
};
171175
extractRemoteTypes?: boolean;
172176
abortOnError?: boolean;
173177
}

packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import { ThirdPartyExtractor } from './ThirdPartyExtractor';
66
describe('ThirdPartyExtractor', () => {
77
const projectRoot = join(__dirname, '..', '..', '..');
88
const destDir = join(projectRoot, 'dist', 'third-party-extractor');
9-
const thirdPartyExtractor = new ThirdPartyExtractor(destDir, projectRoot);
9+
const thirdPartyExtractor = new ThirdPartyExtractor({
10+
destDir,
11+
context: projectRoot,
12+
exclude: ['ignore-pkg', /ignore-pkg2-/, /ignore-pkg3/.toString()],
13+
});
1014

1115
it('should correctly infer pkg dir with types field in package.json', () => {
1216
const tsupDir = thirdPartyExtractor.inferPkgDir('tsup');
@@ -52,4 +56,14 @@ describe('ThirdPartyExtractor', () => {
5256
expect(fs.existsSync(join(destDir, 'tsup'))).toEqual(true);
5357
expect(fs.existsSync(join(destDir, '@types/react'))).toEqual(true);
5458
});
59+
60+
it('exclude pkg', async () => {
61+
const excludePkg = ['ignore-pkg', 'ignore-pkg2-subpath', 'ignore-pkg3'];
62+
excludePkg.forEach((pkg) => {
63+
thirdPartyExtractor.addPkgs(pkg, `${pkg}-dir`);
64+
});
65+
expect(
66+
Object.keys(thirdPartyExtractor.pkgs).some((p) => excludePkg.includes(p)),
67+
).toEqual(false);
68+
});
5569
});

packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,49 @@ const ignoredPkgs = ['typescript'];
1010
const isNodeUtils = (pkgJsonPath: string, importPath: string) => {
1111
return pkgJsonPath === importPath;
1212
};
13+
14+
type ThirdPartyExtractorOptions = {
15+
destDir: string;
16+
context?: string;
17+
exclude?: Array<string | RegExp>;
18+
};
19+
1320
class ThirdPartyExtractor {
1421
pkgs: Record<string, string>;
1522
pattern: RegExp;
1623
context: string;
1724
destDir: string;
25+
exclude: Array<string | RegExp>;
1826

19-
constructor(destDir: string, context = process.cwd()) {
27+
constructor({
28+
destDir,
29+
context = process.cwd(),
30+
exclude = [],
31+
}: ThirdPartyExtractorOptions) {
2032
this.destDir = destDir;
2133
this.context = context;
2234
this.pkgs = {};
2335
this.pattern = /(from|import\()\s*['"]([^'"]+)['"]/g;
36+
this.exclude = exclude;
2437
}
2538

2639
addPkgs(pkgName: string, dirName: string): void {
2740
if (ignoredPkgs.includes(pkgName)) {
2841
return;
2942
}
43+
44+
if (
45+
this.exclude.some((pattern) => {
46+
if (typeof pattern === 'string') {
47+
return new RegExp(pattern).test(pkgName);
48+
} else {
49+
return pattern.test(pkgName);
50+
}
51+
})
52+
) {
53+
return;
54+
}
55+
3056
this.pkgs[pkgName] = dirName;
3157
}
3258

0 commit comments

Comments
 (0)