likes
comments
collection
share

基于 Vite 从 0 到 1 启动一个 Vue2 项目

作者站长头像
站长
· 阅读数 47

本篇文章就是教学如何基于 vite01 启动一个 Vue 项目,下面是这个项目运行效果

基于 Vite 从 0 到 1 启动一个 Vue2 项目

传统启动

如果你是刚开始接触 HTML/CSS/JavaScript 三件套开始接触的前端,那么你可能比较熟悉或者比较能接受的引入 Vue 的方式可能是使用 CDN 的方式,大概如下(下面这个是我要介绍的例子)

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<body>
  <div id="app">
    <div>
      {{ "count:" + count }}
      <button @click="handleClick">click + 1</button>
    </div>
  </div>
</body>
<script>
  new Vue({
    data() {
      return {
        count: 0,
      }
    },
    methods: {
      handleClick() {
        this.count++;
      },
    }
  }).$mount('#app');
</script>

但如果你继续深入学习的话或者看过一些学习视频,他们可能会推荐你去使用 Webpack 或者 Vite 等一些成熟的工具链去开发项目,而前面我有一篇文章介绍过基于 Webpack 从 0 到 1 启动一个 Vue 项目,那么如何通过 Vite 去运行一个项目呢? 接下来就教你们一步步简单运行一个 Vue 项目

Vite 启动

先找个位置并在终端(或者命令行)初始化一个项目

npm init

初始化后会有一些选项,可以直接回车全部忽略,也可以根据自己意向填写

基于 Vite 从 0 到 1 启动一个 Vue2 项目

选择完成之后

基于 Vite 从 0 到 1 启动一个 Vue2 项目

这个时候系统会创建一个 package.json 文件

基于 Vite 从 0 到 1 启动一个 Vue2 项目

接下来要做的就是安装 Vue

# 文章使用的 Vue2 运行
npm install vue@2.7.10

然后你的 package.json 会有多出一个 dependencies 属性,如下

{
  "dependencies": {
    "vue": "^2.7.10"
  }
}

所以上面的例子需要改成如下写法

// <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
import Vue from "vue"

但这种写法在 HTML 文件需要使用 module 加持,而且现在的 Vue 的位置在 node_modules,不能再从 HTML 中直接导入,所以需要将上面例子中的 JS 代码脱离,命名为 main.js

import Vue from "vue";

new Vue({
  data() {
    return {
      count: 0,
    }
  },
  methods: {
    handleClick() {
      this.count++;
    },
  }
}).$mount('#app');

html 部分命名为 index.html

<body>
  <div id="app">
    <div>
      {{ "count:" + count }}
      <button @click="handleClick">click + 1</button>
    </div>
  </div>
</body>
<script src="./main.js"></script>

此时的文件结构

├── node_modules
├── main.js
├── index.html
├── package-lock.json
└── package.json

如果你有过 HTML 部署的经验或者你的电脑上的 VS Code 恰好有 Live Server 这个软件,你会发现这个文件结构已经能够运行

但是效果和预期不一样,会是下面这样

基于 Vite 从 0 到 1 启动一个 Vue2 项目

此时控制台会有一个错误

Uncaught SyntaxError: Cannot use import statement outside a module (at main.js:1:1)

这个错误的意思是无法在模块外部使用 import,虽然但是,我没能理解它这个的意思

基于 Vite 从 0 到 1 启动一个 Vue2 项目

不过这个错误的原因是我们在引入的 main.js 中使用了 ES Module 语法/规范

import Vue from "vue";

那么如何能够解决这个报错呢?这里可以普及一下 esm 的理念,现在浏览器已经支持直接使用 ES Module,这意味着使用 ES Module 规范的模块可以直接在浏览器中使用,其实这也是 Vite 这类框架的出现的基础,直接使用模块而不再是打包成一个文件引用

而解决这个问题的具体的操作如下

完成以下操作,需要下载 Live Server 插件

  1. 第一步,在 index.html 的引入脚本中开启 type="module",如下
<body>
  <div id="app">
    <div>
      {{ "count:" + count }}
      <button @click="handleClick">click + 1</button>
    </div>
  </div>
</body>
<script type="module" src="./main.js"></script>
  1. 第二步,开启 package.json"type": "module"
{
  // ...
  "type": "module",
  // ....
}
  1. 第三步,最骚的来了,根据这个对不同构建版本的解释 - Vue.js 文档找到对应的文件 vue.esm.broswer.js(可以直接在浏览器使用,而且既有编译时又有运行时),然后拖出来和 index.html 在同一文件夹下,修改 main.js 的导入方式

PS: 有编译时的 Vue.js 才可以正确解析 {{ "count:" + count }}

