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)
}

相关推荐
C澒1 小时前
多场景多角色前端架构方案:基于页面协议化与模块标准化的通用能力沉淀
前端·架构·系统架构·前端框架
崔庆才丨静觅2 小时前
稳定好用的 ADSL 拨号代理,就这家了!
前端
江湖有缘2 小时前
Docker部署music-tag-web音乐标签编辑器
前端·docker·编辑器
恋猫de小郭3 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅9 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606110 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了10 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅10 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅10 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅11 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端