深入浅出 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 协议 ,转载请注明出处!