Skip to content

Commit

Permalink
fix: add promise polyfill if not used in bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jan 7, 2021
1 parent 52ac81a commit b72db4e
Showing 1 changed file with 57 additions and 45 deletions.
102 changes: 57 additions & 45 deletions packages/plugin-legacy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ function viteLegacyPlugin(options = {}) {

async generateBundle(opts, bundle) {
if (!isLegacyOutput(opts)) {
if (!modernPolyfills.size) {
return
}
isDebug &&
console.log(
`[@vitejs/plugin-legacy] modern polyfills:`,
modernPolyfills
)
if (!modernPolyfills.size) {
return
}
await buildPolyfillChunk(
'polyfills-modern',
modernPolyfills,
Expand All @@ -79,12 +79,19 @@ function viteLegacyPlugin(options = {}) {
}

// legacy bundle
isDebug &&
console.log(
`[@vitejs/plugin-legacy] legacy polyfills:`,
legacyPolyfills
)
if (legacyPolyfills.size) {
if (!legacyPolyfills.has('es.promise')) {
// check if the target needs Promise polyfill because SystemJS relies
// on it
detectPolyfills(`Promise.resolve()`, targets, legacyPolyfills)
}

isDebug &&
console.log(
`[@vitejs/plugin-legacy] legacy polyfills:`,
legacyPolyfills
)

await buildPolyfillChunk(
'polyfills-legacy',
legacyPolyfills,
Expand Down Expand Up @@ -150,46 +157,16 @@ function viteLegacyPlugin(options = {}) {
) {
return null
}

// analyze and record modern polyfills
const { ast } = babel.transformSync(raw, {
ast: true,
code: false,
configFile: false,
sourceMaps: false,
presets: [
[
presetEnv,
{
targets: { esmodules: true },
modules: false,
useBuiltIns: 'usage',
corejs: { version: 3, proposals: false },
shippedProposals: true,
ignoreBrowserslistConfig: true
}
]
]
})
for (const node of ast.program.body) {
if (node.type === 'ImportDeclaration') {
const source = node.source.value
if (
source.startsWith('core-js/') ||
source.startsWith('regenerator-runtime/')
) {
modernPolyfills.add(node.source.value)
}
}
}
detectPolyfills(raw, { esmodules: true }, modernPolyfills)
return null
}

if (!genLegacy) {
return
}

const detectPolyfills =
const needPolyfills =
options.polyfills !== false && !Array.isArray(options.polyfills)

// transform the legacy chunk with @babel/preset-env
Expand All @@ -204,21 +181,20 @@ function viteLegacyPlugin(options = {}) {
presetEnv,
{
targets,
// modules are already converted to systemjs by rollup
modules: false,
bugfixes: true,
useBuiltIns: detectPolyfills ? 'usage' : false,
shippedProposals: true,
corejs: detectPolyfills
useBuiltIns: needPolyfills ? 'usage' : false,
corejs: needPolyfills
? { version: 3, proposals: false }
: undefined,
shippedProposals: true,
ignoreBrowserslistConfig: options.ignoreBrowserslistConfig
}
]
]
})

if (detectPolyfills) {
if (needPolyfills) {
// detect and remove polyfill imports. Since the legacy bundle uses
// format: 'system', any import declarations are polyfill imports injected
// by @babel/preset-env.
Expand Down Expand Up @@ -336,6 +312,42 @@ function viteLegacyPlugin(options = {}) {
return [legacyGenerateBundlePlugin, legacyPostPlugin]
}

/**
* @param {string} code
* @param {any} targets
* @param {Set<string>} list
*/
function detectPolyfills(code, targets, list) {
const { ast } = babel.transformSync(code, {
ast: true,
configFile: false,
presets: [
[
presetEnv,
{
targets,
modules: false,
useBuiltIns: 'usage',
corejs: { version: 3, proposals: false },
shippedProposals: true,
ignoreBrowserslistConfig: true
}
]
]
})
for (const node of ast.program.body) {
if (node.type === 'ImportDeclaration') {
const source = node.source.value
if (
source.startsWith('core-js/') ||
source.startsWith('regenerator-runtime/')
) {
list.add(source)
}
}
}
}

/**
* @param {string} name
* @param {Set<string>} imports
Expand Down

0 comments on commit b72db4e

Please sign in to comment.