The modern property in Nuxt.js allows you to serve both modern bundles to modern browsers and legacy bundles to those legacy browsers that still exist. When we write modern JavaScript code using async/await, fetch, arrow functions etc we still transpile this code to ES5 and bundle it with polyfills to accommodate the small percentage of users still on older browsers.
The solution is to use
<script type="module"> // for modern browsers
<script nomodule> // for legacy ones
Nuxt.js allows us to easily activate this by using the modern property. By default it is set to false so if you want to use it you will have to add it to your package.json script.
There are 3 possible values for the modern mode, 'client', 'server' and false.
- 'client': Serves both the modern bundle and the legacy bundle scripts. It will provide a link rel="modulepreload" for the modern bundle.
- 'server' or true: The node.js server will check the browser version based on the user agent and serve the corresponding modern or legacy bundle.
- false: Disables the modern build
In order to active it you will need to add the --modern flag(-m for short) and add the mode you require to your build or start scripts.
{
"scripts": {
"build: "nuxt build --modern=server",
}
}
When building static sites which use the generate command the modern property also works but only the client option is honoured and will be selected automatically so we don't have to provide any values.
{
"scripts": {
"generate: "nuxt generate -m",
}
}
And that's it. Just by modifying one small command you will now reduce your bundle size for modern browsers yet still have a fallback for those legacy ones. :)
Top comments (8)
I still can't understand why we need:
"build: modern": "nuxt build --modern = server",
Cause i thought nuxt perfectly works with fetch and others features (Thanks to polyfills)
Yes, we can disable support for older browsers, but for what? What exactly will be an advantage for us using this method
At the bottom of the documentation of the
modern
property there is a link to an article which explains it better. Basically, if you cut out polyfills your bundle size and parse/eval time can be cut down by half (*based on the numbers of the article).But is important to note that this approach doesn't disable support for older browser, it just avoid loading polyfills on modern browser which doesn't need them.
Interesting! Any way to run the analyzer with the "modern" option set? I'm curious what the difference will be.
Also, I am running a static generated site; would it be safe to simply set the "-m" flag on my deployment server, or do I need to test/make some changes before that?
you can just set it on the deployment server. no need to do anything else. you can try running both commands in dev and see. never tried it to be honest. Here is some more info on how modern mode works
cli.vuejs.org/guide/browser-compat...
I'm failing to come up with any kind of scenario where I wouldn't want this enabled 100% of the time? This there a reason this isn't turned on by default in nuxt?
it will be in the future I believe
Do you know how to disable polyfills completely? In my not-so-comprehensive tests, google pagespeed insight seems to be running as a legacy browser. and this caused all the polyfills to be loaded. which also makes my pagespeed score significantly lower.
oh wow, interesting. no idea to be honest