Vue-cli: Modern mode is breaking about @vue/cli-service and @vue/cli-plugin-typescript 3.4.0

Created on 8 Feb 2019  Â·  16Comments  Â·  Source: vuejs/vue-cli

Version

3.4.0

Reproduction link

https://github.com/yoyo930021/modern-mode-example

Environment info

Environment Info:

  System:
    OS: macOS 10.14.3
    CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
  Binaries:
    Node: 10.14.1 - ~/.nvm/versions/node/v10.14.1/bin/node
    Yarn: 1.12.3 - ~/.nvm/versions/node/v10.14.1/bin/yarn
    npm: 6.4.1 - ~/.nvm/versions/node/v10.14.1/bin/npm
  Browsers:
    Chrome: 71.0.3578.98
    Firefox: 64.0.2
    Safari: 12.0.3
  npmPackages:
    @vue/babel-helper-vue-jsx-merge-props:  1.0.0-beta.2
    @vue/babel-plugin-transform-vue-jsx:  1.0.0-beta.2
    @vue/babel-preset-app:  3.4.0
    @vue/babel-preset-jsx:  1.0.0-beta.2
    @vue/babel-sugar-functional-vue:  1.0.0-beta.2
    @vue/babel-sugar-inject-h:  1.0.0-beta.2
    @vue/babel-sugar-v-model:  1.0.0-beta.2
    @vue/babel-sugar-v-on:  1.0.0-beta.2
    @vue/cli-overlay:  3.4.0
    @vue/cli-plugin-babel: ^3.4.0 => 3.4.0
    @vue/cli-plugin-eslint: ^3.4.0 => 3.4.0
    @vue/cli-plugin-typescript: ^3.4.0 => 3.3.0
    @vue/cli-service: ^3.4.0 => 3.3.0
    @vue/cli-shared-utils:  3.4.0
    @vue/component-compiler-utils:  2.5.2
    @vue/eslint-config-prettier: ^4.0.1 => 4.0.1
    @vue/eslint-config-typescript: ^4.0.0 => 4.0.0
    @vue/preload-webpack-plugin:  1.1.0
    @vue/web-component-wrapper:  1.2.0
    eslint-plugin-vue: ^5.0.0 => 5.1.0
    vue: ^2.5.22 => 2.6.3
    vue-class-component: ^6.0.0 => 6.3.2
    vue-eslint-parser:  4.0.3
    vue-hot-reload-api:  2.3.1
    vue-loader:  15.6.2
    vue-property-decorator: ^7.0.0 => 7.3.0
    vue-style-loader:  4.1.2
    vue-template-compiler: ^2.5.21 => 2.6.3
    vue-template-es2015-compiler:  1.8.2
  npmGlobalPackages:
    @vue/cli: Not Found

Steps to reproduce

  1. yarn build --modern
  2. open dist/js/app.[hash].js
  3. search async or await not found and file is like dist/js/app-legacy.[hash].js

What is expected?

dist/js/app.[hash].js have async await word.

What is actually happening?

modern mode is breaking


If you try to run yarn add --dev @vue/[email protected] && yarn add --dev @vue/[email protected]

modern mode is succeed.

bug now cli-service build typescript

All 16 comments

Did some digging and the issue is actually caused by the ESLint plugin. It somehow calls index.js from @vue/babel-preset-app early and causes it to be cached before the modern build is executed.

I was actually able to reproduce on a default setup without TypeScript plugin involved. The required combination is ESLint plugin + a *.vue file with a <script> block - i.e. when ESLint is applied to the script block of a Vue file, the babel preset somehow gets loaded again and cached.

This may have something to do with eslint-plugin-vue... This can be reproduced with even an empty eslint config.

@sodatea we need to look into this with high priority since modern mode is pretty much broken.

Ok I think I found out a more serious flaw in the design. Modern mode currently relies on running the build twice with different env variables, and the babel preset dynamically returns different config based on the env variables. Technically, this should not work since the babel preset is cached by babel... but it happened to work when babel-loader is being run in multiple threads (and thus the preset is reloaded in each thread). When somehow the babel preset is loaded in a reused thread before the modern build (somehow introduced by a mix of TS + ESLint), it causes the thing to fail. If the user runs the build on a single-core machine or explicitly disables thread-loader, it would also fail.

Currently, a workaround is using a self-invalidating babel.config.js:

