diff --git a/packages/@vue/cli-plugin-webpack-4/generator.js b/packages/@vue/cli-plugin-webpack-4/generator.js index 83d10e9165..ae0ea29973 100644 --- a/packages/@vue/cli-plugin-webpack-4/generator.js +++ b/packages/@vue/cli-plugin-webpack-4/generator.js @@ -44,7 +44,8 @@ module.exports = (api) => { return toMerge }, { - warnIncompatibleVersions: false + warnIncompatibleVersions: false, + forceOverwrite: true } ) } diff --git a/packages/@vue/cli/__tests__/Generator.spec.js b/packages/@vue/cli/__tests__/Generator.spec.js index 63ed6ea858..a7f4334574 100644 --- a/packages/@vue/cli/__tests__/Generator.spec.js +++ b/packages/@vue/cli/__tests__/Generator.spec.js @@ -523,6 +523,41 @@ test('api: extendPackage + { warnIncompatibleVersions: false }', async () => { }) }) +test('api: extendPackage + { forceOverwrite: true }', async () => { + const generator = new Generator('/', { + pkg: { + devDependencies: { + 'sass-loader': '^11.0.0' + } + }, + plugins: [{ + id: 'test', + apply: api => { + api.extendPackage( + { + devDependencies: { + 'sass-loader': '^10.0.0' + } + }, + { warnIncompatibleVersions: false, forceOverwrite: true } + ) + } + }] + }) + + await generator.generate() + const pkg = JSON.parse(fs.readFileSync('/package.json', 'utf-8')) + + // should not warn about the version conflicts + expect(logs.warn.length).toBe(0) + // should use the newer version + expect(pkg).toEqual({ + devDependencies: { + 'sass-loader': '^10.0.0' + } + }) +}) + test('api: render fs directory', async () => { const generator = new Generator('/', { plugins: [ diff --git a/packages/@vue/cli/lib/GeneratorAPI.js b/packages/@vue/cli/lib/GeneratorAPI.js index 2a5b91eba5..ac2e6d3fcf 100644 --- a/packages/@vue/cli/lib/GeneratorAPI.js +++ b/packages/@vue/cli/lib/GeneratorAPI.js @@ -219,12 +219,15 @@ class GeneratorAPI { * that dependency fields are always deep merged regardless of this option. * @param {boolean} [options.warnIncompatibleVersions=true] Output warning * if two dependency version ranges don't intersect. + * @param {boolean} [options.forceOverwrite=false] force using the dependency + * version provided in the first argument, instead of trying to get the newer ones */ extendPackage (fields, options = {}) { const extendOptions = { prune: false, merge: true, - warnIncompatibleVersions: true + warnIncompatibleVersions: true, + forceOverwrite: false } // this condition statement is added for compatibility reason, because diff --git a/packages/@vue/cli/lib/util/mergeDeps.js b/packages/@vue/cli/lib/util/mergeDeps.js index ac8c6cc6fb..60f6e48a4d 100644 --- a/packages/@vue/cli/lib/util/mergeDeps.js +++ b/packages/@vue/cli/lib/util/mergeDeps.js @@ -28,7 +28,8 @@ module.exports = function mergeDeps ( sources, { prune, - warnIncompatibleVersions + warnIncompatibleVersions, + forceOverwrite } ) { const result = Object.assign({}, sourceDeps) @@ -63,11 +64,15 @@ module.exports = function mergeDeps ( const r = tryGetNewerRange(sourceRangeSemver, injectingRangeSemver) const didGetNewer = !!r - // if failed to infer newer version, use existing one because it's likely - // built-in - result[depName] = didGetNewer - ? injectSemver(injectingRange, r) - : sourceRange + if (forceOverwrite) { + result[depName] = injectingRange + } else if (didGetNewer) { + result[depName] = injectSemver(injectingRange, r) + } else { + // if failed to infer newer version, use existing one because it's likely + // built-in + result[depName] = sourceRange + } // if changed, update source if (result[depName] === injectingRange) { @@ -85,7 +90,7 @@ module.exports = function mergeDeps ( `conflicting versions for project dependency "${depName}":\n\n` + `- ${sourceRange} injected by generator "${sourceGeneratorId}"\n` + `- ${injectingRange} injected by generator "${generatorId}"\n\n` + - `Using ${didGetNewer ? `newer ` : ``}version (${ + `Using ${(!forceOverwrite && didGetNewer) ? `newer ` : ``}version (${ result[depName] }), but this may cause build errors.` ) diff --git a/packages/@vue/cli/types/cli-test.ts b/packages/@vue/cli/types/cli-test.ts index c78c62ecad..2c8ffba685 100644 --- a/packages/@vue/cli/types/cli-test.ts +++ b/packages/@vue/cli/types/cli-test.ts @@ -112,7 +112,8 @@ const generator: GeneratorPlugin = (api, options, rootOptions, invoking) => { { merge: true, prune: true, - warnIncompatibleVersions: true + warnIncompatibleVersions: true, + forceOverwrite: true } ) diff --git a/packages/@vue/cli/types/index.d.ts b/packages/@vue/cli/types/index.d.ts index 7a25c20b3c..9a159f7791 100644 --- a/packages/@vue/cli/types/index.d.ts +++ b/packages/@vue/cli/types/index.d.ts @@ -38,6 +38,7 @@ type ExtendPackageOptions = prune?: boolean merge?: boolean warnIncompatibleVersions?: boolean + forceOverwrite?: boolean } | boolean @@ -121,6 +122,8 @@ declare class GeneratorAPI { * that dependency fields are always deep merged regardless of this option. * @param [options.warnIncompatibleVersions=true] Output warning * if two dependency version ranges don't intersect. + * @param [options.forceOverwrite=false] force using the dependency + * version provided in the first argument, instead of trying to get the newer ones */ extendPackage( fields: (pkg: Record) => object,