1. Vite和Webpack
-
速度和效率
- 构建速度
- 打包速度
-
使用方式
-
插件生态
-
配置复杂度
举例:
webpack
加载less
:
vite
中加载less
:
-
-
热更新机制
2. 核心原理
-
模块声明
首先在把
type= "module"
放到<script>
标签中来声明这是一个模块<script type="module" src="main.js"></script>
这样通过
src
或import
导入的文件将会发起http请求;vite会拦截这些请求,并将请求文件进行特别处理。 -
裸模块替换
当试图请求node_modules文件夹的文件时,会进行
裸模块替换
(路劲转换为相对路劲),浏览器中只识别相对路劲
和绝对路劲
。
import Vue from ‘vue’ 会转换成 import Vue from ‘/@modules/vue’
-
解析
/@moudules
接下里将
/@modules
解析为真正的文件地址,并返回给浏览器。其它打包工具,如webpack
打包时帮我们做了这件事情。通过
import
导入的文件webpack
会去node_modules/包名/package.json
文件内找moduel
属性,如下例子。{ "license": "MIT", "main": "index.js", "module": "dist/vue.runtime.esm-bundler.js", "name": "vue", "repository": { "type": "git", "url": "git+https://github.com/vuejs/vue-next.git" }, "types": "dist/vue.d.ts", "unpkg": "dist/vue.global.js", "version": "3.2.20" }
只要将这个
dist/vue.runtime.esm-bundler.js
这个地址文件返回就好了。 -
解析单文件(
SFC
)组件我们知道.vue文件中包含了
template
,script
,style
,三个部分,vite分别对这三个部分做了处理- (1)解析template
vite中使用
/@vue/compiler-dom
来编译template, 编译后返回的结果类似如下图所示(2)处理script
**
vite
**中使用/@vue/compiler-sfc
来处理单文件组件,它的作用跟vue-loader一样。它的解析结果就好像如下所示。(3)解析style
**
vite
对style
的处理比较特殊,可以看到vite
**项目请求type=style
返回的内容中调用了updateStyle
方法,在Vite
中是把它放在了 热更新 的模块中,在mini-vite
中,我们模拟实现的方式, 在client
实现该功能的简版。
3. 安装
-
使用
npm
全局安装vitenpm install vite -g vite --version #查看vite是否安装成功
-
搭建第一个
vite
项目# pnpm安装 pnpm create vite # npm安装 npm create vite@latest
-
后面按提示操作
4. 使用
-
开发服务器
vite [root]
-
构建
vite build [root]
-
其他
vite optimize [root] #预构建依赖 vite preview [root] #本地预览构建产物
5. 工程化
1. 目录解析
2. vite.config.js
配置
-
plugin
简单插件配置 -
resolve
alias
配置引用路径(含tsconfig.json
配置)extension
配置扩展名(默认扩展名为['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
)
-
build
-
target
配置js
输出标准,有以下几个值分别代表不同的标准:-
es2015
:输出ES2015
代码,适用于现代浏览器。 -
esnext
:输出ESNext
代码,适用于现代浏览器。 -
chrome58
:输出Chrome 58
及以上版本支持的代码。 -
firefox57
:输出Firefox 57
及以上版本支持的代码。 -
safari11
:输出Safari 11
及以上版本支持的代码。 -
edge16
:输出Edge 16
及以上版本支持的代码。 -
node10
:输出Node.js 10
及以上版本支持的代码。 -
node12
:输出Node.js 12
及以上版本支持的代码。 -
node14
:输出Node.js 14
及以上版本支持的代码。 -
需要注意的是,不同的构建目标会对代码进行不同的优化和转换,因此可能会影响构建的速度和输出的代码质量。通常情况下,我们应该根据项目的需要来选择合适的构建目标。
另外,如果我们需要输出兼容多个浏览器或环境的代码,可以使用
build.target
的数组形式来配置多个构建目标。
-
-
outDir
/assetsDir
配置打包文件名/静态资源文件名 -
sourcemap
配置是否开启源代码模式。sourcemap
是一种文件格式,它可以将编译后的代码映射回原始的源代码,以便于调试和排错。在开发过程中,我们通常会开启源代码映射文件,以便于在浏览器的开发者工具中调试代码。一般在开发环境中使用,具体在调试工具中的source中可以体现。它有以下三种值可选:true
:生成完整的源代码映射文件。false
:不生成源代码映射文件。inline
:生成内联的源代码映射文件。
-
minify
配置代码是否被压缩,一般在生产环境中使用。它的类型是两个布尔值,分别表示压缩代码和不压缩代码。默认生产环境下会压缩代码。 -
rollupOptions
配置Vite
默认打包器Rollup
的配置项,它里面的配置项和Rollup
有关。支持以下配置:input
:指定入口文件路径。output
:指定输出文件路径和格式。plugins
:指定Rollup
插件。external
:指定外部依赖。treeshake
:指定是否开启Tree Shaking
。(treeshake
选项用于开启或关闭Tree Shaking
,它是一种通过静态分析来删除未使用代码的优化技术。在开启 Tree Shaking 后,Vite
会分析代码中的依赖关系,并删除未使用的代码,从而减小生成的文件大小。需要注意的是,开启Tree Shaking
需要满足一些条件,如代码必须使用ES6
模块语法,不能使用CommonJS
或AMD
格式等)interop
:指定是否开启Interop
。(interop
选项用于控制模块之间的互操作性。在 Vite 中,模块之间的互操作性是通过ES Modules
和CommonJS
之间的转换来实现的。当一个模块使用CommonJS
格式导出时,Vite
会自动将其转换为ES Modules
格式,以便其他模块可以使用它。interop
选项可以控制这种转换的方式,它有以下三个可选值:auto
:自动转换,根据需要自动进行转换。esm
:强制将所有模块都视为ES Modules
格式,不进行转换。cjs
:强制将所有模块都视为CommonJS
格式,不进行转换。
cssCodeSplit
配置打包时是否将css
拆分为独立的文件。如果拆分,浏览器并行加载多个文件,会提高页面加载速度;如果不拆分,会减少请求的次数。cssInlineLimit
选项用于控制CSS
代码内联的阈值。当CSS
代码的大小小于这个阈值时,Vite 会将其内联到 HTML 中,否则会将其拆分为独立的文件。默认值为4096
,即4KB
。cssPreprocessOptions
选项用于配置CSS
预处理器的选项。Vite 支持多种CSS
预处理器,包括Sass
、Less
、Stylus
等。这个选项可以用来传递预处理器的选项,比如配置变量、函数等。
-
root
配置项目的根目录,默认为vite
命令执行的目录,目录路径是相对vite.config.ts
的。 -
server
配置开发服务器。以下有常用的配置:host
指定服务器的主机名port
指定服务器的端口号https
指定是否启用HTTPS
proxy
配置代理规则
-
optimizeDeps
配置模块的优化策略。这个配置项包含了三个子选项:include
、exclude
和entries
。include
:指定需要进行预构建的模块,可以是模块路径或者模块名称。exclude
:指定不需要进行预构建的模块,可以是模块路径或者模块名称。entries
:将某些模块标记为入口模块,以便优化器能够更好地对这些模块进行处理。(在这个配置项中的模块在项目启动时就会被预加载和执行,不包括在这里面的模块都默认按需加载的。注意:这个配置项只对ES
模块有效)
-
6. 插件机制
1. 插件种类
Vite 的插件可以分为以下几种:
Rollup
插件:Vite 的插件机制是基于Rollup
的插件机制实现的,因此可以使用Rollup
的大部分插件来扩展 Vite 的功能。- Vite 官方插件:Vite 官方提供了一些专门针对 Vite 的插件,例如
@vitejs/plugin-vue
、@vitejs/plugin-react
等,可以帮助我们更方便地开发Vue
、React
等应用。 - 自定义插件:我们也可以编写自己的插件来扩展 Vite 的功能。自定义插件需要实现
name
和apply
两个属性,其中name
是插件的名称,apply
是插件的逻辑。
需要注意的是,Vite 的插件机制是非常灵活的,我们可以根据自己的需求选择合适的插件来扩展 Vite 的功能。同时,Vite 还提供了一些针对开发环境的插件,例如
vite-plugin-style-import
、vite-plugin-mock
等,可以帮助我们更方便地进行开发和调试。
2. 自定义插件
Vite 的自定义插件需要实现 name
和 apply
两个属性,其中 name
是插件的名称,apply
是插件的逻辑。下面是一个自定义插件的示例:
// my-plugin.js
export default function myPlugin() {
return {
name: 'my-plugin',
transform(code, id) {
// 自定义插件的逻辑
return {
code,
map: null,
};
},
};
}
在上面的示例中,我们定义了一个名为 myPlugin
的自定义插件,它实现了 transform
方法,用于处理模块的代码。transform
方法接收两个参数:code
和 id
。其中,code
是模块的代码,id
是模块的路径。transform
方法需要返回一个包含 code
和 map
属性的对象,code
属性是处理后的代码,map
属性是代码的 sourcemap
。
接下来,我们需要将自定义插件添加到 Vite 的配置文件中。可以通过 plugins
配置项来添加自定义插件,如下所示:
// vite.config.js
import { defineConfig } from 'vite';
import myPlugin from './my-plugin';
export default defineConfig({
plugins: [
myPlugin(), // 使用自定义插件
],
});
在上面的示例中,我们通过 plugins
配置项将自定义插件 myPlugin
添加到了 Vite 的配置中。
需要注意的是,自定义插件的实现方式和逻辑都是由开发者自行决定的,可以根据实际需求来编写插件。同时,Vite 的插件机制是基于 Rollup
的插件机制实现的,因此可以使用 Rollup
的大部分插件来扩展 Vite 的功能。