webpack + vite 打包优化

webpack 优化

1、依赖转化,兼容低版本浏览器

// 对依赖进行转换
transpileDependencies: true,

2、生产环境关闭sourceMap

// 生产关闭sourceMap
productionSourceMap: false,

3、打包输出目录名称修改和静态资源的存放

outputDir: 'bundle', // 打包后文件的目录 (默认为dist)
assetsDir: 'static', //  outputDir的静态资源(js、css、img、fonts)目录  默认为‘’没有单独目录js/css/img在根目录中。

/*
下面这两个资源是配合使用的(要是 publicPath 是 "./" , 那么indexPath 是 'index.html' 就可以了)
要是 publicPath 是 '../' ,那么 indexPath 是 'templates/index.html'
*/
// 例如
publicPath: "./",          // 打包之后的html中引入js、 css的相对路径 例如 <link href='./static/css/xxx.css' />
indexPath: 'index.html',   // 生成的 index.html 文件
// 或者
publicPath: "../",         // 打包之后的html中引入js、 css的相对路径 例如 <link href='../static/css/xxx.css' />
indexPath: 'templates/index.html',     // 生成的 templates/index.html 文件

4、修改图标

// 修改浏览器的icon图标,不加下面的,修改浏览器图标不生效
pwa: {
    iconPaths: {
        favicon32: 'favicon.ico',
        favicon16: 'favicon.ico',
        appleTouchIcon: 'favicon.ico',
        maskIcon: 'favicon.ico',
        msTileImage: 'favicon.ico',
    }
}

5、修改webpack配置

5-1、写在此处的配置可以覆盖掉脚手架本来就预设上有的配置 (chainWebpack 本身有的配置)
pnpm i compression-webpack-plugin

chainWebpack: config => {
    config.optimization.minimizer('terser').tap(args => {

        // 删除代码中的注释和打印,减少一点代码体积
        args.forEach(item => {
            if (item.hasOwnProperty('terserOptions')) {
                Object.assign(item['terserOptions'].compress, {
                    drop_debugger: true,
                    drop_console: true,
                    pure_funcs: ['console.log']
                })
            }
            item['terserOptions']['format'] = {
                comments: false
            }
        })
        return args
    })


    // 开启 gzip 压缩
    if (process.env.NODE_ENV === "production") {
        const CompressionWebpackPlugin = require("compression-webpack-plugin")
        config.plugin('CompressionPlugin').use(
            new CompressionWebpackPlugin({
                test: /\.(js|css|less|scss|html)$/,   // 将 css、scss、less、html 进行压缩
                threshold: 10240, // 超过10kb的文件就压缩
                deleteOriginalAssets: false, // 不删除源文件
                minRatio: 0.8,   // 最小压缩率 0.8
                algorithm: 'gzip'
            })
        )
    }
}

