mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-22 15:13:55 +08:00
优化构建配置,提升构建效率和文件体积优化 1. 禁用生产环境的 source map:为了减少生产环境构建的文件体积,提高构建速度,生产环境下不再生成 source map。 2. 配置开发服务器代理:在 `devServer` 中配置了代理,解决了跨域问题,确保本地开发时可以顺利访问后端 API。 3. 动态插入 CDN 链接:在生产环境下,通过 `chainWebpack` 动态修改 HTML 插件配置,插入 CDN 链接,避免打包常用库(如 `vue`, `axios`, `element-ui` 等),从而减少打包体积。 4. 代码分割优化:优化了 `splitChunks` 配置,减少了小模块的分割,提升了构建效率和缓存利用率。增加了 `minSize` 和 `maxSize` 配置,避免过多的小模块被拆分。 5. 启用多线程压缩:在生产环境中,配置了 `TerserPlugin` 以启用并行压缩,减少了 JS 文件的压缩时间。 6. 启用 Gzip 压缩:通过 `CompressionPlugin` 配置了 Gzip 压缩,只压缩大于 20KB 的文件,减少了构建后的文件体积。 7. 配置 `externals`:通过 `externals` 排除了 `vue`, `vue-router`, `vuex`, `element-ui`, `axios`, `opus-decoder` 等库的打包,避免重复打包并通过 CDN 加载这些库。 8. 配置文件系统缓存:启用了 Webpack 文件系统缓存,加速了增量构建,缓存目录设置为 `.webpack_cache`,缓存有效期为一个月。 9. 配置 Webpack 别名:为项目中的路径配置了别名,简化了模块导入,减少了代码中的路径冗余。 10. 提供可选的打包分析:通过 `BundleAnalyzerPlugin` 插件,在 `ANALYZE=true` 环境变量下启用打包分析功能,帮助分析并优化构建后的文件。
144 lines
4.8 KiB
JavaScript
144 lines
4.8 KiB
JavaScript
const { defineConfig } = require('@vue/cli-service');
|
|
const dotenv = require('dotenv');
|
|
// TerserPlugin 用于压缩 JavaScript
|
|
const TerserPlugin = require('terser-webpack-plugin');
|
|
// CompressionPlugin 开启 Gzip 压缩
|
|
const CompressionPlugin = require('compression-webpack-plugin')
|
|
// BundleAnalyzerPlugin 用于分析打包后的文件
|
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
// 引入 path 模块
|
|
const path = require('path');
|
|
// 确保加载 .env 文件
|
|
dotenv.config();
|
|
module.exports = defineConfig({
|
|
productionSourceMap: process.env.NODE_ENV === 'production' ? false : true, // 生产环境不生成 source map
|
|
devServer: {
|
|
port: 8001, // 指定端口为 8001
|
|
proxy: {
|
|
'/xiaozhi-esp32-api': {
|
|
target: process.env.VUE_APP_API_BASE_URL, // 后端 API 的基础 URL
|
|
changeOrigin: true, // 允许跨域
|
|
pathRewrite: {
|
|
'^/xiaozhi-esp32-api': '/xiaozhi-esp32-api',
|
|
},
|
|
},
|
|
},
|
|
client: {
|
|
overlay: false, // 不显示 webpack 错误覆盖层
|
|
},
|
|
},
|
|
chainWebpack: config => {
|
|
|
|
// 修改 HTML 插件配置,动态插入 CDN 链接
|
|
config.plugin('html')
|
|
.tap(args => {
|
|
if (process.env.NODE_ENV === 'production') {
|
|
args[0].cdn = {
|
|
css: [
|
|
'https://cdn.jsdelivr.net/npm/element-ui@2.15.14/lib/theme-chalk/index.css',
|
|
'https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css'
|
|
],
|
|
js: [
|
|
'https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js',
|
|
'https://cdn.jsdelivr.net/npm/vue-router@3.6.5/dist/vue-router.min.js',
|
|
'https://cdn.jsdelivr.net/npm/vuex@3.6.2/dist/vuex.min.js',
|
|
'https://cdn.jsdelivr.net/npm/element-ui@2.15.14/lib/index.js',
|
|
'https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js',
|
|
'https://cdn.jsdelivr.net/npm/opus-decoder@0.7.7/dist/opus-decoder.min.js'
|
|
]
|
|
};
|
|
}
|
|
return args;
|
|
});
|
|
|
|
// 代码分割优化
|
|
config.optimization.splitChunks({
|
|
chunks: 'all',
|
|
minSize: 20000,
|
|
maxSize: 250000,
|
|
cacheGroups: {
|
|
vendors: {
|
|
name: 'chunk-vendors',
|
|
test: /[\\/]node_modules[\\/]/,
|
|
priority: -10,
|
|
chunks: 'initial',
|
|
},
|
|
common: {
|
|
name: 'chunk-common',
|
|
minChunks: 2,
|
|
priority: -20,
|
|
chunks: 'initial',
|
|
reuseExistingChunk: true,
|
|
},
|
|
}
|
|
});
|
|
|
|
// 启用优化设置
|
|
config.optimization.usedExports(true);
|
|
config.optimization.concatenateModules(true);
|
|
config.optimization.minimize(true);
|
|
},
|
|
configureWebpack: config => {
|
|
if (process.env.NODE_ENV === 'production') {
|
|
// 开启多线程编译
|
|
config.optimization = {
|
|
minimize: true,
|
|
minimizer: [
|
|
new TerserPlugin({
|
|
parallel: true,
|
|
terserOptions: {
|
|
compress: {
|
|
drop_console: true,
|
|
drop_debugger: true,
|
|
pure_funcs: ['console.log']
|
|
}
|
|
}
|
|
})
|
|
]
|
|
};
|
|
config.plugins.push(
|
|
new CompressionPlugin({
|
|
algorithm: 'gzip',
|
|
test: /\.(js|css|html|svg)$/,
|
|
threshold: 20480,
|
|
minRatio: 0.8
|
|
})
|
|
);
|
|
config.externals = {
|
|
'vue': 'Vue',
|
|
'vue-router': 'VueRouter',
|
|
'vuex': 'Vuex',
|
|
'element-ui': 'ELEMENT',
|
|
'axios': 'axios',
|
|
'opus-decoder': 'OpusDecoder'
|
|
};
|
|
if (process.env.ANALYZE === 'true') { // 通过环境变量控制
|
|
config.plugins.push(
|
|
new BundleAnalyzerPlugin({
|
|
analyzerMode: 'server', // 开启本地服务器模式
|
|
openAnalyzer: true, // 自动打开浏览器
|
|
analyzerPort: 8888 // 指定端口号
|
|
})
|
|
);
|
|
}
|
|
config.cache = {
|
|
type: 'filesystem', // 使用文件系统缓存
|
|
cacheDirectory: path.resolve(__dirname, '.webpack_cache'), // 自定义缓存目录
|
|
allowCollectingMemory: true, // 启用内存收集
|
|
compression: 'gzip', // 启用gzip压缩缓存
|
|
maxAge: 5184000000, // 缓存有效期为 1个月
|
|
buildDependencies: {
|
|
config: [__filename] // 每次配置文件修改时缓存失效
|
|
}
|
|
};
|
|
config.resolve.alias = {
|
|
'@': path.resolve(__dirname, 'src'), // 让 '@' 代表 'src' 目录
|
|
'@assets': path.resolve(__dirname, 'src/assets'), // 设置 '@assets' 为 'src/assets' 目录
|
|
'@components': path.resolve(__dirname, 'src/components'), // 设置 '@components' 为 'src/components' 目录
|
|
'@views': path.resolve(__dirname, 'src/views'), // 设置 '@views' 为 'src/views' 目录
|
|
}
|
|
}
|
|
},
|
|
|
|
});
|