Vite 能够显著提升开发体验的关键特性之一就是其依赖预加载和预构建机制。
当我们使用 ES 模块导入依赖时,例如:
import Vue from 'vue';
import someModule from './some-module.js';
Vite 在构建过程中会对这些依赖进行预加载。对于非绝对路径(/
开头)或相对路径(./
或 ../
开头)的引用,Vite 会自动进行路径补全,使其能够正确解析。
Vite 通过以下方式处理路径:
node_modules
解析: 对于不带路径前缀的模块名(如 vue
),Vite 会自动在 node_modules
目录中查找。/node_modules/.vite/deps/vue.js?v=f3b2a9c1
。vite dev
): Vite 使用原生 ES 模块,按需编译,并动态预构建依赖。每次依赖更新后,Vite 会确保其相对路径的正确性,实现快速加载和热更新。vite build
): Vite 使用 Rollup 进行打包。Rollup 专注于生成优化的代码,将多个模块合并成更少的文件,减少 HTTP 请求次数和文件体积。预构建的依赖也会被 Rollup 打包到最终的构建产物中。Vite 在预构建依赖时,执行以下操作:
为什么需要 esbuild?
许多 npm 包仍然以 CommonJS 格式发布。由于 Vite 主要处理 ES 模块,因此需要使用 esbuild 将 CommonJS 模块转换为 ES 模块,以确保兼容性。
示例:
假设有以下模块:
// a.js
export default function a() {}
// b.js
export { default as a } from './a.js';
经过 Vite 处理后,可能会被转换为:
// .vite/deps/a.js
function a() {}
export { a as default };
// .vite/deps/b.js
import { a as __vite_default_export_0__ } from './a.js?v=someHash';
export { __vite_default_export_0__ as a };
通过这种方式,Vite 解决了以下问题:
.vite/deps
,便于管理和优化。Vite 的预加载和依赖预构建机制有效地提升了开发效率和构建性能。通过转换模块格式、合并文件、动态路径补全和缓存机制,Vite 大大减少了构建时间和网络传输开销,使开发者能够更专注于代码编写。
如上所述,esbuild 的主要作用是将 CommonJS 等非 ES 模块格式转换为 ES 模块,以兼容 Vite 的构建流程。
optimizeDeps
)可以通过 vite.config.js
中的 optimizeDeps
选项来配置依赖预构建行为:
import { defineConfig } from 'vite';
export default defineConfig({
optimizeDeps: {
exclude: ['some-package'], // 排除指定的依赖,不进行预构建
include: ['other-package'], // 强制包含指定的依赖,即使 Vite 没有检测到
},
});
exclude
:指定不需要预构建的依赖。例如,一些库可能已经提供了 ES 模块版本,或者与 esbuild 不兼容。include
:强制包含某些依赖进行预构建。这在某些情况下很有用,例如,当某个依赖没有被静态分析正确检测到时。@types/vite
来获得更好的语法提示。带类型提示的写法:
import { defineConfig } from 'vite';
export default defineConfig({
// 配置选项
});
Vite 提供了比 Webpack 更简洁的环境处理方式:
.env
文件来管理环境变量。
.env
:通用环境变量。.env.local
:本地开发环境变量(优先级高于 .env
)。.env.[mode]
:特定模式的环境变量,如 .env.production
、.env.development
。.env.[mode].local
:特定模式的本地环境变量(优先级最高)。Vite 会根据当前环境自动加载相应的 .env
文件。
vite.config.js
中根据 mode
参数进行条件配置:import { defineConfig } from 'vite';
export default defineConfig(({ mode }) => {
if (mode === 'production') {
return {
build: {
minify: 'esbuild', // 生产环境使用 esbuild 压缩
},
};
} else {
return {
server: {
port: 3000, // 开发环境使用 3000 端口
},
};
}
});
可以使用策略模式来更优雅地处理不同环境的配置:
import { defineConfig, UserConfigExport } from 'vite';
const baseConfig: UserConfigExport = {
// 基础配置
};
const devConfig: UserConfigExport = {
server: {
port: 3000,
},
};
const prodConfig: UserConfigExport = {
build: {
minify: 'esbuild',
},
};
const envResolver = {
build: () => ({ ...baseConfig, ...prodConfig }),
serve: () => ({ ...baseConfig, ...devConfig }),
};
export default defineConfig(({ command }) => {
return envResolver[command]();
});
这种方式避免了大量的 if...else
语句,使配置代码更加清晰和易于维护。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务