什么是构建工具
首先,看下企业级项目里可能会用到哪些功能:
- TypeScript:如果遇到ts文件需要使用tsc将TypeScript代码转换为js代码
- React/Vue:安装react-compiler/vue-complier,将jsx文件或者vue文件转换为render函数
- less/sass/postcss/component-style:需要安装less-loader,sass-loader等一系列编译工具
- 语法降级:babel将ES新语法转换为旧版浏览器可接受语法
- 体积优化:uglifyjs将代码进行压缩,变成体积更小性能更高的文件
而浏览器只认识html,css,js,所以就需要一个东西能够把这些功能集成到一起,这个东西就是构建工具。将我们写的浏览器不认识的代码,交给构建工具进行编译处理的过程叫做打包,打包完成以后会给出浏览器可以认识的文件。
构建工具承担了哪些脏活累活:
- 模块化开发支持。支持直接从node_modules里引入代码 + 多种模块化支持
- 处理代码兼容性。比如babel语法降级,less/ts语法转换(不是构建工具做的,构建工具只是将这些语法对应的处理工具集成进来自动化处理)
- 提高项目性能。压缩文件,代码分割
优化开发体验:
- 自动监听文件变化:当文件变化后自动调用对应集成工具进行重新打包,然后在浏览器重新运行(整个过程叫做热更新,hot replacement)
- 开发服务器:解决跨域问题
总之,构建工具让我们不用关心生产的代码如何在浏览器上运行,只需关心我们的开发就行了。
手动安装Vite
首先,新建一个项目文件夹test-vite:mkdir test-vite && cd test-vite
。
前置准备
- 安装 Node.js 版本 18+ 或 20+
- 安装好pnpm:
npm i -g pnpm
配置npm全局安装路径,以管理员身份运行命令:npm config set prefix "E:\develop\NodeJS"
,E:\develop\NodeJS是Node.js安装目录。
配置npm镜像源地址:npm config set registry https://registry.npmmirror.com
。
开箱即用
安装 vite 命令行工具:pnpm add -D vite
。
创建一个 index.html 文件:<p>Hello Vite!</p>
。
然后在终端中运行 vite:pnpm vite
,就可以在 http://localhost:5173 上访问 index.html。
依赖预构建
Vite解决了3个问题:
- 不同的第三方包会有不同的导出格式,这个是Vite没法约束人家的
- 对路径的处理上可以直接使用.vite/deps,方便路径重写
- 网络多包传输的性能问题,这也是原生ES Module规范不敢支持node_modules的原因之一。有了依赖预构建,无论有多少的export和import,Vite都会尽可能的将他们进行集成,最后只生成一个或几个模块
配置文件
当以命令行方式运行 vite 时,Vite 会自动解析 项目根目录 下名为 vite.config.js 的配置文件。
配置智能提示
因为 Vite 本身附带 TypeScript 类型,所以可以通过 IDE 和 jsdoc 的配合来实现智能提示:
/** @type {import('vite').UserConfig} */
export default {
// ...
}
情景配置
新建3个配置文件:base文件(vite.base.config.js)、开发环境(vite.dev.config.js)和生产环境(vite.prod.config.js)配置文件:
import { defineConfig } from 'vite'
export default defineConfig({
// ...
})
修改 vite.config.js 配置文件:
import { defineConfig } from 'vite'
import viteBaseConfig from './vite.base.config'
import viteDevConfig from './vite.dev.config'
import viteProdConfig from './vite.prod.config'
// 策略模式
const envResolver = {
build: () => {
console.log('生产环境...')
return { ...viteBaseConfig, ...viteProdConfig }
},
serve: () => {
console.log('开发环境...')
return { ...viteBaseConfig, ...viteDevConfig }
},
}
export default defineConfig(({ command }) => {
return envResolver[command]()
})
修改 package.json 文件,添加:
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "vite --mode test"
},
在终端中运行命令:pnpm dev
或pnpm build
。
环境变量
vite内置了dotenv这个第三方库,dotenv会自动读取 .env 文件,并解析其中的环境变量,将其注入到process对象下(但vite考虑到和其他配置的一些冲突问题,并不会直接注入到process对象下)。
不过当你的确需要时,可以使用 Vite 导出的 loadEnv 函数来加载指定的 .env 文件。
新建3个环境变量配置文件:
- .env 共用环境变量
- .env.development 开发环境需要用到的环境变量
- .env.production 生产环境需要用到的环境变量
修改 vite.config.js 配置文件的 export:
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd(), '')
console.log('当前环境:', env)
return envResolver[command]()
})
在终端中运行命令:pnpm dev --mode development
,会将mode设置为development传递进来。
当调用loadEnv时,会做如下几件事:
- 直接找到.env文件,解析其中的环境变量,并放进一个对象里
- 将传进来的mode变量值进行拼接,如 .env.development,根据提供的目录去取对应的文件进行解析,并放进一个对象里
如果是客户端,Vite会将对应的环境变量注入到import.meta.env里去。但为了防止将隐私性的变量直接送进import.meta.env中,所以Vite做了一层拦截。如果环境变量不是以VITE开头,就不会注入到客户端中去。如果想要更改VITE这个前缀,可以使用envPrefix配置。
vite和create-vite的关系:
create-vite是vite的脚手架,create-vite内置了vite。