import Vue from "./vue.esm.browser.js"

// ...

此时的文件结构

├── node_modules
├── main.js
├── index.html
├── vue.esm.browser.js
├── package-lock.json
└── package.json

再次刷新运行

基于 Vite 从 0 到 1 启动一个 Vue2 项目

解析成功

你可能会觉得主动去 node_modules 里拖出一个文件也太秀了,有没有一种工具可以直接找到并运行在浏览器里呢?没错,vite 就是干这件事的

Vite

npm install vite --save-dev

新增 script

{
  // ..
  "scripts": {
    "dev": "vite",
  },
  // ...
}

修改 main.js

import Vue from "vue";

新增 vite.config.js 文件

import { defineConfig } from "vite";

// https://vitejs.dev/config/
export default defineConfig({
  // root 默认值是 process.cwd(), 即当前工作文件夹
  // 所以例子中的 index.html 无需任何修改
  // 同时 index.html 中引用的 .js 需要在同一个 root 目录下
  root: process.cwd(),
  server: {
    port: 5173, // 默认端口是 5173
  },
  plugins: [vue()],
});

注意:由于 Vite 配置有一些默认值,所以我将一些关键的属性重写并做了注释

运行 npm run dev,结果如下

基于 Vite 从 0 到 1 启动一个 Vue2 项目

同样解析成功

与 Webpack 比较

比较一下 Webpack 启动 Vue2 项目和 Vite 启动 Vue2 项目的终端/命令行对比图

Vite

基于 Vite 从 0 到 1 启动一个 Vue2 项目

Webpack

基于 Vite 从 0 到 1 启动一个 Vue2 项目

通过上面的图片可以看出来,Vite 好像其实就是只开了 5173 的服务,而 Webpack 却的实打实的 code generated(打包),同时这就是这两个开发工具为什么在速度上会有差距,回到 Vite 文档的两张图,你会更清楚两者的工作原理

Vite

基于 Vite 从 0 到 1 启动一个 Vue2 项目

Webpack

基于 Vite 从 0 到 1 启动一个 Vue2 项目

在看一下刚才的例子是不是真的请求过我们的 Vue 模块

基于 Vite 从 0 到 1 启动一个 Vue2 项目

添加 .vue 支持

有朋友可能会问了,你这个味道不对呀,我平时开发都是用的 .vue 后缀的文件开发呀,我要用单文件组件(Single File Components (SFCs))开发!

对于现在的前端工程化来说,不可能全部 html 代码都写在同一个文件里,正确的处理方式是编写 SFC 然后通过 JS 模块化统一导入到 html

基于 Vite 从 0 到 1 启动一个 Vue2 项目

对于 JS 的模块化当然是只能导入 .js 文件,但是为了便于平时的开发,Vue 框架提供了 .vue 文件(SFC)的选择,然后通过编译转成 .js 文件

而在 Vite 中提供这一支持的是

由于本篇文章采用的是 vue@2.7.10,因此需要导入 @vitejs/vite-plugin-vue2

npm install @vitejs/plugin-vue2 --save-dev

修改 vite.config.js

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue2";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
});

迁移 index.html 模板内容和 main.js 部分 JavascriptApp.vue

<!-- index.html -->
<body>
  <div id="app"></div>
</body>
<script type="module" src="./main.js"></script>
// main.js
import Vue from "vue";
import App from "./App.vue";

new Vue({
  render: (h) => h(App),
}).$mount("#app");
<!-- App.vue -->
<template>
  <div>
    {{ "count:" + count }}
    <button @click="handleClick">click + 1</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    handleClick() {
      this.count++;
    },
  },
};
</script>

再次运行 npm run dev,解析成功

基于 Vite 从 0 到 1 启动一个 Vue2 项目

从上面文章其实有一些问题并没有详细讲解,读者看完可以思考一下

  1. 为什么通过 import Vue from 'vue' 能够直接找到 node_modules 中的对应文件
    1. import Vue from 'vue' 是怎么判断是 CommonJS 还是 ES Module
    2. 设置 <script type="module" ... />package.json 的属性 "type": "module" 之后,为什么 import Vue from 'vue' 默认导出的是仅运行时的 Vue,即 vue.runtime.esm.js
  2. 基于 ES Module 规范导入模块/库/包,那么面对一些老的库,不支持 ES Module 时,Vite 会怎么处理?

本篇文章例子的 githubpandoralink/vue2-start-with-vite

参考资料

  1. 为什么选 Vite - Vite 官方文档
  2. 对不同构建版本的解释 - Vue.js 文档
转载自:https://juejin.cn/post/7171097111964942349
评论
请登录