"use strict"; const { defineConfig } = require("@vue/cli-service"); const CompressionWebpackPlugin = require("compression-webpack-plugin"); const isProduction = process.env.NODE_ENV === "production"; const path = require("path"); const MomentLocalesPlugin = require("moment-locales-webpack-plugin"); function resolve(dir) { return path.join(__dirname, dir); } const HappyPack = require("happypack"); const os = require("os"); const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }); module.exports = defineConfig({ publicPath: "/", outputDir: "dist", assetsDir: "static", productionSourceMap: false, transpileDependencies: true, devServer: { host: "127.0.0.1", port: 9997, open: true, proxy: {} }, configureWebpack: (config) => { config.plugins.push( new MomentLocalesPlugin({ localesToKeep: ["zh-cn"] }) ); if (isProduction) { const productionGzipExtensions = ["html", "js", "css"]; config.plugins.push( new CompressionWebpackPlugin({ filename: "[path].gz[query]", algorithm: "gzip", test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"), threshold: 20480, // 只压缩大于 20KB 的文件 minRatio: 0.8, // 压缩率小于 0.8 的才处理 deleteOriginalAssets: false // 保留原文件 }) ); config.plugins.push( new HappyPack({ id: "happybabel", loaders: ["babel-loader"], threadPool: happyThreadPool }) ); // config.externals = { // vue: "Vue", // "vue-router": "VueRouter", // axios: "axios", // echarts: "echarts" // }; config.optimization = { usedExports: true, sideEffects: true, splitChunks: { chunks: "all", // 对所有 chunk 进行分割 minSize: 30000, // 模块大于 30KB 才会被分割 maxSize: 0, // 不限制最大大小 minChunks: 1, // 至少被引用 1 次 maxAsyncRequests: 5, // 最大异步请求数 maxInitialRequests: 3, // 最大初始请求数 automaticNameDelimiter: "~", // 文件名分隔符 cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, // 分离 node_modules 中的模块 priority: -10 }, default: { minChunks: 2, // 至少被引用 2 次的模块 priority: -20, reuseExistingChunk: true // 重用已有的 chunk } } } }; } }, chainWebpack(config) { config.module.rule("svg").exclude.add(resolve("src/assets/svg")).end(); config.module .rule("icons") .test(/\.svg$/) .include.add(resolve("src/assets/svg")) .end() .use("svg-sprite-loader") .loader("svg-sprite-loader") .options({ symbolId: "icon-[name]" }) .end(); config.module .rule("gltf-glb") .test(/\.(gltf|glb)$/) .use("file-loader") .loader("file-loader") .options({ name: "static/models/[name].[hash:8].[ext]", // 输出路径和文件名 esModule: false // 确保兼容传统导入方式 }) .end(); config.plugin("html").tap((args) => { args[0].title = "铁塔_web服务平台"; return args; }); config.resolve.alias.set("@", resolve("src")); } });