Skip to content

Vite 的基本使用

TIP

本小节对应的项目源代码,可以去 刘龙彬/vue3-component-study-1 仓库中下载。

浏览器内的模板编译 vs 构建工具

什么是浏览器内的模板编译

浏览器内的模板编译,指的就是把浏览器不识别的代码,编译成浏览器能识别和运行的代码。例如下面的 v-for 指令:

html
<ul>
  <li v-for="item in todos">
    <span>{{ item.task }}</span>
  </li>
</ul>

浏览器无法正确解析和执行 v-for 指令,因为这是 Vue 框架提供的特殊语法。因此,为了保证浏览器最终能渲染出列表的结构,Vue 必须做以下 2 件事情:

  1. 模板编译成 js 渲染函数
  2. 执行渲染函数并保证项目的持续运行

图示如下:

image-20230702234638950

我们之前在浏览器中引入的 vue-3.4.29.js 就完整的包含了 CompilerRuntime

也就是说,浏览器在真正调用 runtime-dom 运行网页之前,必须先调用 compiler-dom 进行模板的编译,这就带来了以下两个问题:

  1. 如果模板结构比较复杂,则在模板编译阶段会耗费很长的时间,造成用户体验差的问题。
  2. 导入的 vue.js 体积较大,因为它完整的包含了 CompilerRuntime,导致通过网络加载 vue.js 时比较耗时。

通过构建工具进行预构建

为了解决浏览器内模板编译耗时问题和导入的 vue.js 包体积大的问题,我们推荐大家通过构建工具对 Vue 项目进行预构建。构建工具的作用如下图所示:

image-20230702234638950

通过预构建,我们可以把模板编译的过程独立于项目运行之前。这样做的好处有以下两点:

  1. 节省了项目运行期间的模板编译过程,提高了性能
  2. 减少了大约 14KB 的 vue.js 包的体积,因为只需要依赖于 Runtime 运行时,不再依赖于 Compiler 编译器

主流的构建工具

目前,市面上主流的构建工具有以下 2 个:

  1. Webpack
  2. Vite

其中 Webpack 是一个老牌的前端工程化的构建工具,功能强大,插件众多,生态完善。支持 Vue,React,Angular 等主流的前端框架。

而 Vite 是 Vue 官方团队研发出的前端工程化构建工具,以卓越的构建性能而迅速崛起,同样支持 Vue,React,Angular 等主流的前端框架。

在今后的 Vue3 项目中,我们选择 Vite 作为项目的构建工具,主要原因有以下两点:

  1. 构建速度极快,开发体验好
  2. Vue 官方出品,和 Vue3 的项目完美契合

TIP

参考文档: 为什么选 Vite

基于 Vite 创建 Vue3 项目

创建 Vue3 项目

  1. 打开终端,运行如下的 npm 命令,基于命令行的方式快速创建 vue3 的项目:

    bash
    npm create vite@latest
  2. 通过对终端进行交互式的操作,选择项目的配置:

    npm create vue@latest
    Need to install the following packages:
      create-vue@3.10.4
    Ok to proceed? (y) y
    
    Vue.js - The Progressive JavaScript Framework
    
    √ 请输入项目名称: ... demo1
    √ 是否使用 TypeScript 语法? ... 否
    √ 是否启用 JSX 支持? ... 否
    √ 是否引入 Vue Router 进行单页面应用开发? ... 否
    √ 是否引入 Pinia 用于状态管理? ... 否
    √ 是否引入 Vitest 用于单元测试? ... 否
    √ 是否要引入一款端到端(End to End)测试工具? » 不需要
    √ 是否引入 ESLint 用于代码质量检测? ... 否
    √ 是否引入 Vue DevTools 7 扩展用于调试? (试验阶段) ... 否
    
    正在初始化项目 D:\demo1...
    
    项目初始化完成,可执行以下命令,把项目运行起来:
    
      cd demo1
      npm install
      npm run dev

熟悉项目的目录结构

  1. 认识根目录下重要的文件文件夹
index.html ········ 项目主页。当我们把项目运行起来之后,在浏览器中看到的就是这个页面。
src ··············· 源代码目录。开发过程中程序员写的所有代码,都要放到 src 目录下。
package.json ······ 包管理配置文件。记录了项目的依赖包,还提供了 `dev` 和 `build` 两个命令。
vite.config.js ···· vite 构建时的配置文件。用来对 vite 的运行方式进行个性化的配置。
  1. 认识 src 目录下的文件和文件夹:
main.js ··········· vue 项目运行的入口。
App.vue ··········· 整个项目的根组件。
assets ············ 静态资源的存放目录。例如图片、全局 CSS 样式表、字体等都可以放到此目录下。
components ········ 组件目录。用户自己封装的 .vue 组件可以放在此目录下。

Vue3 运行的两种方式

构建工具 + Runtime

官方推荐的运行方式

通过构建工具对模板代码进行预编译。当项目在浏览器中启动时,只需要 Runtime 版本的 Vue 即可运行项目。

基于 Vite 创建的 Vue3 项目,默认就采用了构建工具 + Runtime 的方式运行,而且这种默认的运行方式是高效的。

此时在项目的入口文件 src/main.js 中,通过 import { createApp } from 'vue' 导入的 Vue,是 node_modules/vue/dist/vue.runtime.esm-bundler.js 版本的 Vue。打开它的源代码,我们发现它只依赖于 @vue/runtime-dom

js
/**
 * vue v3.4.31
 * (c) 2018-present Yuxi (Evan) You and Vue contributors
 * @license MIT
 **/
import { initCustomFormatter, warn } from '@vue/runtime-dom'
export * from '@vue/runtime-dom'

// ...省略其它代码

Compiler + Runtime

不推荐使用

当项目在浏览器中启动时,先调用 Compiler 编译模板代码,再把编译完成的代码基于 Runtime 版本的 Vue 运行到浏览器中。

改造 src/main.js 模块,注释原有的代码并重新编写:

js
// import './assets/main.css'

// import { createApp } from 'vue'
// import App from './App.vue'

// createApp(App).mount('#app')

import { createApp, ref } from 'vue'

const app = createApp({
  setup() {
    const count = ref(0)

    return { count }
  }
})

app.mount('#app')

改造 index.html,定义模板结构并渲染数据:

html
<div id="app">
  <h1>count 的值是:{{ count }}</h1>
  <button @click="count++">+1</button>
</div>

此时,运行 Vite 项目会产生终端警告:

[Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".
  at <App>

这是因为以 import { createApp, ref } from 'vue' 方式导入的是 vue.runtime.esm-bundler.js 版本的 Vue,仅包含 Runtime 运行时,不包含 Compiler,所以当项目运行到浏览器的时候,无法调用 Compiler 编译 index.html 中的模板代码。

为了解决这个问题,我们需要参考 [Vue warn] 的警告消息导入 vue.esm-bundler.js 版本的 Vue 即可。因为它同时包含了 Compiler 和 Runtime。打开它的源码,我们发现它依赖了 @vue/compiler-dom@vue/runtime-dom

改造后的 main.js 中的代码如下:

js
// import { createApp, ref } from 'vue'
import { createApp, ref } from 'vue/dist/vue.esm-bundler'

const app = createApp({
  setup() {
    const count = ref(0)

    return { count }
  }
})

app.mount('#app')

总结

在实际工作中,推荐采用 构建工具 + Runtime 的方式进行项目开发。Compiler + Runtime 的方式仅供我们在学习 Vue 基础语法(指令、计算属性、侦听器等)的时候进行使用。

天不生夫子,万古长如夜