diff --git a/src/doctor/rules/CJS_IMPORT_ESM.ts b/src/doctor/rules/CJS_IMPORT_ESM.ts index 880c5baa..6fad6008 100644 --- a/src/doctor/rules/CJS_IMPORT_ESM.ts +++ b/src/doctor/rules/CJS_IMPORT_ESM.ts @@ -1,13 +1,13 @@ -import type { IApi } from '../../types'; -import vm from 'vm'; import { chalk, winPath } from '@umijs/utils'; -import type { IDoctorReport } from '..'; -import { getPkgNameFromPath } from '../utils'; import enhancedResolve from 'enhanced-resolve'; +import vm from 'vm'; +import type { IDoctorReport } from '..'; +import type { IApi } from '../../types'; +import { getPkgNameFromPath } from '../../utils'; export default (api: IApi) => { const sandbox = vm.createContext({ require }); - let resolver: ReturnType; + let resolver: ReturnType<(typeof enhancedResolve)['create']['sync']>; api.describe({ // disable temporarily diff --git a/src/doctor/rules/PHANTOM_DEPS.ts b/src/doctor/rules/PHANTOM_DEPS.ts index 48ba65ed..cb125c12 100644 --- a/src/doctor/rules/PHANTOM_DEPS.ts +++ b/src/doctor/rules/PHANTOM_DEPS.ts @@ -1,7 +1,7 @@ import { chalk } from '@umijs/utils'; import type { IDoctorReport } from '..'; import type { IApi } from '../../types'; -import { getPkgNameFromPath } from '../utils'; +import { getPkgNameFromPath } from '../../utils'; export default (api: IApi) => { api.addImportsCheckup(({ file, imports, mergedAlias, mergedExternals }) => { diff --git a/src/doctor/utils.ts b/src/doctor/utils.ts deleted file mode 100644 index 7851ec56..00000000 --- a/src/doctor/utils.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function getPkgNameFromPath(p: string) { - return p.match(/^(?:@[a-z\d][\w-.]*\/)?[a-z\d][\w-.]*/i)?.[0]; -} diff --git a/src/prebundler/config.ts b/src/prebundler/config.ts index 91b1f0a3..bc99f9d9 100644 --- a/src/prebundler/config.ts +++ b/src/prebundler/config.ts @@ -6,6 +6,7 @@ import { winPath } from '@umijs/utils'; import path from 'path'; import { IApi, IFatherPreBundleConfig } from '../types'; import { + getDepPkgName, getDepPkgPath, getDtsInfoForPkgPath, getNestedTypeDepsForPkg, @@ -127,7 +128,7 @@ export function getConfig(opts: { // process deps config Object.entries(deps).forEach(([dep, depConfig]) => { // handle array deps - const depName = Array.isArray(deps) ? deps[parseInt(dep)] : dep; + let depName = Array.isArray(deps) ? deps[parseInt(dep)] : dep; depConfig = Array.isArray(deps) ? {} : depConfig; const depEntryPath = require.resolve(depName, { paths: [opts.cwd] }); @@ -135,6 +136,7 @@ export function getConfig(opts: { const depTypeInfo = depConfig.dts !== false ? getDtsInfoForPkgPath(depPkgPath) : null; const depPkg = require(depPkgPath); + depName = getDepPkgName(depName, depPkg); // generate bundle config config.deps[depEntryPath] = { @@ -147,7 +149,7 @@ export function getConfig(opts: { pkg: depPkg, output: path.resolve( opts.cwd, - `${output || DEFAULT_OUTPUT_DIR}/${depPkg.name}/index.js`, + `${output || DEFAULT_OUTPUT_DIR}/${depName}/index.js`, ), }; @@ -167,7 +169,7 @@ export function getConfig(opts: { } // prepare deps externals - depExternals[depPkg.name] = config.deps[depEntryPath].output; + depExternals[depName] = config.deps[depEntryPath].output; }); // process extraDtsDeps config diff --git a/src/utils.ts b/src/utils.ts index cad9d126..a9fe6cd2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ -import { pkgUp, chalk, logger as umiLogger } from '@umijs/utils'; +import { chalk, logger as umiLogger, pkgUp } from '@umijs/utils'; import Cache from 'file-system-cache'; -import path from 'path'; +import path, { isAbsolute } from 'path'; import { CACHE_PATH } from './constants'; import { IApi } from './types'; @@ -9,7 +9,7 @@ const caches: Record> = {}; /** * get file-system cache for specific namespace */ -export function getCache(ns: string): typeof caches['0'] { +export function getCache(ns: string): (typeof caches)['0'] { // return fake cache if cache disabled if (process.env.FATHER_CACHE === 'none') { return { set() {}, get() {}, setSync() {}, getSync() {} } as any; @@ -183,3 +183,18 @@ export const logger: Omit = new Proxy( }, }, ); + +export function isFilePath(path: string) { + return isAbsolute(path) || path.startsWith('.'); +} + +export function getPkgNameFromPath(p: string) { + return p.match(/^(?:@[a-z\d][\w-.]*\/)?[a-z\d][\w-.]*/i)?.[0]; +} + +export const getDepPkgName = (name: string, packageJson: { name: string }) => { + if (isFilePath(name)) { + return packageJson.name; + } + return getPkgNameFromPath(name) ?? name; +}; diff --git a/tests/fixtures/prebundle/npm-alias/.fatherrc.ts b/tests/fixtures/prebundle/npm-alias/.fatherrc.ts new file mode 100644 index 00000000..0051836c --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/.fatherrc.ts @@ -0,0 +1,5 @@ +export default { + prebundle: { + deps: ['a', 'a-alias'], + }, +}; diff --git a/tests/fixtures/prebundle/npm-alias/expect.ts b/tests/fixtures/prebundle/npm-alias/expect.ts new file mode 100644 index 00000000..1d85e265 --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/expect.ts @@ -0,0 +1,12 @@ +export default (files: Record) => { + expect(Object.keys(files)).toMatchInlineSnapshot(` + Array [ + "a/index.d.ts", + "a/index.js", + "a/package.json", + "a-alias/index.d.ts", + "a-alias/index.js", + "a-alias/package.json", + ] + `); +}; diff --git a/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/index.d.ts b/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/index.d.ts new file mode 100644 index 00000000..bac41a59 --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/index.d.ts @@ -0,0 +1 @@ +export type a = string; diff --git a/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/index.js b/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/index.js new file mode 100644 index 00000000..0ed5c300 --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/index.js @@ -0,0 +1 @@ +export default 'a'; diff --git a/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/package.json b/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/package.json new file mode 100644 index 00000000..1f66e3dd --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/node_modules/a-alias/package.json @@ -0,0 +1,8 @@ +{ + "name": "a", + "version": "0.0.1", + "main": "index.ts", + "typings": "index.d.ts", + "dependencies": { + } +} diff --git a/tests/fixtures/prebundle/npm-alias/node_modules/a/index.d.ts b/tests/fixtures/prebundle/npm-alias/node_modules/a/index.d.ts new file mode 100644 index 00000000..bac41a59 --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/node_modules/a/index.d.ts @@ -0,0 +1 @@ +export type a = string; diff --git a/tests/fixtures/prebundle/npm-alias/node_modules/a/index.js b/tests/fixtures/prebundle/npm-alias/node_modules/a/index.js new file mode 100644 index 00000000..0ed5c300 --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/node_modules/a/index.js @@ -0,0 +1 @@ +export default 'a'; diff --git a/tests/fixtures/prebundle/npm-alias/node_modules/a/package.json b/tests/fixtures/prebundle/npm-alias/node_modules/a/package.json new file mode 100644 index 00000000..1f66e3dd --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/node_modules/a/package.json @@ -0,0 +1,8 @@ +{ + "name": "a", + "version": "0.0.1", + "main": "index.ts", + "typings": "index.d.ts", + "dependencies": { + } +} diff --git a/tests/fixtures/prebundle/npm-alias/package.json b/tests/fixtures/prebundle/npm-alias/package.json new file mode 100644 index 00000000..13a5d849 --- /dev/null +++ b/tests/fixtures/prebundle/npm-alias/package.json @@ -0,0 +1,8 @@ +{ + "name": "npm-alias", + "version": "0.0.0", + "devDependencies": { + "a": "0.0.1", + "a-alias": "npm:a@0.0.1" + } +} diff --git a/tests/utils.test.ts b/tests/utils.test.ts index dfdb74c0..27b1676e 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -1,5 +1,5 @@ -import { logger } from '../src/utils'; import { logger as umiLogger } from '@umijs/utils'; +import { getDepPkgName, isFilePath, logger } from '../src/utils'; jest.mock('@umijs/utils', () => { const originalModule = jest.requireActual('@umijs/utils'); @@ -55,4 +55,43 @@ describe('logger', () => { process.env.NODE_ENV = originalEnv; }); + + describe(isFilePath.name, () => { + test('absolute', () => { + expect(isFilePath('/path/to/name')).toBe(true); + }); + + test('relative', () => { + expect(isFilePath('./name/test')).toBe(true); + }); + + test('module', () => { + expect(isFilePath('name')).toBe(false); + expect(isFilePath('@scope/name')).toBe(false); + }); + }); + + describe(getDepPkgName.name, () => { + test('normal module', () => { + expect(getDepPkgName('name', { name: 'test' })).toBe('name'); + expect(getDepPkgName('name/test', { name: 'test' })).toBe('name'); + }); + + test('scope module', () => { + expect(getDepPkgName('@scope/name', { name: 'test' })).toBe( + '@scope/name', + ); + expect(getDepPkgName('@scope/name/test', { name: 'test' })).toBe( + '@scope/name', + ); + }); + + test('absolute', () => { + expect(getDepPkgName('/path/to/name', { name: 'test' })).toBe('test'); + }); + + test('relative', () => { + expect(getDepPkgName('./name/test', { name: 'test' })).toBe('test'); + }); + }); });