vite5 的基本使用与自动导入文件

介绍

Vite 和 Webpack 一样,也是个前端工程化构建工具。根据官方文档的描述它由两部分组成:

  • 一个开发服务器,它基于原生 ES 模块提供了丰富的内建功能,如速度快到惊人的模块热更新(HMR)。
  • 一套构建指令,它使用 Rollup 打包你的代码,并且它是预配置的,可输出用于生产环境的高度优化过的静态资源。

对于生产构建,vite 的目标浏览器是:

支持原生 ES 模块、原生 ESM 动态导入和 import.meta。

现代浏览器大多已经能够支持 ES6+ 的语法,我们只需要在 index.html 使用 <script src> 引入 js 文件时,添加 type 属性为 module,即可以支持 ES Module 的模块化方案:

html 复制代码
<!-- index.html -->
<script src="./index.js" type="module"></script>

所以在开发项目时,没必要再像 webpack 那样将 es6+ 的语法使用 babel 等工具转成 es5。但是 vite 也不是什么都没做就直接把我们编写的 js 代码扔给浏览器了,因为还有一些问题需要处理,比如:

  • import 文件时必须添加后缀名,也就是不能省略 .js
  • 如果导入的文件又依赖其它的文件,那么每个 js 文件都会被依次加载,影响效率;

比如使用了 lodash 库,这里安装的是使用 ES Module 规范的 lodash-es,导入时也是直接去找到导出了 lodash 对象的 lodash.default.js:

javascript 复制代码
// index.js
import _ from './node_modules/lodash-es/lodash.default.js'
const add = (augend, addend) => {
  return _.add(augend, addend)
}
console.log(add(1, 2))

lodash.default.js 里又导入了 array.js、collection.js 等,array.js 里又需要依赖其它文件,这些文件都会被一个个加载:

  • 无法处理 .ts 或 .vue 等文件。

借助 vite,就能帮我们解决上述这些问题。

安装与使用

初体验

先使用 pnpm 直接安装个 vite 来体验下:

powershell 复制代码
pnpm init
pnpm add vite -D

安装成功后可以在 node_modules.bin 目录下看到已经有了名为 vite 的可执行文件:

所以可以直接执行:

powershell 复制代码
npx vite

vite 就会开启开发服务器并构建我们的项目。现在,在导入文件时,就可以去掉后缀名,并且直接从 lodash-es 导入:

javascript 复制代码
import _ from 'lodash-es'
const add = (augend, addend) => {
  return _.add(augend, addend)
}
console.log(add(1, 2))

vite 会将 lodash 相关文件都放到一个文件去,这样无疑减少了 http 请求,提高了效率:

处理 ts 文件

vite 对 ts 是天生支持的,无需像在 webpack 中使用时还要安装 typescript 和 ts-loader。比如项目中有 ts 代码:

typescript 复制代码
// utils\index.ts
export function sayHello(msg: string) {
  console.log(msg)
}
javascript 复制代码
// index.js
import { sayHello } from './utils/index'
const msg = 'hello juejin'
sayHello(msg)

在开发阶段,vite 会使用 ESBuild 将 ts 文件转换成 js 代码,然后通过使用 connect 创建的开发服务器将对 utils/index.ts 的请求进行转发,将转换成 js 的文件返回给浏览器,所以最终浏览器得到的 utils/index.ts 里其实都是 js 代码,可以直接解析:

甚至在 index.html 的 <script> 引入的文件都可以直接是 ts 文件:

html 复制代码
<!-- index.html -->
<script src="./index.ts" type="module"></script>

处理样式文件

vite 不需要额外的配置就能处理 css、sass 和 less 等文件,但是如果使用了 sass 或 less 还是需要安装这些预处理依赖的。比如在 index.js 导入了 css 和 scss 文件:

javascript 复制代码
import './styles/main.css'
import './styles/main.scss'

那么就需要安装好 sass:

powershell 复制代码
npm i sass -D

如果要使用 PostCSS,也是只要安装了 postcss 和其依赖的插件,比如 postcss-preset-env,然后再配置下 postcss.config 即可,而不需要像 webpack 那样还要去 webpack.config 配置什么 loader:

powershell 复制代码
npm i postcss postcss-preset-env -D
javascript 复制代码
// postcss.config.js
module.exports = {
  plugins: [require('postcss-preset-env')]
}