5-2、代码分割以外还可以利用 webpack 的 externals 将第三方的比较大的包拆出来使用 cdn 的方式引入
5-3、写在此处的都是预设没有配置的,脚手架本来就有的配置是不会覆盖的
// configureWebpack表示脚手架 vue-cli 本来没有的 webpack 的一些配置
configureWebpack: {
   // 代码分割
   optimization: {
       splitChunks: {
           chunks: "all",

           // 定义一个cache组,将第三方的包抽离出来
           cacheGroups: {
               elementUI: {
                   // 抽离出来的名字
                   name: "element-chunk-vendors",
                   // 在node_modules包里面找
                   test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
                   // 权重,越大优先打包
                   priority: 30,
               },
               vue: {
                   name: "vue-chunk-vendors",
                   test: /[\\/]node_modules[\\/]vue(.*)[\\/]/,
                   chunks: "initial",
                   priority: 20,
                   reuseExistingChunk: true,
               },
               vueRouter: {
                   name: "vueRouter-chunk-vendors",
                   test: /[\\/]node_modules[\\/]vue-router(.*)[\\/]/,
                   chunks: "initial",
                   priority: 19,
               },
               vuex: {
                   name: "vuex-chunk-vendors",
                   test: /[\\/]node_modules[\\/]vuex(.*)[\\/]/,
                   chunks: "initial",
                   priority: 18,
               },
               echarts: {
                   name: "echarts-chunk-vendors",
                   test: /[\\/]node_modules[\\/]echarts(.*)[\\/]/,
                   chunks: "initial",
                   priority: 17,
               },
               // 剩下的别忘记单独抽离
               libs: {
                   name: "chunk-libs-vendors",
                   test: /[\\/]node_modules[\\/]/,
                   priority: 1, // 权重最低,优先考虑前面内容
                   chunks: "initial",
               },

               // 针对自己写的代码,重复使用的满足下面的配置就会抽离出来单独打包,比如 utils 下面的包
               default: {
                   // 其他没有写的配置会使用上面的默认值
                   test: /[\\/]src(.*)[\\/]/,
                   name: "common-chunk",
                   minSize: 20000, // 超过 20kb,就会拆包
                   minChunks: 2,  // 引用两次就会拆包
                   priority: -10,
                   reuseExistingChunk: true
               }
           }
       }
   },

   // 配置别名
   resolve: {
       alias: {
           "#": path.resolve(__dirname, "src")
       }
   },

	// 分析插件
   plugins: [
       new BundleAnalyzer({
           analyzerMode: 'server',
           analyzerHost: '127.0.0.1',
           analyzerPort: 8088,
           reportFilename: 'report.html',
           defaultSizes: 'parsed',
           openAnalyzer: true,
           generateStatsFile: false,
           statsFilename: 'state.json',
           statsOptions: null,
           logLevel: 'info'
       })
   ]
}

6、完整配置

const path = require("path")
const { defineConfig } = require('@vue/cli-service')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = defineConfig({
    // 对依赖进行转换
    transpileDependencies: true,

    // 生产关闭sourceMap
    productionSourceMap: false,

    outputDir: 'bundle', // 打包后文件的目录 (默认为dist)
    assetsDir: 'static', //  outputDir的静态资源(js、css、img、fonts)目录  默认为‘’没有单独目录js/css/img在根目录中。

    // 修改浏览器的icon图标
    pwa: {
        iconPaths: {
            favicon32: 'favicon.ico',
            favicon16: 'favicon.ico',
            appleTouchIcon: 'favicon.ico',
            maskIcon: 'favicon.ico',
            msTileImage: 'favicon.ico',
        }
    },


    // webpack 配置(写在此处的配置可以覆盖掉脚手架本来就预设上有的配置)
    chainWebpack: config => {
        config.optimization.minimizer('terser').tap(args => {

            // 删除代码中的注释和打印,减少一点代码体积
            args.forEach(item => {
                if (item.hasOwnProperty('terserOptions')) {
                    Object.assign(item['terserOptions'].compress, {
                        drop_debugger: true,
                        drop_console: true,
                        pure_funcs: ['console.log']
                    })
                }
                item['terserOptions']['format'] = {
                    comments: false
                }
            })
            return args
        })


        // 开启 gzip 压缩,对应的 nginx 也需要配置
        if (process.env.NODE_ENV === "production") {
            config.plugin('CompressionPlugin').use(
                new CompressionWebpackPlugin({
                    test: /\.(js|css|less|scss|html)$/,   // 将 css、scss、less、html 进行压缩
                    threshold: 10240, // 超过10kb的文件就压缩
                    deleteOriginalAssets: false, // 不删除源文件
                    minRatio: 0.8,   // 最小压缩率 0.8
                    algorithm: 'gzip'
                })
            )
        }
    },

    // webpack 配置(写在此处的都是预设没有配置的,脚手架本来就有的配置是不会覆盖的)
    configureWebpack: {
        // 代码分割
        optimization: {
            splitChunks: {
                chunks: "all",

                // 定义一个cache组,将第三方的包抽离出来
                cacheGroups: {
                    elementUI: {
                        // 抽离出来的名字
                        name: "element-chunk-vendors",
                        // 在node_modules包里面找
                        test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
                        // 权重,越大优先打包
                        priority: 30,
                    },
                    vue: {
                        name: "vue-chunk-vendors",
                        test: /[\\/]node_modules[\\/]vue(.*)[\\/]/,
                        chunks: "initial",
                        priority: 20,
                        reuseExistingChunk: true,
                    },
                    vueRouter: {
                        name: "vueRouter-chunk-vendors",
                        test: /[\\/]node_modules[\\/]vue-router(.*)[\\/]/,
                        chunks: "initial",
                        priority: 19,
                    },
                    vuex: {
                        name: "vuex-chunk-vendors",
                        test: /[\\/]node_modules[\\/]vuex(.*)[\\/]/,
                        chunks: "initial",
                        priority: 18,
                    },
                    echarts: {
                        name: "echarts-chunk-vendors",
                        test: /[\\/]node_modules[\\/]echarts(.*)[\\/]/,
                        chunks: "initial",
                        priority: 17,
                    },
                    // 剩下的别忘记单独抽离
                    libs: {
                        name: "chunk-libs-vendors",
                        test: /[\\/]node_modules[\\/]/,
                        priority: 1, // 权重最低,优先考虑前面内容
                        chunks: "initial",
                    },

                    // 针对自己写的代码,重复使用的满足下面的配置就会抽离出来单独打包,比如 utils 下面的包
                    default: {
                        // 其他没有写的配置会使用上面的默认值
                        test: /[\\/]src(.*)[\\/]/,
                        name: "common-chunk",
                        minSize: 20000, // 超过 20kb,就会拆包
                        minChunks: 2,  // 引用两次就会拆包
                        priority: -10,
                        reuseExistingChunk: true
                    }
                }
            }
        },

        // 配置别名
        resolve: {
            alias: {
                "#": path.resolve(__dirname, "src")
            }
        },


        plugins: [
            new BundleAnalyzer({
                analyzerMode: 'server',
                analyzerHost: '127.0.0.1',
                analyzerPort: 8088,
                reportFilename: 'report.html',
                defaultSizes: 'parsed',
                openAnalyzer: true,
                generateStatsFile: false,
                statsFilename: 'state.json',
                statsOptions: null,
                logLevel: 'info'
            })
        ]
    }
})

