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/vue@2.6.11/dist/vue.min.js', // '//cdn.jsdelivr.net/npm/vue-router@3.3.4/dist/vue-router.min.js', // '//cdn.jsdelivr.net/npm/vuex@3.4.0/dist/vuex.min.js', // '//cdn.jsdelivr.net/npm/axios@0.19.2/dist/axios.min.js', // '//cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js', // '//cdn.jsdelivr.net/npm/clipboard@2.0.6/dist/clipboard.min.js', // '//cdn.jsdelivr.net/npm/@antv/data-set@0.11.4/build/data-set.min.js', // '//cdn.jsdelivr.net/npm/js-cookie@2.2.1/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/vue@2.6.11/dist/vue.min.js', // '//cdn.jsdelivr.net/npm/vue-router@3.3.4/dist/vue-router.min.js', // '//cdn.jsdelivr.net/npm/vuex@3.4.0/dist/vuex.min.js', // '//cdn.jsdelivr.net/npm/axios@0.19.2/dist/axios.min.js', // '//cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js', // '//cdn.jsdelivr.net/npm/clipboard@2.0.6/dist/clipboard.min.js', // '//cdn.jsdelivr.net/npm/@antv/data-set@0.11.4/build/data-set.min.js', // '//cdn.jsdelivr.net/npm/js-cookie@2.2.1/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打包优化。
上一篇:Java爬虫爬取图片壁纸