diff --git a/.changeset/chilled-eels-shout.md b/.changeset/chilled-eels-shout.md new file mode 100644 index 00000000000..b3c94b44e83 --- /dev/null +++ b/.changeset/chilled-eels-shout.md @@ -0,0 +1,5 @@ +--- +'@module-federation/third-party-dts-extractor': patch +--- + +fix(third-party-dts-extractor): correctly sets the source of the package types diff --git a/packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts b/packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts index 9a879d8b1f5..e5b2462054b 100644 --- a/packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts +++ b/packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts @@ -8,12 +8,17 @@ describe('ThirdPartyExtractor', () => { const destDir = join(projectRoot, 'dist', 'third-party-extractor'); const thirdPartyExtractor = new ThirdPartyExtractor(destDir, projectRoot); - it('should correctly infer pkg dir with types field in package.json', () => { + it("should correctly infer pkg's types dir with types/typings field in package.json", () => { const tsupDir = thirdPartyExtractor.inferPkgDir('tsup'); - const pkgJson = fs.readJSONSync(`${tsupDir}/package.json`); - expect(pkgJson.name).toBe('tsup'); - expect(Boolean(pkgJson.types || pkgJson.typings)).toEqual(true); + if (!tsupDir) { + throw new Error('tsup dir not found'); + } + + const dirContent = fs.readdirSync(tsupDir); + const dtsFiles = dirContent.filter((file) => file.endsWith('.d.ts')); + + expect(dtsFiles.length).toBeGreaterThan(0); }); it('should correctly infer pkg types dir without types field in package.json', () => { diff --git a/packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts b/packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts index 442e17b68c1..eba61f19555 100644 --- a/packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts +++ b/packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts @@ -2,7 +2,7 @@ import findPkg from 'find-pkg'; import fs from 'fs-extra'; import path from 'path'; import resolve from 'resolve'; -import { getTypedName } from './utils'; +import { getTypedName, getPackageRootDir } from './utils'; const ignoredPkgs = ['typescript']; @@ -48,7 +48,8 @@ class ThirdPartyExtractor { if (isNodeUtils(importEntry, importPath)) { return; } - const pkgJsonPath = findPkg.sync(importEntry) as string; + const packageDir = getPackageRootDir(importPath); + const pkgJsonPath = path.join(packageDir, 'package.json'); const dir = path.dirname(pkgJsonPath); const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) as Record< @@ -61,8 +62,9 @@ class ThirdPartyExtractor { } if (types) { - this.addPkgs(pkg.name, dir); - return dir; + const typesDir = path.dirname(path.resolve(dir, types)); + this.addPkgs(pkg.name, typesDir); + return typesDir; } else if (fs.existsSync(path.resolve(dir, 'index.d.ts'))) { this.addPkgs(pkg.name, dir); return dir; diff --git a/packages/third-party-dts-extractor/src/utils.ts b/packages/third-party-dts-extractor/src/utils.ts index d6b9e0cfe14..5c54e36f343 100644 --- a/packages/third-party-dts-extractor/src/utils.ts +++ b/packages/third-party-dts-extractor/src/utils.ts @@ -1,5 +1,33 @@ +import path from 'node:path'; + function getTypedName(name: string) { return `@types/${name.replace(/^@/, '').replace('/', '__')}`; } -export { getTypedName }; +function getPackageRootDir(packageName: string | undefined): string { + if (!packageName) { + throw new Error('No package name provided.'); + } + + let packageRootDir: string; + + try { + // First, try resolving the package's package.json + const packageJsonPath = require.resolve(`${packageName}/package.json`); + packageRootDir = path.dirname(packageJsonPath); + } catch (error) { + // If resolving package.json fails, fall back to resolving the package itself + try { + const packageEntryPath = require.resolve(packageName); + packageRootDir = path.dirname(packageEntryPath); + } catch (fallbackError) { + throw new Error( + `Could not resolve package "${packageName}" or its package.json.`, + ); + } + } + + return packageRootDir; +} + +export { getTypedName, getPackageRootDir };