module.exports = api => {
  // 1. avoid this whole config from being cached
  api.cache(() => process.env.VUE_CLI_MODERN_BUILD)
  return {
    presets: [
      // 2. avoid the preset return value from being cached
      // babel also caches presets based on their options
      ['@vue/app', { modern: process.env.VUE_CLI_MODERN_BUILD }]
    ]
  }
}

I think to properly fix this we need to fundamentally re-design modern mode to not rely on env variables.

but it happened to work when babel-loader is being run in multiple threads (and thus the preset is reloaded in each thread)

No wonder I can't get a reliable reproduction of this issue…

Modern mode still hangs for me @vue/cli 3.5.3. Please could someone confirm which version this fix should be present in, or what the version dependencies are?

@bigsee I believe it's fixed since @vue/cli-service 3.4.1

Updating @vue/cli-service, @vue/cli-plugin-babel and @vue/cli-plugin-eslint fixed this issue for me. Also make sure you import @babel/polyfill using this method: https://github.com/vuetifyjs/vue-cli-plugin-vuetify/issues/3#issuecomment-385357316.

issue is still here 👹
Environment Info:

System:
OS: macOS 10.14.5
CPU: (8) x64 Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz
Binaries:
Node: 8.9.1 - ~/.nvm/versions/node/v8.9.1/bin/node
Yarn: 1.15.2 - /usr/local/bin/yarn
npm: 5.5.1 - ~/.nvm/versions/node/v8.9.1/bin/npm
Browsers:
Chrome: 74.0.3729.157
Firefox: 66.0.5
Safari: 12.1.1
npmPackages:
@vue/cli-overlay: 3.6.0
@vue/cli-plugin-eslint: ^3.6.0 => 3.6.0
@vue/cli-plugin-typescript: ^3.6.0 => 3.6.0
@vue/cli-service: ^3.6.0 => 3.6.0
@vue/cli-shared-utils: 3.6.0
@vue/component-compiler-utils: 2.6.0
@vue/eslint-config-standard: ^4.0.0 => 4.0.0
@vue/eslint-config-typescript: ^4.0.0 => 4.0.0
@vue/preload-webpack-plugin: 1.1.0
@vue/web-component-wrapper: 1.2.0
eslint-plugin-vue: ^5.0.0 => 5.2.2 (4.7.1)
typescript: ^3.4.3 => 3.4.5
vue: ^2.6.10 => 2.6.10
vue-class-component: ^7.0.2 => 7.0.2
vue-eslint-parser: 2.0.3 (5.0.0)
vue-hot-reload-api: 2.3.3
vue-loader: 15.7.0
vue-property-decorator: ^8.1.0 => 8.1.0
vue-router: ^3.0.3 => 3.0.6
vue-style-loader: 4.1.2
vue-template-compiler: ^2.6.10 => 2.6.10
vue-template-es2015-compiler: 1.9.1
vuelidate: ^0.7.4 => 0.7.4
vuex: ^3.0.1 => 3.1.0
vuex-class: ^0.3.2 => 0.3.2
npmGlobalPackages:
@vue/cli: 3.7.0

@lovetingyuan could you please provide a reproduction and open a new issue?

https://github.com/lovetingyuan/vue-cli-modern-bug
@sodatea please see README.md, thanks

It's a duplicate of https://github.com/vuejs/vue-cli/issues/3206
Babel is required for modern mode.
We'll update the documentation soon.

ok, thanks a lot.

@sodatea why is babel required for modern mode?

@rcheung9 For modern mode, we need to target the compiled code to those browsers who supports script type="module". Such fine control can only be achieved in babel config, typescript exposes very limited compiler options.

What about setting target(in Typescript compiler options) to ES2015?

@babel/polyfill does not get provided when you use vue ui and install babel as a plugin.
After installing it manually it adds about 90kb to both my builds and does not build modern.
@vue/cli-service, @vue/cli-plugin-babel and @vue/cli-plugin-eslint are updated to their latest version, imported the polyfill in the entry JS file and added the babel config file:
module.exports = { presets: [ ['@vue/app', { useBuiltIns: 'entry', }] ] };

what am I missing here?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BusyHe picture BusyHe  Â·  3Comments

jgribonvald picture jgribonvald  Â·  3Comments

DrSensor picture DrSensor  Â·  3Comments

brandon93s picture brandon93s  Â·  3Comments

csakis picture csakis  Â·  3Comments