Skip to content

Library with polyfills built by the CLI will pollute the global scope #6194

Open
@fangbinwei

Description

@fangbinwei

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 its corejs 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?

babel/babel#9853 (comment)
babel/babel#11572

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions