Search code examples
vue.jsvue-clivue-cli-3

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


Solution

  • 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