const { resolve } = require("path"); const path = require("path"); const WebpackBar = require("webpackbar"); // const dayjs = require('dayjs') // const time = dayjs().format('YYYY-M-D HH:mm:ss') const merge = require("webpack-merge"); const tsImportPluginFactory = require("ts-import-plugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const productionGzipExtensions = ["js", "css", "svg"]; // process.env.VUE_APP_UPDATE_TIME = time const isProduction = process.env.NODE_ENV === "production"; const cdn = { css: ["https://cdn.jsdelivr.net/npm/vant@3/lib/index.css"], js: [ "https://unpkg.com/vue@3.2.31/dist/vue.global.js", "https://unpkg.com/vue-router@4.0.14/dist/vue-router.global.js", "https://unpkg.com/vuex@4.0.2/dist/vuex.global.js", "https://cdn.jsdelivr.net/npm/vant@3/lib/vant.min.js", "https://cdn.jsdelivr.net/npm/echarts@5.3.2/dist/echarts.min.js" ] }; const { publicPath, assetsDir, parallel, outputDir, lintOnSave, transpileDependencies, title, devPort } = require("./src/config/default/vue.custom.config"); const CompressionPlugin = require("compression-webpack-plugin"); module.exports = { publicPath, assetsDir, parallel, outputDir, lintOnSave, transpileDependencies, // css: { // loaderOptions: { // postcss: { // plugins: [ // require('postcss-px2rem-exclude')({ // 'remUnit':98, //设计稿是750,那么这里的设置就是填750/10=75 // 'propList': ['*', '!border','!border-left','!border-right'], // 'exclude': /node_modules|folder_name/i // 解决UI库px转rem问题 配置忽略node包 // }) // ] // } // }, // }, css: { loaderOptions: { postcss: { plugins: [ require("postcss-pxtorem")({ // 把px单位换算成rem单位 rootValue: 96, // vant官方使用的是37.5 minPixelValue: 4, unitPrecision: 3, selectorBlackList: ["mu"], // 忽略转换正则匹配项 propList: ["*"] }) ] } } }, devServer: { hot: true, port: devPort, open: true, noInfo: false, overlay: { warnings: true, errors: true }, proxy: { "/sgh5/duoduo-service/": { target: "https://duoduoenv.sagacloud.cn", // target: 'http://192.168.0.47:52015', changeOrigin: true, pathRewrite: { "^/sgh5/duoduo-service": "/duoduo-service" } }, "/sgh5/pad_mtime": { target: "http://39.106.8.246:9091/", changeOrigin: true, pathRewrite: { "^/sgh5/pad_mtime": "/pad_mtime" } }, "/sgh5/server/": { // target: 'https://duoduoenv.sagacloud.cn', target: "http://sso.sagacloud.cn", changeOrigin: true, pathRewrite: { "^/sgh5/server": "/server" } }, "/sgh5/mngserver/": { // target: 'https://duoduoenv.sagacloud.cn', target: "http://mng.sagacloud.cn", changeOrigin: true, pathRewrite: { "^/sgh5/mngserver": "/server" } }, "/sgh5/anon/": { // target: 'https://duoduoenv.sagacloud.cn', target: "http://mng.sagacloud.cn", changeOrigin: true, pathRewrite: { "^/sgh5/anon": "/anon" } }, "/sgh5/test/": { // target: 'https://duoduoenv.sagacloud.cn', target: "http://192.168.88.6:52009", // 永琪 // target: 'http://192.168.4.54:52009', // 小静 // target: 'http://192.168.16.168:52015', changeOrigin: true, pathRewrite: { "^/sgh5/test": "" } }, "/sgh5/test1/": { // target: 'https://duoduoenv.sagacloud.cn', target: "http://192.168.0.65:52009", changeOrigin: true, pathRewrite: { "^/sgh5/test1": "" } } // '/api': { // target: 'http://api.sagacloud.cn', // changeOrigin: true, // pathRewrite: { // '^/api': '' // } // }, // '/duoduo-service/': { // target: 'https://duoduoenv.sagacloud.cn', // changeOrigin: true, // pathRewrite: { // '^/duoduo-service': '/duoduo-service' // } // }, // '/server/': { // target: 'https://duoduoenv.sagacloud.cn', // changeOrigin: true, // pathRewrite: { // '^/server': '/server' // } // }, // '/object/': { // target: 'http://192.168.0.14:52010', // changeOrigin: true, // pathRewrite: { // '^/object': '/object' // } // }, // '/mapServer/': { // target: 'http://192.168.0.14:52015', // changeOrigin: true, // pathRewrite: { // '^/mapServer': '' // } // } } }, pluginOptions: { "style-resources-loader": { preProcessor: "scss", patterns: [ path.resolve(__dirname, "src/styles/_variables.scss"), path.resolve(__dirname, "src/styles/_mixins.scss") ] } }, configureWebpack() { return { resolve: { alias: { "@": resolve("src"), "*": resolve(""), Assets: resolve("src/assets") } }, module: { rules: [ { test: /\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files loader: "@intlify/vue-i18n-loader", include: [ // Use `Rule.include` to specify the files of locale messages to be pre-compiled path.resolve(__dirname, "src/lang") ] } ] }, plugins: isProduction ? [ new UglifyJsPlugin({ uglifyOptions: { compress: { drop_debugger: true, drop_console: true //生产环境自动删除console }, warnings: false }, sourceMap: false, parallel: true //使用多进程并行运行来提高构建速度。默认并发运行数:os.cpus().length - 1。 }), // 配置压缩 new CompressionPlugin({ test: new RegExp( "\\.(" + productionGzipExtensions.join("|") + ")$" ), threshold: 1024 * 10, // 30K minRatio: 0.8, algorithm: "gzip", // 使用gzip压缩 // test: /\.js$|\.css$/, // 匹配文件名 filename: "[path].gz[query]", // 压缩后的文件名(保持原文件名,后缀加.gz) deleteOriginalAssets: false }), new WebpackBar({ name: title }) ] : [ new WebpackBar({ name: title }) ] // externals: isProduction ? { // 'vue': 'Vue', // 'vuex': 'Vuex', // 'vant' : 'vant', // 'vue-router': 'VueRouter', // 'echarts': 'echarts' // } : {} }; }, chainWebpack: config => { config.plugins.delete("preload"); config.plugins.delete("prefetch"); config.optimization.minimizer("terser").tap(args => { args[0].parallel = 4; args[0].terserOptions.compress.warnings = true; args[0].terserOptions.compress.drop_debugger = true; args[0].terserOptions.compress.drop_console = true; return args; }); config.module .rule("ts") .use("ts-loader") .tap(options => { options = merge(options, { transpileOnly: true, getCustomTransformers: () => ({ before: [ tsImportPluginFactory({ libraryName: "vant", libraryDirectory: "es", style: true }) ] }), compilerOptions: { module: "es2015" } }); return options; }); } };