vue.config.js中打包相关配置

1.原始篇

let path = require('path');
const webpack = require('webpack');
const ThemeColorReplacer = require('webpack-theme-color-replacer');
const { getThemeColors, modifyVars } = require('./src/utils/themeUtil');
const { resolveCss } = require('./src/utils/theme-color-replacer-extend');
const CompressionWebpackPlugin = require('compression-webpack-plugin');

// const productionGzipExtensions = ['js', 'css'];
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
const isProd = process.env.NODE_ENV === 'production';

const assetsCDN = {
    // webpack build externals
    externals: {
        // vue: 'Vue',
        // 'vue-router': 'VueRouter',
        // vuex: 'Vuex',
        // axios: 'axios',
        // nprogress: 'NProgress',
        // clipboard: 'ClipboardJS',
        // '@antv/data-set': 'DataSet',
        // 'js-cookie': 'Cookies',
        // AMap: "window.AMap"
    },
    css: [
        // '//at.alicdn.com/t/font_2338481_gghb7xktb5.css'
    ],
    js: [
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/nprogress.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/clipboard.min.js',
        // '//cdn.jsdelivr.net/npm/@antv/[email protected]/build/data-set.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/src/js.cookie.min.js'
    ]
};

module.exports = {
    lintOnSave: false,
    devServer: {
        // host: "localhost",
        open: true,
        port: 8088,
        
        //配置几个跨域接口
        proxy: {
            '/v2/city/lookup': {
                target: 'https://geoapi.qweather.com', //请求城市定位区域接口地址
                changeOrigin: true, //是否跨域
                // pathRewrite: {
                //     '^/api': '' //路径重写
                // }
            },
            '/v7/weather/now': {
                target: 'https://devapi.qweather.com', //请求指定区域的接口
                changeOrigin: true,  //是否跨域
                // pathRewrite: {
                //     '^/api': '' //路径重写
                // }
            }
        }
    },
    pluginOptions: {
        'style-resources-loader': {
            preProcessor: 'less',
            patterns: [path.resolve(__dirname, "./src/theme/theme.less")],
        }
    },
    configureWebpack: config => {
        config.entry.app = ["babel-polyfill", "whatwg-fetch", "./src/main.js"];
        config.performance = {
            hints: false
        };
        config.plugins.push(
            new ThemeColorReplacer({
                fileName: 'css/theme-colors-[contenthash:8].css',
                matchColors: getThemeColors(),
                injectCss: true,
                resolveCss
            })
        );
        // Ignore all locale files of moment.js
        config.plugins.push(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/))
        // 生产环境下将资源压缩成gzip格式
        if (isProd) {
            // add `CompressionWebpack` plugin to webpack plugins
            config.plugins.push(new CompressionWebpackPlugin({
                algorithm: 'gzip',
                // test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
                test: productionGzipExtensions,
                threshold: 4096,
                minRatio: 0.8
            }))
        }
        // if prod, add externals
        if (isProd) {
            config.externals = assetsCDN.externals
        }
    },
    chainWebpack: config => {
        // 生产环境下关闭css压缩的 colormin 项,因为此项优化与主题色替换功能冲突 
        if (isProd) {
            config.plugin('optimize-css')
                .tap(args => {
                    args[0].cssnanoOptions.preset[1].colormin = false;
                    return args
                })
        }
        // 生产环境下使用CDN
        if (isProd) {
            config.plugin('html')
                .tap(args => {
                    args[0].cdn = assetsCDN;
                    return args
                })
        }
    },
    css: {
        loaderOptions: {
            less: {
                lessOptions: {
                    modifyVars: modifyVars(),
                    javascriptEnabled: true
                }
            }
        }
    },
    publicPath: './',
    outputDir: 'distM',
    assetsDir: '',
    productionSourceMap: false
};

2.改进篇

let path = require('path');
const webpack = require('webpack');
const ThemeColorReplacer = require('webpack-theme-color-replacer');
const { getThemeColors, modifyVars } = require('./src/utils/themeUtil');
const { resolveCss } = require('./src/utils/theme-color-replacer-extend');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// const productionGzipExtensions = ["js", "css"];
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
const isProd = process.env.NODE_ENV === 'production';

