From cb03c96ce6abbd76714e381c9252e667d7486e9f Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Tue, 29 Mar 2022 22:48:23 +0200 Subject: [PATCH] feat(externals): smartly pick latest version and warn only on two different major --- package.json | 2 ++ src/rollup/plugins/externals.ts | 30 ++++++++++++++++++++++++------ yarn.lock | 9 +++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f1b70811ae..9c814e1e1d 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "rollup-plugin-terser": "^7.0.2", "rollup-plugin-visualizer": "^5.6.0", "scule": "^0.2.1", + "semver": "^7.3.5", "serve-placeholder": "^1.2.4", "serve-static": "^1.14.2", "std-env": "^3.0.1", @@ -93,6 +94,7 @@ "@types/fs-extra": "^9.0.13", "@types/http-proxy": "^1.17.8", "@types/node-fetch": "^2.6.1", + "@types/semver": "^7.3.9", "@types/serve-static": "^1.13.10", "c8": "^7.11.0", "eslint": "^8.11.0", diff --git a/src/rollup/plugins/externals.ts b/src/rollup/plugins/externals.ts index a7d8203607..028446210f 100644 --- a/src/rollup/plugins/externals.ts +++ b/src/rollup/plugins/externals.ts @@ -3,6 +3,7 @@ import { resolve, dirname, normalize, join, isAbsolute } from 'pathe' import { nodeFileTrace, NodeFileTraceOptions } from '@vercel/nft' import type { Plugin } from 'rollup' import { resolvePath, isValidNodeImport } from 'mlly' +import semver from 'semver' export interface NodeExternalsOptions { inline?: string[] @@ -142,6 +143,17 @@ export function externals (opts: NodeExternalsOptions): Plugin { .then(r => Array.from(r.fileList).map(f => resolve(opts.traceOptions.base, f))) .then(r => r.filter(file => file.includes('node_modules'))) + // Read package.json with cache + const packageJSONCache = new Map() // pkgDir => contents + const getPackageJson = async (pkgDir: string) => { + if (packageJSONCache.has(pkgDir)) { + return packageJSONCache.get(pkgDir) + } + const pkgJSON = JSON.parse(await fsp.readFile(resolve(pkgDir, 'package.json'), 'utf8')) + packageJSONCache.set(pkgDir, pkgJSON) + return pkgJSON + } + // Keep track of npm packages const tracedPackages = new Map() // name => pkgDir for (const file of tracedFiles) { @@ -151,13 +163,19 @@ export function externals (opts: NodeExternalsOptions): Plugin { // Check for duplicate versions const existingPkgDir = tracedPackages.get(pkgName) if (existingPkgDir && existingPkgDir !== pkgDir) { - console.warn(`Multiple versions of package ${pkgName} detected in:\n` + [ - existingPkgDir, - pkgDir - ].map(p => ' - ' + p).join('\n')) - continue + const v1 = await getPackageJson(existingPkgDir).then(r => r.version) + const v2 = await getPackageJson(pkgDir).then(r => r.version) + if (semver.gte(v1, v2)) { + // Existing record is newer or same. Just skip. + continue + } + if (semver.major(v1) !== semver.major(v2)) { + console.warn(`Multiple major versions of package ${pkgName} are being externalized. Picking latest version.\n` + [ + existingPkgDir + '@' + v1, + pkgDir + '@' + v2 + ].map(p => ' - ' + p).join('\n')) + } } - // Add to traced packages tracedPackages.set(pkgName, pkgDir) } diff --git a/yarn.lock b/yarn.lock index 1e65e90e92..7693cfe71d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -889,6 +889,13 @@ __metadata: languageName: node linkType: hard +"@types/semver@npm:^7.3.9": + version: 7.3.9 + resolution: "@types/semver@npm:7.3.9" + checksum: 60bfcfdfa7f937be2c6f4b37ddb6714fb0f27b05fe4cbdfdd596a97d35ed95d13ee410efdd88e72a66449d0384220bf20055ab7d6b5df10de4990fbd20e5cbe0 + languageName: node + linkType: hard + "@types/serve-static@npm:^1.13.10": version: 1.13.10 resolution: "@types/serve-static@npm:1.13.10" @@ -5099,6 +5106,7 @@ __metadata: "@types/http-proxy": ^1.17.8 "@types/jsdom": ^16.2.14 "@types/node-fetch": ^2.6.1 + "@types/semver": ^7.3.9 "@types/serve-static": ^1.13.10 "@vercel/nft": ^0.17.5 archiver: ^5.3.0 @@ -5141,6 +5149,7 @@ __metadata: rollup-plugin-terser: ^7.0.2 rollup-plugin-visualizer: ^5.6.0 scule: ^0.2.1 + semver: ^7.3.5 serve-placeholder: ^1.2.4 serve-static: ^1.14.2 std-env: ^3.0.1