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

相关推荐
weixin_382395236 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__6 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.7 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~8 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华9 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子11 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅11 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni12 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学13 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端