diff --git a/src/rollup/plugins/externals.ts b/src/rollup/plugins/externals.ts index 8772732e52..01cd39143a 100644 --- a/src/rollup/plugins/externals.ts +++ b/src/rollup/plugins/externals.ts @@ -183,7 +183,7 @@ export function externals (opts: NodeExternalsOptions): Plugin { const isNewer = semver.gt(v2, v1) // Warn about major version differences - const getMajor = v => v.split('.').filter(s => s !== '0')[0] + const getMajor = (v: string) => v.split('.').filter(s => s !== '0')[0] if (getMajor(v1) !== getMajor(v2)) { const warn = `Multiple major versions of package \`${pkgName}\` are being externalized. Picking latest version:\n\n` + [ ` ${isNewer ? '-' : '+'} ` + existingPkgDir + '@' + v1, @@ -195,13 +195,14 @@ export function externals (opts: NodeExternalsOptions): Plugin { } } - // Exclude older version files - if (isNewer) { - ignoreDirs.push(existingPkgDir) - } else { - ignoreDirs.push(pkgDir) - pkgDir = existingPkgDir // Update for tracedPackages + const [newerDir, olderDir] = isNewer ? [pkgDir, existingPkgDir] : [existingPkgDir, pkgDir] + // Try to map traced files from one package to another for minor/patch versions + if (getMajor(v1) === getMajor(v2)) { + tracedFiles = tracedFiles.map(f => f.startsWith(olderDir + '/') ? f.replace(olderDir, newerDir) : f) } + // Exclude older version files + ignoreDirs.push(olderDir + '/') + pkgDir = newerDir // Update for tracedPackages } // Add to traced packages @@ -224,9 +225,13 @@ export function externals (opts: NodeExternalsOptions): Plugin { if (!await isFile(file)) { return } const src = resolve(opts.traceOptions.base, file) const { pkgName, subpath } = parseNodeModulePath(file) - const dst = resolve(opts.outDir, `node_modules/${pkgName}/${subpath}`) + const dst = resolve(opts.outDir, `node_modules/${pkgName + subpath}`) await fsp.mkdir(dirname(dst), { recursive: true }) - await fsp.copyFile(src, dst) + try { + await fsp.copyFile(src, dst) + } catch (err) { + consola.warn(`Could not resolve \`${src}\`. Skipping.`) + } } // Write traced files diff --git a/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/index.mjs b/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/index.mjs index ff603d7009..c9e08004a5 100644 --- a/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/index.mjs +++ b/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/index.mjs @@ -1 +1 @@ -export default '2.0.0'; +export default '2.0.1'; diff --git a/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/package.json b/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/package.json index 35693047a5..bfb99596eb 100644 --- a/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/package.json +++ b/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/package.json @@ -1,5 +1,8 @@ { "name": "nitro-lib", - "version": "2.0.0", - "exports": "./index.mjs" + "version": "2.0.1", + "exports": { + ".": "./index.mjs", + "./subpath": "./subpath.mjs" + } } diff --git a/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/subpath.mjs b/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/subpath.mjs new file mode 100644 index 0000000000..c9e08004a5 --- /dev/null +++ b/test/fixture/_/node_modules/nitro-dep-b/node_modules/nitro-lib/subpath.mjs @@ -0,0 +1 @@ +export default '2.0.1'; diff --git a/test/fixture/_/node_modules/nitro-lib/index.mjs b/test/fixture/_/node_modules/nitro-lib/index.mjs index c9e08004a5..ff603d7009 100644 --- a/test/fixture/_/node_modules/nitro-lib/index.mjs +++ b/test/fixture/_/node_modules/nitro-lib/index.mjs @@ -1 +1 @@ -export default '2.0.1'; +export default '2.0.0'; diff --git a/test/fixture/_/node_modules/nitro-lib/package.json b/test/fixture/_/node_modules/nitro-lib/package.json index 2163d64469..81618a9dc9 100644 --- a/test/fixture/_/node_modules/nitro-lib/package.json +++ b/test/fixture/_/node_modules/nitro-lib/package.json @@ -1,5 +1,8 @@ { "name": "nitro-lib", - "version": "2.0.1", - "exports": "./index.mjs" + "version": "2.0.0", + "exports": { + ".": "./index.mjs", + "./subpath": "./subpath.mjs" + } } diff --git a/test/fixture/_/node_modules/nitro-lib/subpath.mjs b/test/fixture/_/node_modules/nitro-lib/subpath.mjs new file mode 100644 index 0000000000..ff603d7009 --- /dev/null +++ b/test/fixture/_/node_modules/nitro-lib/subpath.mjs @@ -0,0 +1 @@ +export default '2.0.0'; diff --git a/test/fixture/routes/modules.ts b/test/fixture/routes/modules.ts index dc7c27e7a1..8231219c07 100644 --- a/test/fixture/routes/modules.ts +++ b/test/fixture/routes/modules.ts @@ -4,11 +4,14 @@ import depA from 'nitro-dep-a' import depB from 'nitro-dep-b' // @ts-ignore import depLib from 'nitro-lib' +// @ts-ignore +import subpathLib from 'nitro-lib/subpath' export default defineEventHandler(() => { return { depA, depB, - depLib + depLib, + subpathLib } }) diff --git a/test/tests.ts b/test/tests.ts index 396b05eba0..6edacb53f9 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -185,7 +185,7 @@ export function testNitro (ctx: Context, getHandler: () => TestHandler | Promise it('resolve module version conflicts', async () => { const { data } = await callHandler({ url: '/modules' }) - expect(data).toMatchObject({ depA: '2.0.1', depB: '2.0.1', depLib: '2.0.1' }) + expect(data).toMatchObject({ depA: '2.0.1', depB: '2.0.1', depLib: '2.0.1', subpathLib: '2.0.1' }) }) } }