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: { '/sgipad/duoduo-service/': { target: 'https://duoduoenv.sagacloud.cn', // target: 'http://192.168.0.47:52015', changeOrigin: true, pathRewrite: { '^/sgipad/duoduo-service': '/duoduo-service' } }, "/sgipad/pad_mtime": { target: 'http://39.106.8.246:9091/', changeOrigin: true, pathRewrite: { '^/sgipad/pad_mtime': '/pad_mtime' } }, '/sgipad/server/': { // target: 'https://duoduoenv.sagacloud.cn', target: 'http://sso.sagacloud.cn', changeOrigin: true, pathRewrite: { '^/sgipad/server': '/server' } }, '/sgipad/mngserver/': { // target: 'https://duoduoenv.sagacloud.cn', target: 'http://mng.sagacloud.cn', changeOrigin: true, pathRewrite: { '^/sgipad/mngserver': '/server' } }, '/sgipad/anon/': { // target: 'https://duoduoenv.sagacloud.cn', target: 'http://mng.sagacloud.cn', changeOrigin: true, pathRewrite: { '^/sgipad/anon': '/anon' } }, '/sgipad/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: { '^/sgipad/test': '' } }, '/sgipad/test1/': { // target: 'https://duoduoenv.sagacloud.cn', target: 'http://192.168.0.65:52009', changeOrigin: true, pathRewrite: { '^/sgipad/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 }) } }