vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.76k stars 6.33k forks source link

core-js polyfill vs babel-polyfill #5386

Closed victortwc closed 4 years ago

victortwc commented 4 years ago

Version

4.3.1

Environment info

System:
    OS: macOS Mojave 10.14.6
    CPU: (8) x64 Intel(R) Core(TM) i5-8257U CPU @ 1.40GHz
  Binaries:
    Node: 12.14.1 - ~/.nvm/versions/node/v12.14.1/bin/node
    Yarn: Not Found
    npm: 6.13.4 - ~/.nvm/versions/node/v12.14.1/bin/npm
  Browsers:
    Chrome: 80.0.3987.163
    Firefox: Not Found
    Safari: 13.1
  npmPackages:
    @twcapps/vue-cli-plugin-build: 0.1.9 => 0.1.9 
    @vue/babel-helper-vue-jsx-merge-props:  1.0.0 
    @vue/babel-plugin-transform-vue-jsx:  1.1.2 
    @vue/babel-preset-app:  4.2.2 
    @vue/babel-preset-jsx:  1.1.2 
    @vue/babel-sugar-functional-vue:  1.1.2 
    @vue/babel-sugar-inject-h:  1.1.2 
    @vue/babel-sugar-v-model:  1.1.2 
    @vue/babel-sugar-v-on:  1.1.2 
    @vue/cli-overlay:  4.2.2 
    @vue/cli-plugin-babel: ~4.2.2 => 4.2.2 
    @vue/cli-plugin-e2e-nightwatch: ~4.2.2 => 4.2.2 
    @vue/cli-plugin-eslint: ~4.2.2 => 4.2.2 
    @vue/cli-plugin-router:  4.2.2 
    @vue/cli-plugin-typescript: ~4.2.2 => 4.2.2 
    @vue/cli-plugin-unit-jest: ^4.2.3 => 4.2.3 
    @vue/cli-plugin-vuex:  4.2.2 
    @vue/cli-service: ~4.2.2 => 4.2.2 
    @vue/cli-shared-utils:  4.2.2 (4.2.3)
    @vue/component-compiler-utils:  3.1.1 
    @vue/eslint-config-airbnb: ~5.0.2 => 5.0.2 
    @vue/eslint-config-typescript: ~5.0.1 => 5.0.1 
    @vue/preload-webpack-plugin:  1.1.1 
    @vue/test-utils: ^1.0.0-beta.32 => 1.0.0-beta.32 
    @vue/web-component-wrapper:  1.2.0 
    eslint-plugin-vue: ~6.2.1 => 6.2.1 
    jest-serializer-vue:  2.0.2 
    typescript: 3.7.5 => 3.7.5 
    vue: ~2.6.11 => 2.6.11 
    vue-class-component: ~7.2.3 => 7.2.3 
    vue-cli-plugin-markdown: ~0.1.2 => 0.1.2 
    vue-eslint-parser:  7.0.0 
    vue-hot-reload-api:  2.3.4 
    vue-i18n: ~8.15.3 => 8.15.3 
    vue-jest:  3.0.5 
    vue-loader:  15.9.0 
    vue-property-decorator: ~8.4.0 => 8.4.0 
    vue-router: ~3.1.5 => 3.1.5 
    vue-spatialnavigation: ^1.2.1 => 1.2.1 
    vue-style-loader:  4.1.2 
    vue-template-compiler: ~2.6.11 => 2.6.11 
    vue-template-es2015-compiler:  1.9.1 
    vuex: ^3.1.3 => 3.1.3 
  npmGlobalPackages:
    @vue/cli: 4.2.3

Steps to reproduce

core-js polyfill is not working the same way as babel-polyfill.

With core-js (or it's indirect use like @vue/cli-plugin-babel/preset) the app behaves weird, not updating the UI from events on Safari 6 (Samsung Tizen 2016).

What is expected?

App works after the preset applies all polyfills

What is actually happening?

Weird behavior, UI not updating even though the event method is called. (Could be related to macrotaks? Which polyfills would wrongly cause this?)


On Tizen 2016, the regular Vue CLI 4 project is not working properly after applying the polyfills. If I use babel-polyfill with useBuiltIns: "entry" it works just fine. Is there any fundamental difference between those?

haoqunjiang commented 4 years ago

https://babeljs.io/docs/en/babel-polyfill

🚨 As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (needed to use transpiled generator functions):


As for your specific issue, please provide a reproduction.

victortwc commented 4 years ago

Hi @sodatea, I understand that the cli is using core-js directly because babel-polyfill has been deprecated. I just wanted to understand what could cause the issue.

As for reproduction, it would be very difficult for me to provide it, as it is very specific to a Samsung tizen TV. The use case follows:

The TV SDK will send me an event with the current video progress (a number). I'm using xstate to manage a state machine that will handle the transitions and this event is passed up to the app via a callback. So the app is doing:

this.player.subscribe(this.handleStateUpdate);

handleStateUpdate(state) {
      this.progressTime = state.progressTime;
}

It's a very simple event that will call the function and update the ui reactively, nothing fancy there. If I put a console.log to see the state variable and check on a remote devtools the UI updates, as if the event loop was delayed sufficiently for Vue to detect the changes. If I use a setTimeout wrapping the assignment it also works with core-js, maybe it's the queue-microtasks polyfill that's included from babel but not from core-js? I'm quite lost at this point.

I'll try to download an old version of Safari and try to repro locally (as the TV is using Safari 6 equivalent of webkit).

Thanks

haoqunjiang commented 4 years ago

Honestly, I'm not sure.

I use babel-polyfill with useBuiltIns: "entry" it works just fine

Does it work if you replace babel-polyfill with core-js/stable. Because in the default setup, the core-js polyfills are required on-demand. So if core-js/stable also works, we can narrow down the issue to the polyfills that are not loaded by default.

victortwc commented 4 years ago

It doesn't work, unfortunately. I'll try experimenting a bit with the different polyfills that are being applied by babel. It's super strange.

victortwc commented 4 years ago

So I tested corejs@2.6.11 by including only

import "core-js/fn/set";
import "core-js/fn/map";
import "core-js/fn/promise";
import "core-js/fn/object";
import "core-js/fn/array";

which is the bare minimal to make my app run on that device. The UI update works just fine. I'll try to find the offender now by including each package from core-js.

victortwc commented 4 years ago

Tested core-js@3.6.5 by including only

import "core-js/stable/symbol";
import "core-js/stable/object";
import "core-js/stable/array";
import "core-js/stable/promise";
import "core-js/stable/map";
import "core-js/stable/set";

which is the bare minimal to make my app run on that device. The UI update stopped working.

victortwc commented 4 years ago

Found the breaking package from core-js@3: core-js/stable/promise

Using core-js@2 core-js/fn/promise works fine, even using everything else from core-js@3 as in:

import "core-js3/stable/symbol";
import "core-js3/stable/object";
import "core-js3/stable/array";
import "core-js2/fn/promise";
import "core-js3/stable/map";
import "core-js3/stable/set";

Super weird edge case. Now I think it's out of scope of vue-cli, right @sodatea ?

haoqunjiang commented 4 years ago

Yeah. It's either in the core-js polyfill or the Vue nextTick implementation. You can check if the new polyfill breaks any logic of nextTick https://github.com/vuejs/vue/blob/dev/src/core/util/next-tick.js