'use strict' const path = require('path') function resolve(dir) { return path.join(__dirname, dir) } const CompressionPlugin = require('compression-webpack-plugin') const name = process.env.VUE_APP_TITLE || '小智权限管理系统' // 网页标题 const port = process.env.port || process.env.npm_config_port || 80 // 端口 // vue.config.js 配置说明 //官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions // 这里只列一部分,具体配置参考文档 module.exports = { transpileDependencies: [ // 让 Babel 处理 quill 模块 'quill' ], // 部署生产环境和开发环境下的URL publicPath: process.env.NODE_ENV === "production" ? "/" : "/", // 在 npm run build 或 yarn build 时,生成文件的目录名称(要和baseUrl的生产环境路径一致,默认dist) outputDir: 'dist', // 用于放置生成的静态资源(js、css、img、fonts)的目录(项目打包之后,静态资源会放在这个文件夹下) assetsDir: 'static', lintOnSave: process.env.NODE_ENV === 'development', productionSourceMap: false, // webpack-dev-server 相关配置 devServer: { host: '0.0.0.0', port: port, open: true, // 安全修复:使用环境变量替代硬编码IP proxy: { [process.env.VUE_APP_BASE_API]: { target: process.env.VUE_APP_PROXY_TARGET || 'http://localhost:8090', changeOrigin: true, pathRewrite: { ['^' + process.env.VUE_APP_BASE_API]: '' } } }, allowedHosts: [ 'localhost', '127.0.0.1', '.local' // 允许 .local 域名 // 如需添加其他域名,请在此处添加 ] }, css: { loaderOptions: { sass: { sassOptions: { outputStyle: "expanded" } } } }, configureWebpack: { name: name, resolve: { alias: { '@': resolve('src') } }, plugins: [ // 使用 gzip 解压缩静态文件 new CompressionPlugin({ cache: false, // 不启用文件缓存 test: /\.(js|css|html)?$/i, // 压缩文件格式 filename: '[path].gz[query]', // 压缩后的文件名 algorithm: 'gzip', // 使用 gzip 压缩 minRatio: 0.8 // 压缩率小于 1 才会压缩 }) ], }, chainWebpack(config) { config.plugins.delete('preload') // 删除预加载插件 config.plugins.delete('prefetch') // 删除预获取插件 // 设置 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() // 安全修复:生产环境自动移除 console.log config.when(process.env.NODE_ENV === 'production', config => { // 移除 console 和 debugger config.optimization.minimizer('terser').tap(args => { Object.assign(args[0].terserOptions.compress, { drop_console: true, // 移除所有 console drop_debugger: true, // 移除 debugger pure_funcs: ['console.log'] // 移除 console.log }) return args }) config .plugin('ScriptExtHtmlWebpackPlugin') .after('html') .use('script-ext-html-webpack-plugin', [{ // runtime 必须与 runtimeChunk 名称相同,默认为 runtime inline: /runtime\..*\.js$/ }]) .end() config.optimization.splitChunks({ chunks: 'all', cacheGroups: { libs: { name: 'chunk-libs', test: /[\\/]node_modules[\\/]/, priority: 10, chunks: 'initial' // 仅打包初始依赖的第三方库 }, elementUI: { name: 'chunk-elementUI', // 将 elementUI 拆分成单独的包 test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // 为了适配 cnpm priority: 20 // 权重需要大于 libs 和 app,否则会被打包进 libs 或 app }, commons: { name: 'chunk-commons', test: resolve('src/components'), // 可以自定义规则 minChunks: 3, // 最小公共数量 priority: 5, reuseExistingChunk: true // 重用已存在的块 } } }) config.optimization.runtimeChunk('single') }) } }