Description
Version
4.5.10
Reproduction link
https://github.com/fangbinwei/vue-cli-issue-lib-polyfill-pollution
Environment info
System:
OS: macOS 11.1
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Binaries:
Node: 12.14.0 - ~/.nvm/versions/node/v12.14.0/bin/node
Yarn: 1.22.10 - ~/.nvm/versions/node/v12.14.0/bin/yarn
npm: 6.13.4 - ~/.nvm/versions/node/v12.14.0/bin/npm
Browsers:
Chrome: 87.0.4280.88
Edge: 87.0.664.66
Firefox: 82.0.3
Safari: 14.0.2
npmPackages:
@vue/babel-helper-vue-jsx-merge-props: 1.2.1
@vue/babel-helper-vue-transform-on: 1.0.0
@vue/babel-plugin-jsx: 1.0.0
@vue/babel-plugin-transform-vue-jsx: 1.2.1
@vue/babel-preset-app: 4.5.10
@vue/babel-preset-jsx: 1.2.4
@vue/babel-sugar-composition-api-inject-h: 1.2.1
@vue/babel-sugar-composition-api-render-instance: 1.2.4
@vue/babel-sugar-functional-vue: 1.2.2
@vue/babel-sugar-inject-h: 1.2.2
@vue/babel-sugar-v-model: 1.2.3
@vue/babel-sugar-v-on: 1.2.3
@vue/cli-overlay: 4.5.10
@vue/cli-plugin-babel: ~4.5.0 => 4.5.10
@vue/cli-plugin-router: 4.5.10
@vue/cli-plugin-vuex: 4.5.10
@vue/cli-service: ~4.5.0 => 4.5.10
@vue/cli-shared-utils: 4.5.10
@vue/component-compiler-utils: 3.2.0
@vue/preload-webpack-plugin: 1.1.2
@vue/web-component-wrapper: 1.2.0
vue: ^2.6.11 => 2.6.12
vue-hot-reload-api: 2.3.4
vue-loader: 15.9.6 (16.1.2)
vue-style-loader: 4.1.2
vue-template-compiler: ^2.6.11 => 2.6.12
vue-template-es2015-compiler: 1.9.1
npmGlobalPackages:
@vue/cli: 5.0.0-alpha.0
Steps to reproduce
cd app-use-corejs2
# cd app-use-corejs3
yarn install
yarn serve
Compare the results of IE11 and Chrome. Promise.prototype.finally
is not a function in IE11.
application project will inject
promise.finally
polyfill, but it won't work since the pollution of promise polyfill(without 'finally') in our lib.
What is expected?
Polyfills are injected to library without global namespace pollution. promise.finally
polyfill works in IE11.
What is actually happening?
Check the README of the reproduction demo.
-
By using useBuiltIns: "usage", Babel will only inject polyfills for unsupported ECMAScript features (according to target browser version) but only if they are actually used in the input source code;
-
By using
@babel/plugin-transform-runtime
and setting itscorejs
option, Babel will inject ponyfills (which are "pure" and don't pollute the global scope) for every used ECMAScript feature supported by core-js. This is usually used by library authors.
@babel/plugin-transform-runtime
does not support only polyfilling the features required by the target browser versions like @babel/preset-env
does. This results in unnecessarily large bundles containing unused polyfills.
useBuiltIns
and @babel/plugin-transform-runtime's corejs option
are mutually exclusive. Now CLI selects to set the @babel/plugin-transform-runtime
's corejs option to false
, and use useBuiltIns
with its corejs
option. We don't care the pollutions when developing an application, but it's better bundle library without side effect(pollution). The pollution caused by the library may lead to weird problems, and it is difficult to locate the bug.
How to solve?
-
setting
useBuiltIns: false
, using@babel/plugin-transform-runtime
and itscorejs
option to bundle library (but increasing bundle size) -
babel try to solve this problem by
babel-polyfills
, but it's experimental now. related issue: RFC: Rethink polyfilling story babel/babel#10008