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..1b8bd2533e 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,11 @@ const defaultOptions = { filename: 'test-entry-file.js' } +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}]+`)}`) +} + beforeEach(() => { process.env.VUE_CLI_ENTRY_FILES = JSON.stringify([path.join(process.cwd(), 'test-entry-file.js')]) }) @@ -22,9 +27,9 @@ test('polyfill detection', () => { filename: 'test-entry-file.js' }) // default includes - expect(code).not.toMatch(`import "core-js/modules/es6.promise"`) + expect(code).not.toMatch(genCoreJSImportRegExp('es6.promise')) // usage-based detection - expect(code).not.toMatch(`import "core-js/modules/es6.map"`) + expect(code).not.toMatch(genCoreJSImportRegExp('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(genCoreJSImportRegExp('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(genCoreJSImportRegExp('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(genCoreJSImportRegExp('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(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 @@ -98,7 +103,7 @@ test('async/await', () => { } hello() `.trim(), defaultOptions) - expect(code).toMatch(`import "core-js/modules/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 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) + }) } } }