Joe
Joe

Reputation: 23

Vue-cli3 vue-cli-service build --modern doesn't work

After npm run build --modern runs successfully, I only see one app in the output. Shouldn't there be two? enter image description here

Upvotes: 1

Views: 2161

Answers (2)

tony19
tony19

Reputation: 138276

After npm run build --modern runs successfully, I only see one app in the output. Shouldn't there be two?

Actually, the build --modern command creates two apps in dist/js (see dist/js/app.4e3aeb0e.js and dist/js/app-legacy.10b7d753.js):

➜ ls -al dist/js
total 1840
drwxr-xr-x  10 tony  staff     320 Sep  2 19:25 .
drwxr-xr-x   7 tony  staff     224 Sep  2 19:25 ..
-rw-r--r--   1 tony  staff    4772 Sep  2 19:25 app-legacy.10b7d753.js                    <-- LEGACY
-rw-r--r--   1 tony  staff   23682 Sep  2 19:25 app-legacy.10b7d753.js.map
-rw-r--r--   1 tony  staff    4718 Sep  2 19:25 app.4e3aeb0e.js                           <-- MODERN
-rw-r--r--   1 tony  staff   23625 Sep  2 19:25 app.4e3aeb0e.js.map
-rw-r--r--   1 tony  staff   80454 Sep  2 19:25 chunk-vendors-legacy.df5f2e07.js          <-- LEGACY
-rw-r--r--   1 tony  staff  397535 Sep  2 19:25 chunk-vendors-legacy.df5f2e07.js.map
-rw-r--r--   1 tony  staff   63276 Sep  2 19:25 chunk-vendors.4fd390fb.js                 <-- MODERN
-rw-r--r--   1 tony  staff  326296 Sep  2 19:25 chunk-vendors.4fd390fb.js.map

The apps are selectively loaded in index.html. First, the modern-mode scripts are preloaded with <link rel="modulepreload"> in the <head>:

<link href=/js/app.4e3aeb0e.js rel=modulepreload as=script>
<link href=/js/chunk-vendors.4fd390fb.js rel=modulepreload as=script>

Those scripts are later loaded in the <body> (Note: Only browsers that support <script type="module"> would load the script):

<script type=module src=/js/chunk-vendors.4fd390fb.js></script>
<script type=module src=/js/app.4e3aeb0e.js></script>

Finally, there's a nomodule fallback to the legacy-mode scripts (Note: The nomodule attribute tells the browser to load the script only if module scripts are not supported):

<script>!function () { var e = document, t = e.createElement("script"); if (!("noModule" in t) && "onbeforeload" in t) { var n = !1; e.addEventListener("beforeload", function (e) { if (e.target === t) n = !0; else if (!e.target.hasAttribute("nomodule") || !n) return; e.preventDefault() }, !0), t.type = "module", t.src = ".", e.head.appendChild(t), t.remove() } }();</script>
<script src=/js/chunk-vendors-legacy.df5f2e07.js nomodule></script>
<script src=/js/app-legacy.10b7d753.js nomodule></script>

I compare the size between the --modern and no modern, there is not difference?

I'm not sure how you're comparing the sizes, but the modern build is in fact larger in size. In the following example, I built a Vue-CLI generated app (with default preset) twice (once without --modern and again with --modern), and renamed the output directories. See the size increase in dist-modern of index.html and js/:

➜ ls -al dist*
dist-default:
total 16
drwxr-xr-x   7 tony  staff   224 Sep  2 19:25 .
drwxr-xr-x  13 tony  staff   416 Sep  2 19:27 ..
drwxr-xr-x   3 tony  staff    96 Sep  2 19:25 css
-rw-r--r--   1 tony  staff  1150 Sep  2 19:25 favicon.ico
drwxr-xr-x   3 tony  staff    96 Sep  2 19:25 img
-rw-r--r--   1 tony  staff   724 Sep  2 19:25 index.html
drwxr-xr-x   6 tony  staff   192 Sep  2 19:25 js

dist-modern:
total 16
drwxr-xr-x   7 tony  staff   224 Sep  2 19:25 .
drwxr-xr-x  13 tony  staff   416 Sep  2 19:27 ..
drwxr-xr-x   3 tony  staff    96 Sep  2 19:25 css
-rw-r--r--   1 tony  staff  1150 Sep  2 19:25 favicon.ico
drwxr-xr-x   3 tony  staff    96 Sep  2 19:25 img
-rw-r--r--   1 tony  staff  1213 Sep  2 19:25 index.html        <-- LARGER
drwxr-xr-x  10 tony  staff   320 Sep  2 19:25 js                <-- LARGER

Upvotes: 3

Felipe Augusto
Felipe Augusto

Reputation: 8184

I couldn't find the docs you put in the image, but from docs it says:

--modern builds your app using Modern Mode, shipping native ES2015 code to modern browsers that support it, with auto fallback to a legacy bundle.

Then I'd interpret that as just one flexible app.

From the docs you mentioned at the comment, I found this relevant part:

The cool part though is that there are no special deployment requirements. The generated HTML file automatically employs the techniques discussed in Phillip Walton's excellent post:

The modern bundle is loaded with <script type="module">, in browsers that support it; they are also preloaded using <link rel="modulepreload"> instead.

The legacy bundle is loaded with <script nomodule>, which is ignored by browsers that support ES modules.

A fix for <script nomodule> in Safari 10 is also automatically injected.

With that I'm able to interpret the same way, one app that behaves differently according to the browser.

Talking about the size, I'm not sure if it's necessary more settings to enable that, but according to the docs, it's not. I encourage you to continue reading them, for me this is the best way to be up to date to any needs.

Upvotes: 3

Related Questions