// 打包分析工具加了之后 启动需要加上:
 "build": "vue-cli-service build",
 "build:analyze": "cross-env NODE_ENV=production npm_config_report=true vue-cli-service build"

https://juejin.cn/post/6951297954770583565

vite 优化

pnpm i unplugin-auto-import unplugin-vue-components vite-plugin-compression -D


import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import viteCompression from "vite-plugin-compression";


// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        vue(),

        Components({//自定义的模块
            dirs: ['src/components'],
            extensions: ['vue', 'ts'],
            resolvers: [ElementPlusResolver()]
        }),
        AutoImport({ // 插件进行自动导入相关的依赖库
            //安装两行后你会发现在组件中不用再导入ref,reactive等
            imports: ['vue', 'vue-router'],
            // 可选,用于自动导入组件类型
            dts: 'src/components.d.ts'
        }),

        // 开启gzip压缩
        viteCompression({
            verbose: true,
            disable: false,
            threshold: 10240,
            algorithm: 'gzip',
            ext: '.gz',
        })
    ],

    // 打包
    build: {
        // 打包删除 console 和 debugger 
        terserOptions: {
            compress: {
                drop_console: true,
                drop_debugger: true
            }
        },

        rollupOptions: {
            output: {  //静态资源分类打包
                chunkFileNames: 'static/js/[name]-[hash].js',
                entryFileNames: 'static/js/[name]-[hash].js',
                assetFileNames: 'static/[ext]/[name]-[hash].[ext]',

                 manualChunks: {  // 相当于webpack中的 codeSplit
                    common: ["vue"],
                    elementPluse: ["element-plus"],
                    vueRouter: ["vue-router"],
                    pinia: ["pinia"],
                    echarts: ["echarts"],
                }

            }

        }
    }
});

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值