Skip to content

modern only build #4254

@jacekkarczmarczyk

Description

@jacekkarczmarczyk

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

Activity

LinusBorg

LinusBorg commented on Jul 10, 2019

@LinusBorg
Member

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.

jacekkarczmarczyk

jacekkarczmarczyk commented on Jul 10, 2019

@jacekkarczmarczyk
Author

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

essenmitsosse

essenmitsosse commented on Jul 10, 2019

@essenmitsosse

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.

jacekkarczmarczyk

jacekkarczmarczyk commented on Jul 10, 2019

@jacekkarczmarczyk
Author

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
essenmitsosse

essenmitsosse commented on Jul 30, 2019

@essenmitsosse

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.

tobyzerner

tobyzerner commented on Nov 6, 2019

@tobyzerner

Any update on this?

tobyzerner

tobyzerner commented on Nov 6, 2019

@tobyzerner

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: []
      }
    ]
  ]
}
alexcroox

alexcroox commented on Nov 10, 2019

@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.

praveenpuglia

praveenpuglia commented on Jan 24, 2020

@praveenpuglia
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.

praveenpuglia

praveenpuglia commented on Jan 24, 2020

@praveenpuglia

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

alexcroox

alexcroox commented on May 13, 2020

@alexcroox

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.

phil294

phil294 commented on May 29, 2020

@phil294

@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:

const tempFilename = path.join(this.targetDir, htmlPath, `legacy-assets-${htmlName}.json`)
const legacyAssets = JSON.parse(await fs.readFile(tempFilename, 'utf-8'))

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:

} else if (process.env.VUE_CLI_MODERN_BUILD) {
// targeting browsers that support <script type="module">
targets = { esmodules: true }

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: #3438 (comment)

alexcroox

alexcroox commented on May 29, 2020

@alexcroox

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

awulkan

awulkan commented on Jan 20, 2021

@awulkan

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 tried this as well, but it still appears to build a legacy version. I would really love to be able to fully turn off the legacy build. Our internal applications only target modern browsers.

wirk

wirk commented on Apr 28, 2021

@wirk

@awulkan I just used your approach and then simply removed the --modern flag. Works like a charm!

DevinWell1ee

DevinWell1ee commented on Jul 21, 2021

@DevinWell1ee

@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:

const tempFilename = path.join(this.targetDir, htmlPath, `legacy-assets-${htmlName}.json`)
const legacyAssets = JSON.parse(await fs.readFile(tempFilename, 'utf-8'))

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:

} else if (process.env.VUE_CLI_MODERN_BUILD) {
// targeting browsers that support <script type="module">
targets = { esmodules: true }

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: #3438 (comment)

how build legacy only ?

DevinWell1ee

DevinWell1ee commented on Jul 21, 2021

@DevinWell1ee

@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:

const tempFilename = path.join(this.targetDir, htmlPath, `legacy-assets-${htmlName}.json`)
const legacyAssets = JSON.parse(await fs.readFile(tempFilename, 'utf-8'))

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:

} else if (process.env.VUE_CLI_MODERN_BUILD) {
// targeting browsers that support <script type="module">
targets = { esmodules: true }

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: #3438 (comment)

image

want to build legacy only

rsweny

rsweny commented on Nov 28, 2021

@rsweny

In package.json, editing the browserslist to be only modern browsers, ie ["last 2 versions and not dead"], and then removing the --modern flag builds only one set of the js files and these files are identical to what the modern flag outputs.

AceLing

AceLing commented on Feb 17, 2022

@AceLing

First, modify .browserslistrc:

> 1%
last 2 versions
not dead
not ie 11

Then, execute npm run build and CMD output:

All browser targets in the browserslist configuration have supported ES module.
Therefore we don't build two separate bundles for differential loading.

Finally, I get "modern only build"!!!

jeth318

jeth318 commented on Mar 25, 2022

@jeth318

First, modify .browserslistrc:

> 1%
last 2 versions
not dead
not ie 11

Then, execute npm run build and CMD output:

All browser targets in the browserslist configuration have supported ES module.
Therefore we don't build two separate bundles for differential loading.

Finally, I get "modern only build"!!!

The "not ie 11" solved it for me. Thanks.

SherinBloemendaal

SherinBloemendaal commented on May 30, 2022

@SherinBloemendaal

First, modify .browserslistrc:

> 1%
last 2 versions
not dead
not ie 11

Then, execute npm run build and CMD output:

All browser targets in the browserslist configuration have supported ES module.
Therefore we don't build two separate bundles for differential loading.

Finally, I get "modern only build"!!!

The "not ie 11" solved it for me. Thanks.

Yes exactly, the "not ie 11" solved it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @tobyzerner@praveenpuglia@rsweny@alexcroox@LinusBorg

        Issue actions

          modern only build · Issue #4254 · vuejs/vue-cli