前言:
在浏览器支持 ES 模块之前,JavaScript 并没有提供原生机制让开发者以模块化的方式进行开发。这也正是我们对 "打包" 这个概念熟悉的原因:使用工具抓取、处理并将我们的源码模块串联成可以在浏览器中运行的文件。
打包构建工具演变:
webpack、Rollup 和 Parcel 等,然后到vite,它们极大地改善了前端开发者的开发体验。
需求衍生:
由于JavaScript 代码量也呈指数级增长,包含数千个模块的大型项目相当普遍。
启动开发服务器通常需要很长时间,有时候长达6/7分钟之久,即使使用模块热替换(HMR),文件修改后的效果也需要几秒钟才能在浏览器中刷新出来,极大影响开发体验,需要升级工具。
选择vite理由:
- 原生 ESM 开发服务器,Vite 还通过原生 ESM 导入提供了许多主要用于打包场景的增强功能。
- Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间,Vite 将会使用 esbuild 预构建依赖。esbuild 使用 Go 编写,并且比以 JavaScript (node.js)编写的打包器(webpack)预构建依赖快 10-100 倍。
- Vite 以 原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
- Vite利用 HTTP 头让浏览器进行文件请求时,启用协商缓存来缓存源码模块,而依赖模块请求则进行强缓存,因此一旦被缓存它们将不需要再次请求,大大提高加载速度。
- Vite 附带了一套构建优化的构建命令,开箱即用。
- 支持自定义后端集成。
- Vite 还提供了强大的扩展性,可通过其 插件 API 和 JavaScript API 进行扩展,并提供完整的类型支持。
配置 Vite:
当以命令行方式运行 vite 时,Vite 会自动解析项目根目录下名为 vite.config.js 的配置文件(也支持其他 JS 和 TS 扩展名)。
javascript
/**vite.config.js或vite.config.ts**/
//最基础的配置
export default {
// 配置选项
}
javascript
/**vite.config.js或vite.config.ts**/
//配置智能提示
/** @type {import('vite').UserConfig} */
//defineConfig工具函数,这样不用jsdoc注解也可以获取类型提示
import { defineConfig } from 'vite'
export default defineConfig({
// ...
})
/**
情景配置:
如果配置文件需要基于(dev/serve 或 build)命令或者不同的 模式 来决定选项,
亦或者是一个 SSR 构建(ssrBuild),则可以选择导出这样一个函数:
**/
export default defineConfig(({ command, mode, ssrBuild }) => {
if (command === 'serve') {
return {
// dev 独有配置
}
} else {
// command === 'build'
return {
// build 独有配置
}
}
})
/**
异步配置:
如果配置需要调用一个异步函数,也可以转而导出一个异步函数。
这个异步函数也可以通过 defineConfig 传递,以便获得更好的智能提示:
**/
export default defineConfig(async ({ command, mode }) => {
const data = await asyncFunction()
return {
// vite 配置
}
})
/**
在配置中使用环境变量:
环境变量通常可以从 process.env 获得。
注意 Vite 默认是不加载 .env 文件的,因为这些文件需要在执行完Vite配置后才能确定加载哪一个,
举个例子,root 和 envDir 选项会影响加载行为。
不过当你的确需要时,你可以使用 Vite 导出的 loadEnv 函数来加载指定的 .env 文件。
**/
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ command, mode }) => {
// 根据当前工作目录中的 `mode` 加载 .env 文件
// 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
const env = loadEnv(mode, process.cwd(), '')
return {
// vite 配置
define: {
__APP_ENV__: JSON.stringify(env.APP_ENV),
},
}
})
//共享配置及常用配置,不需要的可以不添加属性,将启用默认配置:
import { defineConfig } from 'vite'
import { viteMockServe } from 'vite-plugin-mock'
const localEnabled = process.env.USE_MOCK || false;
const prodEnabled = process.env.USE_CHUNK_MOCK || false;
export default defineConfig(({ command, mode }) => {
return {
root: process.cwd(), //默认process.cwd()。tips:项目根目录(index.html 文件所在的位置)。可以是一个绝对路径,或者一个相对于该配置文件本身的相对路径。
base: '/', //默认/。合法值:[1.绝对 URL 路径名,例如 /foo/,2.完整的 URL,例如 https://foo.com/,3.空字符串或 ./(用于嵌入形式的开发)]
mode: '', //'development' 用于开发,'production' 用于构建
define: 'XXX', //Record<string, any>定义全局常量替换方式,其中每项在开发环境下会被定义在全局,而在构建时被静态替换
//plugins: 需要用到的插件数组。Falsy 虚值的插件将被忽略,插件数组将被扁平化(flatten)
plugins: [
vue(), // vue原生插件
viteMockServe({ //引入mock插件配置,tips:mock,模拟真实数据以测试软件功能
mockPath: "./src/server/mock", //mock配置数据文件路径
localEnabled: localEnabled, // 开发打包开关 true时打开mock false关闭mock
prodEnabled: prodEnabled, //prodEnabled, // 生产打包开关
// 这样可以控制关闭mock的时候不让mock打包到最终代码内
injectCode: `
import { setupProdMockServer } from './mockProdServer';
setupProdMockServer();
`,
logger: false, // 是否在控制台显示请求日志
supportTs:false // 打开后,可以读取 ts 文件模块 打开后将无法监视 .js 文件
})
],
publicDir: 'public' //作为静态资源服务的文件夹,该值可以是文件系统的绝对路径,也可以是相对于项目根目录的相对路径,设定为 false 关闭此项功能
cacheDir: "node_modules/.vite", //默认:node_modules/.vite,存储缓存文件的目录,此目录下会存储预打包的依赖项或 vite 生成的某些缓存文件。此选项的值可以是文件的绝对路径,也可以是以项目根目录为基准的相对路径。当没有检测到 package.json 时,则默认为 .vite。
resolve: {
alias: [{ find: '@', replacement: resolve(__dirname, 'src') }],// 配置别名,
dedupe: '', // 如果你在你的应用程序中有相同依赖的副本(比如 monorepos),请使用此选项强制 Vite 始终将列出的依赖项解析为同一副本(从项目根目录)。
conditions: [], //情景导出 package.json 配置中的exports字段
mainFields: '', //默认['module', 'jsnext:main', 'jsnext'],如果一个入口点从 exports 成功解析,resolve.mainFields 将被忽略
browserField: ''//已废弃
extensions: [], //默认['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'],导入时想要省略的扩展名列表。注意,不 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会影响 IDE 和类型支持。
preserveSymlinks: false, //启用此选项会使 Vite 通过原始文件路径(即不跟随符号链接的路径)而不是真正的文件路径(即跟随符号链接后的路径)确定文件身份。
},
css: {
modules: '', // 配置 css modules 的行为
preprocessorOptions:{
scss: {
additionalData:`$injectedColor:orange;` //指定传递给 css 预处理器的选项
},
less: {
math: 'parens-division', //指定传递给 less 预处理器的选项
},
styl: { //指定传递给 styl/stylus 预处理器的选项
define: {
$specialColor: new stylus.nodes.RGBA(51, 197, 255, 1),
},
},
},
json: {
namedExports: true,//是否支持从 .json 文件中进行按名导入
stringify: false, //若设置为 true 导入的json会被转为 export default JSON.parse("..") 会比转译成对象字面量性能更好
},
//继承自 esbuild 转换选项,最常见的用例是自定义 JSX
esbuild: {
jsxFactory: "h",
jsxFragment: "Fragment",
jsxInject:`import Vue from 'vue'`
},
assetsInclude: ['**/*.gltf'], //静态资源处理
logLevel: 'info', //选项:'info' | 'warn' | 'error' | 'silent',调整控制台输出的级别,默认为 'info'
/**
自定义 logger 记录消息:
import { createLogger, defineConfig } from 'vite'
const logger = createLogger()
const loggerWarn = logger.warn
logger.warn = (msg, options) => {
// 忽略空 CSS 文件的警告
if (msg.includes('vite:css') && msg.includes(' is empty')) return
loggerWarn(msg, options)
}
**/
customLogger:logger,//自定义 logger 记录消息
clearScreen: true, //设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息。
envDir: 'root'//默认root, //用于加载 .env 文件的目录。可以是一个绝对路径,也可以是相对于项目根的路径。
envPrefix: 'VITE_',//默认VITE_,以 envPrefix 开头的环境变量会通过 import.meta.env 暴露在你的客户端源码中
appType: 'spa',//默认spa,选项['spa' | 'mpa' | 'custom'], tips: SPA-单页应用, MPA-多页应用,custom- SSR和自定义HTML处理的框架
//server:本地运行配置,以及反向代理配置
server: {
host: "localhost",
https: false,//是否启用 http 2
cors: true,//为开发服务器配置 CORS , 默认启用并允许任何源
open: true,//服务启动时自动在浏览器中打开应用
port: "9000",
strictPort: false, //设为true时端口被占用则直接退出,不会尝试下一个可用端口
force: true,//是否强制依赖预构建
hmr: false,//禁用或配置 HMR 连接
// 传递给 chockidar 的文件系统监视器选项
watch: {
ignored:["!**/node_modules/your-package-name/**"]
},
// 反向代理配置
proxy: {
'/api': {
target: "https://xxxx.com/",
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
//打包配置
build: {
target: "modules", //浏览器兼容性 "esnext"|"modules"
outDir: "dist", // 指定输出路径
assetsDir: "assets", // 生成静态资源的存放路径
assetsInlineLimit: 4096, // 小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项
cssCodeSplit: true, // 启用/禁用 CSS 代码拆分
sourcemap: false, // 构建后是否生成 source map 文件
rollupOptions: {}, // 自定义底层的 Rollup 打包配置
commonjsOptions: {}, // @rollup/plugin-commonjs 插件的选项
lib: {}, //构建的库
manifest: false, // 当设置为 true,构建后将会生成 manifest.json 文件,设置为 false 可以禁用最小化混淆,,或是用来指定使用哪种混淆器
minify: "terser", // boolean | 'terser' | 'esbuild',terser 构建后文件体积更小
terserOptions: {}, // 传递给 Terser 的更多 minify 选项。
write: true, // 设置为 false 来禁用将构建后的文件写入磁盘
emptyOutDir: true, // 默认情况下,若 outDir 在 root 目录下,则 Vite 会在构建时清空该目录。
brotliSize: true, // 启用/禁用 brotli 压缩大小报告
chunkSizeWarningLimit: 500 // chunk 大小警告的限制
ssr: {
// 列出的是要为 SSR 强制外部化的依赖,类型:string[]
external: [],
// 列出的是防止被 SSR 外部化依赖项。类型:string | RegExp | (string | RegExp)[] | true
noExternal: [
]
}
})