You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
5.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
// WorkboxPlugin 用于生成Service Worker
const { InjectManifest } = require('workbox-webpack-plugin');
// 引入 path 模块
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
// 确保加载 .env 文件
dotenv.config();
// 定义CDN资源列表确保Service Worker也能访问
const cdnResources = {
css: [
'https://unpkg.com/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://unpkg.com/vue@2.6.14/dist/vue.min.js',
'https://unpkg.com/vue-router@3.6.5/dist/vue-router.min.js',
'https://unpkg.com/vuex@3.6.2/dist/vuex.min.js',
'https://unpkg.com/element-ui@2.15.14/lib/index.js',
'https://unpkg.com/axios@0.27.2/dist/axios.min.js',
'https://unpkg.com/opus-decoder@0.7.7/dist/opus-decoder.min.js'
]
};
// 判断是否使用CDN
const useCDN = process.env.VUE_APP_USE_CDN === 'true';
module.exports = defineConfig({
productionSourceMap: process.env.NODE_ENV !=='production', // 生产环境不生成 source map
devServer: {
port: 8001, // 指定端口为 8001
proxy: {
'/xiaozhi': {
target: 'http://127.0.0.1:8002',
changeOrigin: true
}
},
client: {
overlay: false, // 不显示 webpack 错误覆盖层
},
},
publicPath: process.env.VUE_APP_PUBLIC_PATH || "/",
chainWebpack: config => {
// 修改 HTML 插件配置,动态插入 CDN 链接
config.plugin('html')
.tap(args => {
// 根据配置决定是否使用CDN
if (process.env.NODE_ENV === 'production' && useCDN) {
args[0].cdn = cdnResources;
}
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
})
);
// 根据是否使用CDN来决定是否添加Service Worker
config.plugins.push(
new InjectManifest({
swSrc: path.resolve(__dirname, 'src/service-worker.js'),
swDest: 'service-worker.js',
exclude: [/\.map$/, /asset-manifest\.json$/],
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB
// 自定义Service Worker注入点
injectionPoint: 'self.__WB_MANIFEST',
// 添加额外信息传递给Service Worker
additionalManifestEntries: useCDN ?
[{ url: 'cdn-mode', revision: 'enabled' }] :
[{ url: 'cdn-mode', revision: 'disabled' }]
})
);
// 如果使用CDN则配置externals排除依赖包
if (useCDN) {
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'element-ui': 'ELEMENT',
'axios': 'axios',
'opus-decoder': 'OpusDecoder'
};
} else {
// 确保不使用CDN时不设置externals让webpack打包所有依赖
config.externals = {};
}
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] // 每次配置文件修改时缓存失效
}
};
}
},
// 将CDN资源信息暴露给service-worker.js
pwa: {
workboxOptions: {
skipWaiting: true,
clientsClaim: true
}
}
});