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

简介: 本篇文章就是教学如何基于 vite 从 0 到 1 启动一个 Vue 项目,在传统启动中,如果你是刚开始接触 HTML/CSS/JavaScript 三件套开始接触的前端,那么你可能比较熟悉或者比较能接受的引入 Vue 的方式可能是使用 CDN 的方式

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

IMG

传统启动

如果你是刚开始接触 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

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

IMG

选择完成之后

IMG

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

IMG

接下来要做的就是安装 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 这个软件,你会发现这个文件结构已经能够运行

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

IMG

此时控制台会有一个错误

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

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

IMG

不过这个错误的原因是我们在引入的 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

再次刷新运行

IMG

解析成功

你可能会觉得主动去 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,结果如下

IMG

同样解析成功

与 Webpack 比较

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

Vite

IMG

Webpack

IMG

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

Vite

IMG

Webpack

IMG

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

IMG

添加 .vue 支持

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

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

IMG

对于 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,解析成功

IMG

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

  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 文档
相关文章
|
JavaScript 数据可视化
vue-cli学习一:vue脚手架的 vue-cli2和vue-cli3版本 创建vue项目,vue的初始化详解
这篇文章介绍了如何使用vue-cli 2和3版本来创建Vue项目,并详细说明了两者之间的主要区别。
586 5
vue-cli学习一:vue脚手架的 vue-cli2和vue-cli3版本 创建vue项目,vue的初始化详解
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
808 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
JavaScript 容器
乾坤qiankun框架搭建 主应用为vue3的项目。
乾坤qiankun框架搭建 主应用为vue3的项目。
1221 2
|
人工智能 JavaScript 关系型数据库
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
603 14
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
|
前端开发 JavaScript Java
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
783 13
【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
|
SQL JavaScript 安全
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
714 11
【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
|
人工智能 JavaScript 安全
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
1061 13
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
|
JavaScript 前端开发 UED
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
632 0
|
数据采集 监控 JavaScript
在 Vue 项目中使用预渲染技术
【10月更文挑战第23天】在 Vue 项目中使用预渲染技术是提升 SEO 效果的有效途径之一。通过选择合适的预渲染工具,正确配置和运行预渲染操作,结合其他 SEO 策略,可以实现更好的搜索引擎优化效果。同时,需要不断地监控和优化预渲染效果,以适应不断变化的搜索引擎环境和用户需求。
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。