From d138023229e17d170b1adce4d33fc908727527ee Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Tue, 26 Mar 2019 17:00:06 +0800 Subject: [PATCH 1/5] fix: use absolute import path for injected core-js polyfills fixes #3678 --- .../__tests__/babel-preset.spec.js | 19 +++++++++----- packages/@vue/babel-preset-app/package.json | 1 + .../@vue/babel-preset-app/polyfillsPlugin.js | 26 ++++++++++++++++--- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js index 91795c510c..27ca794759 100644 --- a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js +++ b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js @@ -7,6 +7,10 @@ const defaultOptions = { filename: 'test-entry-file.js' } +const getCoreJSImportRegExp = mod => { + return new RegExp(`import "${path.join('.*node_modules', 'core-js', 'modules', mod)}`) +} + beforeEach(() => { process.env.VUE_CLI_ENTRY_FILES = JSON.stringify([path.join(process.cwd(), 'test-entry-file.js')]) }) @@ -22,9 +26,10 @@ test('polyfill detection', () => { filename: 'test-entry-file.js' }) // default includes - expect(code).not.toMatch(`import "core-js/modules/es6.promise"`) + // expected to include a `node_modules` in the import path because we use absolute path for core-js + expect(code).not.toMatch(getCoreJSImportRegExp('es6.promise')) // usage-based detection - expect(code).not.toMatch(`import "core-js/modules/es6.map"`) + expect(code).not.toMatch(getCoreJSImportRegExp('es6.map')) ;({ code } = babel.transformSync(` const a = new Map() @@ -36,9 +41,9 @@ test('polyfill detection', () => { filename: 'test-entry-file.js' })) // default includes - expect(code).toMatch(`import "core-js/modules/es6.promise"`) + expect(code).toMatch(getCoreJSImportRegExp('es6.promise')) // promise polyfill alone doesn't work in IE, needs this as well. fix: #1642 - expect(code).toMatch(`import "core-js/modules/es6.array.iterator"`) + expect(code).toMatch(getCoreJSImportRegExp('es6.array.iterator')) // usage-based detection expect(code).toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/) }) @@ -56,7 +61,7 @@ test('modern mode always skips polyfills', () => { filename: 'test-entry-file.js' }) // default includes - expect(code).not.toMatch(`import "core-js/modules/es6.promise"`) + expect(code).not.toMatch(getCoreJSImportRegExp('es6.promise')) // usage-based detection expect(code).not.toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/) @@ -71,7 +76,7 @@ test('modern mode always skips polyfills', () => { filename: 'test-entry-file.js' })) // default includes - expect(code).not.toMatch(`import "core-js/modules/es6.promise"`) + expect(code).not.toMatch(getCoreJSImportRegExp('es6.promise')) // usage-based detection expect(code).not.toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/) delete process.env.VUE_CLI_MODERN_BUILD @@ -98,7 +103,7 @@ test('async/await', () => { } hello() `.trim(), defaultOptions) - expect(code).toMatch(`import "core-js/modules/es6.promise"`) + expect(code).toMatch(getCoreJSImportRegExp('es6.promise')) // should use regenerator runtime expect(code).toMatch(`import "regenerator-runtime/runtime"`) // should use required helper instead of inline diff --git a/packages/@vue/babel-preset-app/package.json b/packages/@vue/babel-preset-app/package.json index cba42ccb15..89cab0c1c6 100644 --- a/packages/@vue/babel-preset-app/package.json +++ b/packages/@vue/babel-preset-app/package.json @@ -22,6 +22,7 @@ }, "homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/babel-preset-app#readme", "dependencies": { + "@babel/helper-module-imports": "^7.0.0", "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-decorators": "^7.1.0", "@babel/plugin-syntax-dynamic-import": "^7.0.0", diff --git a/packages/@vue/babel-preset-app/polyfillsPlugin.js b/packages/@vue/babel-preset-app/polyfillsPlugin.js index 9b8c3f17fd..c54bfa5f33 100644 --- a/packages/@vue/babel-preset-app/polyfillsPlugin.js +++ b/packages/@vue/babel-preset-app/polyfillsPlugin.js @@ -1,3 +1,19 @@ +const { addSideEffect } = require('@babel/helper-module-imports') + +// slightly modifiled from @babel/preset-env/src/utils +// use an absolute path for core-js modules, to fix conflicts of different core-js versions +function getModulePath (mod) { + if (mod === 'regenerator-runtime') { + return require.resolve('regenerator-runtime/runtime') + } + + return require.resolve(`core-js/modules/${mod}`) +} + +function createImport (path, mod) { + return addSideEffect(path, getModulePath(mod)) +} + // add polyfill imports to the first file encountered. module.exports = ({ types }, { entryFiles = [] }) => { return { @@ -9,11 +25,13 @@ module.exports = ({ types }, { entryFiles = [] }) => { } const { polyfills } = state.opts - const { createImport } = require('@babel/preset-env/lib/utils') // imports are injected in reverse order - polyfills.slice().reverse().forEach(p => { - createImport(path, p) - }) + polyfills + .slice() + .reverse() + .forEach(p => { + createImport(path, p) + }) } } } From 58069c3d92c3dc3f981e9a6cf1924281cf4b4d86 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Tue, 26 Mar 2019 17:00:06 +0800 Subject: [PATCH 2/5] test: correctly escape path separators --- .../__tests__/babel-preset.spec.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js index 27ca794759..e756f43464 100644 --- a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js +++ b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js @@ -7,8 +7,8 @@ const defaultOptions = { filename: 'test-entry-file.js' } -const getCoreJSImportRegExp = mod => { - return new RegExp(`import "${path.join('.*node_modules', 'core-js', 'modules', mod)}`) +const genCoreJSImportRegExp = mod => { + return new RegExp(`import "${['.*node_modules', 'core-js', 'modules', mod].join(`\\${path.sep}`)}`) } beforeEach(() => { @@ -27,9 +27,9 @@ test('polyfill detection', () => { }) // default includes // expected to include a `node_modules` in the import path because we use absolute path for core-js - expect(code).not.toMatch(getCoreJSImportRegExp('es6.promise')) + expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise')) // usage-based detection - expect(code).not.toMatch(getCoreJSImportRegExp('es6.map')) + expect(code).not.toMatch(genCoreJSImportRegExp('es6.map')) ;({ code } = babel.transformSync(` const a = new Map() @@ -41,9 +41,9 @@ test('polyfill detection', () => { filename: 'test-entry-file.js' })) // default includes - expect(code).toMatch(getCoreJSImportRegExp('es6.promise')) + expect(code).toMatch(genCoreJSImportRegExp('es6.promise')) // promise polyfill alone doesn't work in IE, needs this as well. fix: #1642 - expect(code).toMatch(getCoreJSImportRegExp('es6.array.iterator')) + expect(code).toMatch(genCoreJSImportRegExp('es6.array.iterator')) // usage-based detection expect(code).toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/) }) @@ -61,7 +61,7 @@ test('modern mode always skips polyfills', () => { filename: 'test-entry-file.js' }) // default includes - expect(code).not.toMatch(getCoreJSImportRegExp('es6.promise')) + expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise')) // usage-based detection expect(code).not.toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/) @@ -76,7 +76,7 @@ test('modern mode always skips polyfills', () => { filename: 'test-entry-file.js' })) // default includes - expect(code).not.toMatch(getCoreJSImportRegExp('es6.promise')) + expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise')) // usage-based detection expect(code).not.toMatch(/import _Map from ".*runtime-corejs2\/core-js\/map"/) delete process.env.VUE_CLI_MODERN_BUILD @@ -103,7 +103,7 @@ test('async/await', () => { } hello() `.trim(), defaultOptions) - expect(code).toMatch(getCoreJSImportRegExp('es6.promise')) + expect(code).toMatch(genCoreJSImportRegExp('es6.promise')) // should use regenerator runtime expect(code).toMatch(`import "regenerator-runtime/runtime"`) // should use required helper instead of inline From 84734568909d801f9448ec365936dac3734d65a0 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Tue, 26 Mar 2019 17:00:06 +0800 Subject: [PATCH 3/5] chore: move the comments up --- packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js index e756f43464..aea61d039f 100644 --- a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js +++ b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js @@ -8,6 +8,7 @@ const defaultOptions = { } const genCoreJSImportRegExp = mod => { + // expected to include a `node_modules` in the import path because we use absolute path for core-js return new RegExp(`import "${['.*node_modules', 'core-js', 'modules', mod].join(`\\${path.sep}`)}`) } @@ -26,7 +27,6 @@ test('polyfill detection', () => { filename: 'test-entry-file.js' }) // default includes - // expected to include a `node_modules` in the import path because we use absolute path for core-js expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise')) // usage-based detection expect(code).not.toMatch(genCoreJSImportRegExp('es6.map')) From 4eb3b7508d246ae6e5d69305fc806d33211cc6f7 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Tue, 26 Mar 2019 17:00:06 +0800 Subject: [PATCH 4/5] test: yet another try to make it work on windows --- packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js index aea61d039f..4849b7619b 100644 --- a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js +++ b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js @@ -9,7 +9,7 @@ const defaultOptions = { const genCoreJSImportRegExp = mod => { // expected to include a `node_modules` in the import path because we use absolute path for core-js - return new RegExp(`import "${['.*node_modules', 'core-js', 'modules', mod].join(`\\${path.sep}`)}`) + return new RegExp(`import "${['.*node_modules', 'core-js', 'modules', mod].join(`[${path.sep}]+`)}`) } beforeEach(() => { From de1d15c2db4cbc5e5896a7a2e9e5144c1372735b Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Tue, 26 Mar 2019 17:00:06 +0800 Subject: [PATCH 5/5] test: try again --- packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js index 4849b7619b..1b8bd2533e 100644 --- a/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js +++ b/packages/@vue/babel-preset-app/__tests__/babel-preset.spec.js @@ -9,7 +9,7 @@ const defaultOptions = { const genCoreJSImportRegExp = mod => { // expected to include a `node_modules` in the import path because we use absolute path for core-js - return new RegExp(`import "${['.*node_modules', 'core-js', 'modules', mod].join(`[${path.sep}]+`)}`) + return new RegExp(`import "${['.*node_modules', 'core-js', 'modules', mod].join(`[\\${path.sep}]+`)}`) } beforeEach(() => {