处理 vue 文件

如果我们的项目里有 vue 文件:

vue 复制代码
<!-- vue\App.vue -->
<script setup>
  import { ref } from 'vue'
  const msg = ref('Hello')
</script>

<template>
  <div>{{ msg }}</div>
</template>
javascript 复制代码
// index.js
import { createApp } from 'vue'
import App from './vue/App.vue'

const app = createApp(App)
app.mount(document.querySelector('#app'))

我们需要先安装 vue:

powershell 复制代码
pnpm add vue

并且安装处理 vue 文件的插件 @vitejs/plugin-vue:

powershell 复制代码
pnpm add @vitejs/plugin-vue -D

然后在 vite.config.js 中使用插件,这里直接使用 ES Module 的语法来导出对象,因为 vite5 中 CJS 的 Node API 已经被废弃:

javascript 复制代码
import vue from '@vitejs/plugin-vue'
export default {
  plugins: [vue()]
}

如果是使用脚手架工具 create vite 创建的 vue 项目,即:

powershell 复制代码
pnpm create vite

在生成的 vite.config.ts 中代码如下,可以看到和上面我们自己写的差不多,但是使用了 defineConfig 这个方法,好处在于编写时会有提示,不容易敲错:

typescript 复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

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

在浏览器查看效果时,可以看到,浏览器获取的 App.vue 文件里的内容其实也是被替换成了 js 代码:

打包与预览

执行如下命令便可对项目打包:

powershell 复制代码
npx vite build

打包完成后可以执行如下命令预览:

powershell 复制代码
npx vite preview

自动导入文件

下面再顺便说一个 vite 如何自动导入文件的功能。

在使用 vite 构建的 vue + ts 项目中,当需要定义路由时,因为我是将各个 route 对象抽离到了 src\router\modules 目录下定义,然后在 src\router\index.ts 通过 router.addRoute 动态添加的:

所以需要在 index 文件自动地去获取 modules 目录下的各个 route 对象。这一功能如果是在原来使用 vue-cli 搭建的项目中,可以使用 webpack 的 require.context(),而在 vite 中,则是使用 import.meta.glob()

typescript 复制代码
const modulesFiles: Record<string, any> = import.meta.glob('./modules/*.ts', {
  eager: true
})

如果单独打印 console.log(import.meta.glob('./modules/*.ts')),会发现其结果为一个对象,里面的 key 都是文件的路径,value 都是函数:

import() 的返回值是一个 promise,需要我们在 .then 里获取导入的结果然后编写后续逻辑,这主要是为了实现懒加载,比如我们在定义 route 的 component 属性时一般也是使用这种语法来实现的路由懒加载。但是此处我们显然希望立即获取到结果,于是我们给 import.meta.glob() 传入了第 2 个参数 { eager: true }

直接打印 modulesFiles,结果如下:

现在对象里的 value 就都是 Module 了,我们可以通过 default 属性来获取各个文件导出的 route 对象了:

typescript 复制代码
for (const key in modulesFiles) {
  const module = modulesFiles[key].default
  router.addRoute(module)
}

相关推荐
玩电脑的辣条哥2 小时前
Python如何播放本地音乐并在web页面播放
开发语言·前端·python
ew452182 小时前
ElementUI表格表头自定义添加checkbox,点击选中样式不生效
前端·javascript·elementui
suibian52352 小时前
AI时代:前端开发的职业发展路径拓宽
前端·人工智能
Moon.92 小时前
el-table的hasChildren不生效?子级没数据还显示箭头号?树形数据无法展开和收缩
前端·vue.js·html
垚垚 Securify 前沿站3 小时前
深入了解 AppScan 工具的使用:筑牢 Web 应用安全防线
运维·前端·网络·安全·web安全·系统安全
工业甲酰苯胺5 小时前
Vue3 基础概念与环境搭建
前端·javascript·vue.js
mosquito_lover17 小时前
怎么把pyqt界面做的像web一样漂亮
前端·python·pyqt
柴柴的小记9 小时前
前端vue引入特殊字体不生效
前端·javascript·vue.js
柠檬豆腐脑9 小时前
从前端到全栈:新闻管理系统及多个应用端展示
前端·全栈
bin915310 小时前
DeepSeek 助力 Vue 开发:打造丝滑的颜色选择器(Color Picker)
前端·javascript·vue.js·ecmascript·deepseek