vue-cli4打包优化(webapck优化)

一、去除生产环境sourceMap

sourceMap资源映射文件,存的是打包前后的代码位置,方便开发使用,这个占用相当一部分空间

module.exports = {
    
    
  // 根据你的实际情况更改这里
  publicPath,
  assetsDir: 'assets',
  lintOnSave: true,
  productionSourceMap: false,
}

二、对资源文件进行压缩

需要下载 compression-webpack-plugin

cnpm i compression-webpack-plugin -D
const CompressionWebpackPlugin = require('compression-webpack-plugin')

module.exports = {
    
    
  // 根据你的实际情况更改这里
  publicPath,
  assetsDir: 'assets',
  lintOnSave: true,
  configureWebpack: {
    
    
    plugins:[
      new CompressionWebpackPlugin({
    
    
        filename: '[path].gz[query]',
        algorithm: 'gzip',
        // test: /\.js$|\.html$|\.json$|\.css/,
        test: /\.js$|\.json$|\.css/,
        threshold: 10240, // 只有大小大于该值的资源会被处理
        minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
        // deleteOriginalAssets: true // 删除原文件
      })
    ],
  },
}

压缩后也会节省一部分空间,单后端要对nginx修改,配合前端

nginx配置示例:

location ~ .*\.(js|json|css)$ {
    
    
    gzip on;
    gzip_static on; # gzip_static是nginx对于静态文件的处理模块,该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。
    gzip_min_length 1k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types  text/css application/javascript application/json;
    root /dist;
}

nginx需要安装http_gzip_static_module以支持gzip_static

三、图片压缩

需要下载 image-webpack-loader

module.exports = {
    
    
  // 根据你的实际情况更改这里
  publicPath,
  assetsDir: 'assets',
  lintOnSave: true,
  // image
  config.module
    .rule('images')
    .use('image-webpack-loader')
    .loader('image-webpack-loader')
    .options({
    
    
      bypassOnDebug: true
    })
    .end()
}

四、去除console.log打印

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
new UglifyJsPlugin({
    
    
    uglifyOptions: {
    
    
        output: {
    
    
            comments: false, // 去掉注释
        },
        warnings: false,
        compress: {
    
    
            drop_console: true,
            drop_debugger: false,
            pure_funcs: ['console.log'] //移除console
        }
    }
})

五、只打包改变的文件

const {
    
     HashedModuleIdsPlugin } = require('webpack');
configureWebpack: config => {
    
        
    const plugins = [];
    plugins.push(
        new HashedModuleIdsPlugin()
    )
}

六、开启分析打包日志

安装cnpm i webpack-bundle-analyzer -D


chainWebpack: config => {
    
    
    config
        .plugin('webpack-bundle-analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
}

七、完整配置

vue.config.js完整配置

const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 去掉注释
const CompressionWebpackPlugin = require('compression-webpack-plugin'); // 开启压缩
const {
    
     HashedModuleIdsPlugin } = require('webpack');

function resolve(dir) {
    
    
    return path.join(__dirname, dir)
}

const isProduction = process.env.NODE_ENV === 'production';

// cdn预加载使用
const externals = {
    
    
    'vue': 'Vue',
    'vue-router': 'VueRouter',
    'vuex': 'Vuex',
    'axios': 'axios',
    "element-ui": "ELEMENT"
}

const cdn = {
    
    
    // 开发环境
    dev: {
    
    
        css: [
            'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
        ],
        js: []
    },
    // 生产环境
    build: {
    
    
        css: [
            'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
        ],
        js: [
            'https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js',
            'https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js',
            'https://cdn.jsdelivr.net/npm/[email protected]/dist/vuex.min.js',
            'https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js',
            'https://unpkg.com/element-ui/lib/index.js'
        ]
    }
}

module.exports = {
    
    

    lintOnSave: false, // 关闭eslint
    productionSourceMap: false,
    publicPath: './', 
    outputDir: process.env.outputDir, // 生成文件的目录名称
    chainWebpack: config => {
    
    

        config.resolve.alias
            .set('@', resolve('src'))

        // 压缩图片
        config.module
            .rule('images')
            .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({
    
     bypassOnDebug: true })

        // webpack 会默认给commonChunk打进chunk-vendors,所以需要对webpack的配置进行delete
        config.optimization.delete('splitChunks')

        config.plugin('html').tap(args => {
    
    
            if (process.env.NODE_ENV === 'production') {
    
    
                args[0].cdn = cdn.build
            }
            if (process.env.NODE_ENV === 'development') {
    
    
                args[0].cdn = cdn.dev
            }
            return args
        })

        config
            .plugin('webpack-bundle-analyzer')
            .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    },

    configureWebpack: config => {
    
    
        const plugins = [];

        if (isProduction) {
    
    
            plugins.push(
                new UglifyJsPlugin({
    
    
                    uglifyOptions: {
    
    
                        output: {
    
    
                            comments: false, // 去掉注释
                        },
                        warnings: false,
                        compress: {
    
    
                            drop_console: true,
                            drop_debugger: false,
                            pure_funcs: ['console.log']//移除console
                        }
                    }
                })
            )
            // 服务器也要相应开启gzip
            plugins.push(
                new CompressionWebpackPlugin({
    
    
                    algorithm: 'gzip',
                    test: /\.(js|css)$/,// 匹配文件名
                    threshold: 10000, // 对超过10k的数据压缩
                    deleteOriginalAssets: false, // 不删除源文件
                    minRatio: 0.8 // 压缩比
                })
            )

            // 用于根据模块的相对路径生成 hash 作为模块 id, 一般用于生产环境
            plugins.push(
                new HashedModuleIdsPlugin()
            )

            // 开启分离js
            config.optimization = {
    
    
                runtimeChunk: 'single',
                splitChunks: {
    
    
                    chunks: 'all',
                    maxInitialRequests: Infinity,
                    minSize: 1000 * 60,
                    cacheGroups: {
    
    
                        vendor: {
    
    
                            test: /[\\/]node_modules[\\/]/,
                            name(module) {
    
    
                                // 排除node_modules 然后吧 @ 替换为空 ,考虑到服务器的兼容
                                const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
                                return `npm.${
      
      packageName.replace('@', '')}`
                            }
                        }
                    }
                }
            };

            // 取消webpack警告的性能提示
            config.performance = {
    
    
                hints: 'warning',
                //入口起点的最大体积
                maxEntrypointSize: 1000 * 500,
                //生成文件的最大体积
                maxAssetSize: 1000 * 1000,
                //只给出 js 文件的性能提示
                assetFilter: function (assetFilename) {
    
    
                    return assetFilename.endsWith('.js');
                }
            }

            // 打包时npm包转CDN
            config.externals = externals;
        }

        return {
    
     plugins }
    },

    pluginOptions: {
    
    
        // 配置全局less
        'style-resources-loader': {
    
    
            preProcessor: 'less',
            patterns: [resolve('./src/style/theme.less')]
        }
    },
    devServer: {
    
    
        open: false, // 自动启动浏览器
        host: '0.0.0.0', // localhost
        port: 6060, // 端口号
        https: false,
        hotOnly: false, // 热更新
        proxy: {
    
    
            '^/sso': {
    
    
                target: process.env.VUE_APP_SSO, // 重写路径
                ws: true,   //开启WebSocket
                secure: false,      // 如果是https接口,需要配置这个参数
                changeOrigin: true
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43638968/article/details/109093199