Vue-cli: modern only build

Created on 9 Jul 2019  路  13Comments  路  Source: vuejs/vue-cli

What problem does this feature solve?

Allows to create modern only build. Some applications don't need legacy build.
I guess that could be achieved by proper configuration of browsersrc file, but this solution seems a bit hacky and unintuitive, and I'm not sure if it would work

What does the proposed API look like?

For example
vue-cli-service build --modern="only"
vue-cli-service build --modern --no-legacy
vue-cli-service build --modern-only

documentation enhancement cli-service build

Most helpful comment

I would like a flag to disable legacy build so I can run both the legacy and modern builds in parallel in my continuous integration/deployment environment. This would help speed up deployments, and overcome challenges where enforced RAM limits are hit in containers when trying to build both modern and legacy at the same time.

All 13 comments

I guess that could be achieved by proper configuration of browsersrc file, but this solution seems a bit hacky and unintuitive, and I'm not sure if it would work

It's not "hacky" imho. but the easiest way would be to simply switch your babel config to this:

// babel.config.js
module.exports = {
  presets: [
    [
      "@vue/app", 
      { 
        targets: { esmodules: true },
        polyfills: false
      }
    ]
  ]
}

..which is basically what modern mode does.

It's indeed simple when you look at it, but not so obvious to come to the solution without diving deeper in the source code. But I guess adding this information in docs near the "There are a few useful flags" in https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-build or (and) here https://cli.vuejs.org/guide/browser-compatibility.html#modern-mode would be fine as well

I was also looking for this today. Unfortunatly the example by @LinusBorg gives me basically the same build as before, where as the modern build from the same project turns out much small. For example with the settings in babel.config.js that @LinusBorg postet, Array-spreads are still converted to function calls.

I've just tried it on a simple app with the following results, definitely not the same as standard modern build

./legacy:
razem 400
 20 -rwxrwxrwx 1 Jacek Brak  19733 07-10 17:01 app-legacy.f94d5f87.js
 68 -rwxrwxrwx 1 Jacek Brak  67645 07-10 17:01 chunk-36d467ff-legacy.d362b459.js
312 -rwxrwxrwx 1 Jacek Brak 318992 07-10 17:01 chunk-vendors-legacy.dd62c234.js

./modern:
razem 376
 20 -rwxrwxrwx 1 Jacek Brak  18920 07-10 17:02 app.f630369e.js
 68 -rwxrwxrwx 1 Jacek Brak  66653 07-10 17:02 chunk-78699489.56a5ccb7.js
288 -rwxrwxrwx 1 Jacek Brak 293241 07-10 17:02 chunk-vendors.2e379de4.js

./modern-only:
razem 396
 20 -rwxrwxrwx 1 Jacek Brak  18930 07-10 17:05 app.3b1cdbdb.js
 68 -rwxrwxrwx 1 Jacek Brak  66653 07-10 17:05 chunk-78699489.56a5ccb7.js
308 -rwxrwxrwx 1 Jacek Brak 312730 07-10 17:05 chunk-vendors.e37ac886.js

I am also wondering why there doesn't seem any other way to setup webpack to output what would be the output of a modern build.

Any update on this?

Did some digging and found a solution. Pretty much what @LinusBorg suggested, but polyfills can't be falsy or it doesn't get used. This is working to generate a modern build for me:

// babel.config.js
module.exports = {
  presets: [
    [
      '@vue/cli-plugin-babel/preset', 
      { 
        targets: { esmodules: true },
        polyfills: []
      }
    ]
  ]
}

I would like a flag to disable legacy build so I can run both the legacy and modern builds in parallel in my continuous integration/deployment environment. This would help speed up deployments, and overcome challenges where enforced RAM limits are hit in containers when trying to build both modern and legacy at the same time.

module.exports = {
  presets: [
    '@vue/app',
    {
      targets: { esmodules: true },
      polyfills: []
    }
  ],
  plugins: [
    [
      'component',
      {
        libraryName: 'element-ui',
        styleLibraryName: 'theme-chalk'
      }
    ]
  ]
};

This is what my babel.config.js looks like but I am getting error saying

Unknown option: .targets. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.

I also tried the fix by @tobyzerner but resulted in same.

Nevermind! Guess I had to move to V4 to make all this work. It does work now! Thanks!

Does the suggestion from @LinusBorg or @tobyzerner still modify and inject the dist/index.html with both the <script type="module" and nomodule tags even if run independently?

I'm running into enforced RAM limits in my CI/CD containers that I can't control and it's because it's trying to do both modern and legacy builds in one go and I'd like to split them out into 2 separate pipelines.

@alexcroox

I would like a flag to disable legacy build so I can run both the legacy and modern builds in parallel in my continuous integration/deployment environment. This would help speed up deployments, and overcome challenges where enforced RAM limits are hit in containers when trying to build both modern and legacy at the same time.

This cannot be solved with a simple configuration flag, as currently, modern build depends on files created previously by the legacy build: https://github.com/vuejs/vue-cli/blob/10296ff6a7f98ffc00ae8e79369955ce82f1cd42/packages/%40vue/cli-service/lib/webpack/ModernModePlugin.js#L65-L66

Does the suggestion from @LinusBorg or @tobyzerner still modify and inject the dist/index.html with both the <script type="module" and nomodule tags even if run independently?

No, as that stuff is handled by ModernModePlugin too, and that one only comes into play with --modern flag. Above solutions merely imitate babel-preset-app: https://github.com/vuejs/vue-cli/blob/55d33754f47465a77b8c961eaafe25cfb8fbf191/packages/%40vue/babel-preset-app/index.js#L109-L111
As you can see, this is dependent on an environment variable...
So another, simpler way to generate a "modern only build" is
VUE_CLI_MODERN_BUILD=1 npm run build

Not sure for how long however, as this env dependent behavior is somewhat weirdchamp, as even Evan admitted last year: https://github.com/vuejs/vue-cli/issues/3438#issuecomment-465429050

Thanks for the clarification. Unfortunately I need to serve both modern and legacy in the index.html so it sounds like I won鈥檛 be able to separate them into 2 build processes.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mayefeng picture mayefeng  路  44Comments

AegirLeet picture AegirLeet  路  38Comments

ghenry picture ghenry  路  40Comments

italomaia picture italomaia  路  88Comments

light24bulbs picture light24bulbs  路  41Comments