今天做一个小记录,是从别的网站上抄过来的内容,关于vite.config.js和vue.config.js的配置相关项。平常创建一个新项目时,总是因为config.js的配置项优化而发愁,今天无意间发现有关于特别全的配置,就将它抄到自己的笔记中。
import { defineConfig } from 'vite' // 帮手函数,这样不用 jsdoc 注解也可以获取类型提示
import vue from '@vitejs/plugin-vue'
const { resolve } = require('path')
import { viteMockServe } from "vite-plugin-mock"
const localEnabled = process.env.USE_MOCK || false;
const prodEnabled = process.env.USE_CHUNK_MOCK || false;
// https://vitejs.dev/config/
export default () => defineConfig({
plugins: [ //配置需要使用的插件列表
vue(),
viteMockServe({
mockPath: "./src/server/mock",
localEnabled: localEnabled, // 开发打包开关 true时打开mock false关闭mock
prodEnabled: prodEnabled,//prodEnabled, // 生产打包开关 // 这样可以控制关闭mock的时候不让mock打包到最终代码内
injectCode: `
import { setupProdMockServer } from './mockProdServer';
setupProdMockServer();
`,
logger: false, //是否在控制台显示请求日志
supportTs: false //打开后,可以读取 ts 文件模块 打开后将无法监视 .js 文件
})
], // 强制预构建插件包
optimizeDeps: { //检测需要预构建的依赖项
entries: [], //默认情况下,不在 node_modules 中的,链接的包不会预构建
include: ['axios'], exclude: ['your-package-name'] //排除在优化之外
}, //静态资源服务的文件夹
publicDir: "public",
base: './', //静态资源处理
assetsInclude: "", //控制台输出的级别 info 、warn、error、silent
logLevel: "info", // 设为false 可以避免 vite 清屏而错过在终端中打印某些关键信息
clearScreen: true,
resolve: {
alias: [//配置别名
{
find: '@',
replacement: resolve(__dirname, 'src')
}
], // 情景导出 package.json 配置中的exports字段
conditions: [], // 导入时想要省略的扩展名列表 // 不建议使用 .vue 影响IDE和类型支持
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
},
// css
css: { // 配置 css
// modules 的行为
modules: {},
// postCss 配置
postcss: {}, //指定传递给 css 预处理器的选项
preprocessorOptions: {
scss: {
additionalData: `$injectedColor:orange;`
}
}
},
json: { //是否支持从 .json 文件中进行按名导入
namedExports: true, //若设置为 true 导入的json会被转为 export default JSON.parse("..") 会比转译成对象字面量性能更好
stringify: false
},
//继承自 esbuild 转换选项,最常见的用例是自定义 JSX
esbuild: {
jsxFactory: "h",
jsxFragment: "Fragment",
jsxInject: `import Vue from 'vue'`
},
//本地运行配置,以及反向代理配置
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: { //浏览器兼容性 "esnext"|"modules"
target: "modules",
//指定输出路径
outDir: "dist",
//生成静态资源的存放路径
assetsDir: "assets",
//小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项
assetsInlineLimit: 4096,
//启用/禁用 CSS 代码拆分
cssCodeSplit: true,
//构建后是否生成 source map 文件
sourcemap: false,
//自定义底层的 Rollup 打包配置
rollupOptions: {},
//@rollup/plugin-commonjs 插件的选项
commonjsOptions: {},
//构建的库
lib: {},
//当设置为 true,构建后将会生成 manifest.json 文件
manifest: false,
// 设置为 false 可以禁用最小化混淆, // 或是用来指定使用哪种混淆器 // boolean | 'terser' | 'esbuild'
minify: "terser", //terser 构建后文件体积更小 //传递给 Terser 的更多 minify 选项。
terserOptions: {}, //设置为 false 来禁用将构建后的文件写入磁盘
write: true, //默认情况下,若 outDir 在 root 目录下,则 Vite 会在构建时清空该目录。
emptyOutDir: true,
//启用/禁用 brotli 压缩大小报告
brotliSize: true,
//chunk 大小警告的限制
chunkSizeWarningLimit: 500
},
ssr: { // 列出的是要为 SSR 强制外部化的依赖
external: [], //列出的是防止被 SSR 外部化依赖项
noExternal: []
}
})
const path = require('path');
const CompressionWebpackPlugin = require("compression-webpack-plugin"); // 开启gzip压缩, 按需引用
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i; // 开启gzip压缩, 按需写入
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; // 打包分析
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);
const resolve = (dir) => path.join(__dirname, dir);
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/site/vue-demo/' : '/', // 公共路径
indexPath: 'index.html', // 相对于打包路径index.html的路径
outputDir: process.env.outputDir || 'dist', // 'dist', 生产环境构建文件的目录
assetsDir: 'static', // 相对于outputDir的静态资源(js、css、img、fonts)目录
lintOnSave: false, // 是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码
runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本
productionSourceMap: !IS_PROD, // 生产环境的 source map
parallel: require("os").cpus().length > 1, // 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
pwa: {}, // 向 PWA 插件传递选项。
chainWebpack: config => {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
config.resolve.symlinks(true); // 修复热更新失效 // 如果使用多页面打包,使用vue inspect --plugins查看html是否在结果数组中
config.plugin("html").tap(args => { // 修复 Lazy loading routes Error
args[0].chunksSortMode = "none";
return args;
});
// 添加别名
config.resolve.alias
.set('@', resolve('src'))
.set('@assets', resolve('src/assets'))
.set('@components', resolve('src/components'))
.set('@views', resolve('src/views'))
.set('@store', resolve('src/store')); // 压缩图片
// 需要 npm i -D image-webpack-loader
config.module
.rule("images")
.use("image-webpack-loader")
.loader("image-webpack-loader")
.options({
mozjpeg: { progressive: true, quality: 65 },
optipng: { enabled: false },
pngquant: { quality: [0.65, 0.9], speed: 4 },
gifsicle: { interlaced: false },
webp: { quality: 75 }
}); // set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end() // 打包分析
// 打包之后自动生成一个名叫report.html文件(可忽视)
if (IS_PROD) {
config.plugin("webpack-report").use(BundleAnalyzerPlugin, [
{
analyzerMode: "static"
}
]);
}
config.when(process.env.NODE_ENV !== 'development', config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
vue: {
// 分离vue全家桶
name: true,
test: /[\\/]vue(.+?)[\\/]/,
priority: 5,
chunks: 'initial',
},
element: {
name: true,
test: /[\\/]element(.+?)[\\/]./,
priority: 5,
chunks: 'initial',
},
echarts: {
name: true,
test: /[\\/]echarts(.+?)[\\/]/,
priority: 5,
chunks: 'initial',
},
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single')
})
},
configureWebpack: config => { // 开启 gzip 压缩
// 需要 npm i -D compression-webpack-plugin
const plugins = [];
if (IS_PROD) {
plugins.push(
new CompressionWebpackPlugin({
filename: "[path].gz[query]",
algorithm: "gzip",
test: productionGzipExtensions,
threshold: 10240,
minRatio: 0.8
})
);
}
config.plugins = [...config.plugins, ...plugins];
},
css: {
extract: IS_PROD,
requireModuleExtension: false,// 去掉文件名中的 .module
loaderOptions: {
// 给 less-loader 传递 Less.js 相关选项
less: {
// `globalVars` 定义全局对象,可加入全局变量
globalVars: {
primary: '#333'
}
}
}
},
devServer: {
overlay: { // 让浏览器 overlay 同时显示警告和错误
warnings: true,
errors: true
},
host: "0.0.0.0",
port: 8080, // 端口号
https: false, // https:{type:Boolean}
open: false, //配置自动启动浏览器
hotOnly: true, // 热更新
// proxy: 'http://localhost:8080' // 配置跨域处理,只有一个代理
proxy: { //配置多个跨域
"/api": {
target: "",
changeOrigin: true, // ws: true,//websocket支持
secure: false,
pathRewrite: {
"^/api": "/"
}
},
"/api2": {
target: "",
changeOrigin: true, //ws: true,//websocket支持
secure: false,
pathRewrite: {
"^/api2": "/"
}
},
}
}
}