深入浅出 Vite
vite
Vite 需要 Node.js 版本 14.18+,16+。
由两部分组成:
一个开发服务器,以项目最外层的
index.html为入口文件一套针对生产环境的 Rollup 构建命令。
浏览器支持
默认的构建目标是能支持 原生 ESM 语法的 script 标签、原生 ESM 动态导入 和 import.meta 的浏览器。
在线体验
https://stackblitz.com/edit/vitejs-vite-p476hg?file=index.html&terminal=dev
本地体验
直接安装 vite 即可。
npm init -y、npm install vite -D,然后配置 vite 启动命令 即可。
1 | |
也可以通过 npm create vite@latest 或者 yarn create vite 创建项目
兼容性
Vite 需要 Node.js 版本 14.18+,16+。然而,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意升级你的 Node 版本。
vite 指定根目录启动项目
vite 以当前工作目录作为根目录启动开发服务器。你也可以通过 vite serve some/sub/dir 来指定一个替代的根目录。
注意 Vite 同时会解析项目根目录下的配置文件(即 vite.config.js),因此如果根目录被改变了,你需要将配置文件移动到新的根目录下。
冷启动/预构建依赖
冷启动是指项目启动开发服务器时, node_module/.vite 下没有任何之前的预构建文件, 这一般是项目第一次启动, 或项目通过vite server --force启动, 也可能是你手动删除了node_module/.vite之后启动, 此时Vite需要扫描项目的依赖并使用esbuild对这些依赖进行预构建
依赖预构建:构建的包存放在 node_modules/.vite/deps 目录下,目的有如下几点:
不同的包有不同的导出格式(commonjs,umd,esmodule),通过预构建整合包的导出格式
引用包的路径可以直接使用
.vite/deps,方便路径重写(浏览器默认是不会去 node_modules 下寻找包的)解决网络多包传输的性能问题(以 lodash 为例,它有几千个模块,如果不做处理,在导入后浏览器会发几千个 HTTP 请求)
可以通过安装 lodash-es 这个包来做个实验,在项目中导入 lodash-es,你会发现 vite 对它进行了修改,将所有导出的模块整合成了一个 js 文件,浏览器也只会发送一次 HTTP 请求。
lodash-es 导出的所有定义好的模块方法
启动项目,Vite 已经整合所有 lodash-es 导出的模块
HTTP请求:/node_modules/.vite/deps/lodash-es.js?v=4db083fa
1 | |
我们可以通过 vite.config.js 来配置一下,不对 lodash-es 预构建:
1 | |
重启服务后,你会发现浏览器发送了很多个 HTTP 请求去加载 lodash-es 导出的每个模块方法。
vite为什么快?
开发环境不打包(
Vite 以 原生 ESM 方式提供源码),目前主流的浏览器已经支持模块化了。<script type="module" src="...">按需加载模块,不像webpack那样构建所有源码,vite是根据路由拆分的代码模块,只会处理当前屏幕上实际使用到的模块
vite 使用 esbuild 预构建依赖(不经常改动的依赖包)
利用 HTTP 头来加速整个页面的重新加载。(
源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求。)
vite.config.js
如果项目添加了 vite.config.js,启动项目或者打包项目时,vite 会自动读取这个配置文件
defineConfig
写配置文件时,为了有更好的语法提示,我们可以使用 defineConfig 方法来包裹配置对象
1 | |
或者这样写:
1 | |
defineConfig 也可以接收一个函数作为参数,这个函数也有一个参数:
1 | |
我们可以通过 command 或者 mode 来执行不同环境的配置。
区分打包配置
我们可以根据不同环境,编写不同的配置文件 vite.base.config、vite.dev.config、vite.prod.config。
vite.config.js
1 | |
环境变量配置
Vite 使用 dotenv 从你的 环境目录 中的下列文件加载额外的环境变量:
1 | |
在 vite.config.js 中,想要获取配置的环境变量,我们需要通过如下形式获取:
1 | |
options.mode 可以通过 yarn dev --mode develop 指定。
process.cwd() 表示当前文件的 执行目录
loadEnv 第三个参数是 prefixs,环境变量的前缀,默认是 VITE_,默认情况下只有前缀为 VITE_ 会被加载,除非更改了 prefixes 配置。
在客户端获取环境变量
配置的环境变量会存放到 import.meta.env 中。
为了防止意外地将一些环境变量泄漏到客户端,只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码。
修改默认的环境变量前缀
1 | |
增加测试环境
package.json
1 | |
添加 .env.test 文件,写入测试环境的配置即可。
Vite 如何执行 .vue 文件
Vite 是一个开发服务器,以项目最外层的 index.html 为入口文件。当它遇到 .js 文件结尾的文件,会去开发服务器请求这个 js 文件。并且告诉浏览器以 Content-Type: text/javascript 去解析这个文件。
如果遇到是 .vue 文件,首先会在开发服务器解析 vue 文件,将 vue 文件的内容转化为 js 内容,虽然它是 .vue 结尾的文件,我们还是可以通过 Content-Type: text/javascript 告诉浏览器使用 js 的形式去解析执行文件。
假设 Vite 开发服务器如下:
1 | |
css.modules
任何以 .module.css 为后缀名的 CSS 文件都被认为是一个 CSS modules 文件。
1 | |
1 | |
CSS modules 行为可以通过 css.modules 选项 进行配置。
如果 css.modules.localsConvention 设置开启了 camelCase 格式变量名转换(例如 localsConvention: ‘camelCaseOnly’),你还可以使用按名导入。
1 | |
原理
在 Vite 开发服务器中,遇到了 .module.css 结尾的文件,通过一定的规则将类名进行替换,比如 .red 替换成 ._red_hjlk23_1
并创建一个映射对象 { red: '_red_hjlk23_1' }
将替换过后的内容,塞进动态创建的style 标签里,并且插入到 head 中
将 .module.css 结尾的内容全部替换成 js 内容,方便 热更新
其他配置
css.modules
配置 CSS modules 的行为。选项将被传递给 postcss-modules。
1 | |
配置 CSS 预处理器(less、scss)
https://cn.vitejs.dev/config/shared-options.html#css-preprocessoroptions
css.preprocessorOptions
math 可用的四个选项是:
- always(3.x 默认值)- 支持各种形式的运算
- parens-division (默认 4.0) - 使用 / 运算符不在括号外执行除法(但可以在括号外使用
./运算符进行 “forced” -./已弃用) - parens | strict - 所有数学表达式都需要括号。
- strict-legacy(在 4.0 中删除)- 在某些情况下,如果无法计算表达式的任何部分,则不会计算数学。
设置全局变量,而不是定义在一个单独的文件里频繁的导入。
1 | |
使用的时候,依然使用 @mainColor 形式。
css.devSourcemap
在开发过程中是否启用 sourcemap。
默认情况下 css.devSourcemap 是 false,我们编写的 css 文件会被编译到 style 标签内,并插入到 head 标签中。
如果想要知道我们的 css、less 文件的原始内容、编写的位置,可以将 css.devSourcemap 设置为 true。
css.postcss
单独使用 postcss 来编译 css
npm i -D postcss postcss-cli
需要添加 postcss.config.js 配置文件
执行命令
1 | |
postcss-plugins列表
比较常用的 postcss-preset-env,它可以将现代 CSS 转换为大多数浏览器都能理解的内容,根据目标浏览器或运行时环境确定所需的填充。和 babel-preset/env 一样,它是一套插件的集合。
postcss 停止处理 less、sass了
less 和 sass 等一系列预处理器的 postcss 插件已经停止维护了,我们需要用 less 或 sass 自己的编译器将代码处理完,编译结果给到 postcss。
所以,业内也说,postcss 是 后处理器
不维护的主要原因是,less 或 sass 经常更新,postcss 官方也必须得跟着更新对应的插件,否则会出现问题。这样一来,就导致维护成本高,postcss 官方也觉得没有必要自己去维护。
目前来说,大多数 less 或 sass 的 postcss plugin 是有社区人员维护的。
配置别名 ts 报错问题
导入 nodejs 内置模块时可能提示找不到模块,安装 yarn add @types/node -D
1 | |
但是导入模块时 ts 提示依然报错,修改 tsconfig.json
1 | |
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!