const assetsCDN = {
    // webpack build externals
    externals: {
        //不需要打包进来的资源
        // vue: 'Vue',
        // vuex: 'Vuex',
        // 'vue-router': 'VueRouter',
        // axios: 'axios',
        // nprogress: 'NProgress',
        // clipboard: 'ClipboardJS',
        // '@antv/data-set': 'DataSet',
        // 'js-cookie': 'Cookies',
        // AMap: "window.AMap"
    },
    css: [
        // '//at.alicdn.com/t/font_2338481_gghb7xktb5.css'
    ],
    js: [
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/nprogress.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/dist/clipboard.min.js',
        // '//cdn.jsdelivr.net/npm/@antv/[email protected]/build/data-set.min.js',
        // '//cdn.jsdelivr.net/npm/[email protected]/src/js.cookie.min.js'
    ]
};
let timeStamp = new Date().getTime();
module.exports = {
    publicPath: './',
    outputDir: 'distM',
    assetsDir: '',
    productionSourceMap: false, // 是否为生产环境构建生成 source map?
    lintOnSave: false, //是否开启eslint保存检测,有效值: true || false || 'error'
    devServer: {
        // host: "localhost",
        open: true,
        port: 8087,
        overlay: {
            errors: false,
            warnings: false
        },

        //配置几个跨域接口
        proxy: {
            '/v2/city/lookup': {
                target: 'https://geoapi.qweather.com', //请求城市定位区域接口地址
                changeOrigin: true, //是否跨域
                // pathRewrite: {
                //     '^/api': '' //路径重写
                // }
            },
            '/v7/weather/now': {
                target: 'https://devapi.qweather.com', //请求指定区域的接口
                changeOrigin: true,  //是否跨域
                // pathRewrite: {
                //     '^/api': '' //路径重写
                // }
            }
        }
    },
    pluginOptions: {
        'style-resources-loader': {
            preProcessor: 'less',
            patterns: [path.resolve(__dirname, "./src/theme/theme.less")]
        }
    },
    configureWebpack: config => {
        config.entry.app = ["babel-polyfill", "whatwg-fetch", "./src/main.js"];
        config.performance = {
            hints: false
        };
        config.plugins.push(
            new ThemeColorReplacer({
                fileName: 'css/theme-colors-[contenthash:8].css',
                matchColors: getThemeColors(),
                injectCss: true,
                resolveCss
            })
        );
        // 生产环境下将资源压缩成gzip格式
        if (isProd) {
            // add `CompressionWebpack` plugin to webpack plugins
            config.plugins.push(
                // Ignore all locale files of moment.js 2024-01-18
	            new webpack.IgnorePlugin(/^\.\/locale$/,/moment$/),
                new CompressionWebpackPlugin({
                    algorithm: 'gzip',
                    // test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
                    test: productionGzipExtensions,
                    threshold: 4096, //对4K以上的数据进行压缩
                    minRatio: 0.8,
                }),
                /**
                 * 新增限制 2024-01-18
                 * maxChunks:使用大于或等于 1 的值,来限制 chunk 的最大数量。使用 1 防止添加任何其他额外的 chunk,这是因为 entry/main chunk 也会包含在计数之中。
                 * minChunkSize: 设置 chunk 的最小大小。
                 * 限制打包的个数(减少打包生成的js文件和css文件)
                 */
                new webpack.optimize.LimitChunkCountPlugin({
                    maxChunks: 10,
                    minChunkSize: 100
                }),
            )
        }
        // if prod, add externals
        if (isProd) {
            config.externals = assetsCDN.externals
        }
    },
    chainWebpack: config => {
        if (isProd) {
            // 移除 prefetch 插件
            config.plugins.delete('prefetch');
            // 移除 preload 插件
            config.plugins.delete('preload');
            // 压缩代码
            config.optimization.minimize(true);
            // 分割代码
            config.optimization.splitChunks({
                chunks: 'all'
            });
            // 生产环境下关闭css压缩的 colormin 项,因为此项优化与主题色替换功能冲突 
            config.plugin('optimize-css')
                .tap(args => {
                    args[0].cssnanoOptions.preset[1].colormin = false;
                    return args
                })
            // 生产环境下使用CDN
            config.plugin('html')
                .tap(args => {
                    args[0].cdn = assetsCDN;
                    return args
                })
        }
    },
    css: {
        extract: { // 打包后css文件名称添加时间戳 2024-01-18
            filename: `css/[name].[hash:8].${timeStamp}.css`,
            chunkFilename: `css/chunk.[id].[hash:8].${timeStamp}.css`,
        },
        loaderOptions: {
            less: {
                lessOptions: {
                    modifyVars: modifyVars(),
                    javascriptEnabled: true
                }
            }
        }
    },
    // chunks: ['chunk-vendors', 'chunk-common']
};

通过对chunk生成的css和js文件数量和大小做限制,对代码进行压缩和分割,线上生产环境下使用cdn方式等对webpack打包优化。

你可能感兴趣的:(Vue2,javascript,vue.js,前端)