Vue 项目之 Webpack 打包 Vue 代码(2)

745 阅读3分钟

「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战

1. Vue 源码打包后的不同版本解析

前面提到了 Vue 的版本可以分为两类:Runtime + CompilerRuntime-only。而事实上,Vue 的源码打包后的具体版本是有很多个的:

image-20211121161849708

下面,我们对这些版本进行分类解析:

  • vue(.runtime).global(.prod).js

    • 通过浏览器中的 <script src="..."> 直接使用时,使用的就是这个版本;
    • 我们之前通过 CDN 引入的版本以及下载到本地的 Vue 的版本就是这个版本;
      • 比如我们在浏览器访问 Vue 源码的 CDN 地址:https://unpkg.com/vue@next,你会发现,它会自动跳转到 https://unpkg.com/vue@3.2.22/dist/vue.global.js 这个地址上(版本号可能会变),可以看到,CDN 引入的其实就是 vue.global.js 这个版本的 Vue 源码。
    • 会暴露一个全局的 Vue 供使用;
  • vue(.runtime).esm-browser(.prod).js

    • 用于通过原生 ES 模块导入使用(在浏览器中通过 <script type="module"> 来使用);
    • 就是说在通过 <script src="..."> 方式引入 Vue 源码时,如果添加了 type="module",就会使用这个 esm-browser 版本。
  • vue(.runtime).esm-bundler.js

    • 用于 webpackrollupparcel 等构建工具;

    • 在构建工具中引入 Vue 时,默认使用的是 vue.runtime.esm-bundler.js;

      这就意味着我们前面导入 Vue 的写法:

      ...
      import { createApp } from 'vue';
      ...
      

      这里的 'vue' 引用的其实是 vue.runtime.esm-bundler.js 这个版本,runtime 版本没有包含对 template 的解析,所以最终页面上没有显示对应的内容。

    • 因此,如果我们需要解析 template,就需要手动指定 vue.esm-bundler.js 版本:

      ...
      import { createApp } from 'vue/dist/vue.esm-bundler';
      ...
      

      指定完成后,我们再来运行 npm run build 命令对代码进行编译打包,打包成功后再来看浏览器页面中的效果:

      image-20211121180805046.png

      可以看到,template 中的内容成功渲染到了页面上,可见,这次就能成功编译 template 中的内容了。

  • vue.cjs(.prod).js

    • 服务器端渲染使用;
    • 通过 require() 方式在 Node.js 中使用;

上面这些版本中,被圆括号包裹起来的内容(.runtime.prod)属于可选项,它们的含义如下:

  • .runtime:如果添加了这项内容,就意味着使用“仅运行时”版本,这有个好处,因为“仅运行时”版本不包含“编译器”,所以相对来说其包的大小会更小。当我们不需要对 template 做编译时,就可以添加这项内容。
  • .prod:表示使用生产版本,生产版本是做过压缩的,好处也是包的大小更小些。

以上就是关于 Vue 不同的构建版本对应不同场景下的使用解析。

2. 运行时 + 编译器 vs 仅运行时

  • Vue 项目的开发过程中,我们有 3 种方式来编写 DOM 元素:
    1. template 模板的方式(之前我们使用的方式);
    2. render 函数的方式,使用 h 函数来编写渲染的内容(后面再讲组件化时会讲到);
    3. 通过 .vue 文件中的 template 来编写模板;
  • 它们的模板分别是如何处理的呢?
    • 方式 2 中的 h 函数可以直接返回一个虚拟节点,也就是 VNode 节点(也就是说我们不需要再做编译了,因为它直接返回的就已经是 VNode 了);
    • 方式 1 和方式 3 中的 template 都需要有特定的代码来对其进行解析:
      • 方式 1 中的 template 必须要通过源码中的一部分代码来进行编译;
      • 方式 3 .vue 文件中的 template 可以通过 vue-loader 结合另外一个库对其进行编译和处理;
  • 所以,Vue 在让我们选择版本的时候分为运行时 + 编译器仅运行时
    • 运行时 + 编译器包含了对 template 模板的编译代码,更加完整,但是也更大一些;
    • 仅运行时没有包含对 template 的编译代码,所以不支持对 template 的解析,但也相对更小一些。