webpack5+vue2下的打包优化

117 阅读3分钟

const { defineConfig } = require('@vue/cli-service'),
    isPro = process.env.NODE_ENV === 'production',
    publicPath = isPro ? './' : '/',
    path = require('path'),
    chalk = require('chalk'),
    webpack = require('webpack'),
    resolve = (dir) => path.join(__dirname, dir)
console.log('isPro', isPro);
// 插件
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin'), //压缩 CSS 文件。
    MiniCssExtractPlugin = require('mini-css-extract-plugin'), //插件将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。
    TerserWebpackPlugin = require('terser-webpack-plugin'), //来压缩 JavaScript。
    ProgressBarPlugin = require('progress-bar-webpack-plugin'), //进度条插件
    PurgeCSSPlugin = require('purgecss-webpack-plugin'), //对 CSS Tree Shaking。
    UglifyJsPlugin = require('uglifyjs-webpack-plugin') ,//去除console
     { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

let front = {
    entry: "src/frontPage/main.js",
    template: "public/frontPage.html",
}

module.exports = defineConfig({
    transpileDependencies: true,
    publicPath: "./",
    outputDir: "dist",
    assetsDir: "static",
    lintOnSave: false,
    productionSourceMap: false,
    pages: { index: front },
    devServer: {
        port: 9527,
        allowedHosts: "all",
        proxy: {
            '/api': {
                target: 'http://10.10.29.22:8080',
                changeOrigin: true,
                pathRewrite: {
                    '^/api': ''
                }
            },
        },
    },
    configureWebpack: {
        externals: {
            //   'echarts': 'echarts'
        },
    },
    css: {
        loaderOptions: {
            sass: {
                prependData: `@import "@/coreCommon/assets/style/index.scss";`,
            },
        },
    },
    filenameHashing: true,
    productionSourceMap: !isPro,
    chainWebpack: (config) => {
        const plugins = [new BundleAnalyzerPlugin()]
        // 修复HMR
        config.resolve.symlinks(true)
        if (isPro) {
            plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        output: {
                            comments: false, // 去掉注释
                        },
                        warnings: false,
                        compress: {
                            drop_console: true,
                            drop_debugger: false,
                            pure_funcs: ['console.log'], //移除console
                        },
                    },
                })
            )
       
        }
        // 如果使用多页面打包,使用vue inspect --plugins查看html是否在结果数组中
        // config.plugin('html').tap((args) => {
        //     // html中添加cdn
        //     args[0].cdn = cdn
        //     return args
        // })
    },
    // configureWebpack: {
    //     output: {
    //         pathinfo: false, //默认 webpack 会在输出的 bundle 中生成路径,将路径信息删除可小幅提升构建速度。
    //         // // 仅在生产环境添加 hash
    //         // filename: isPro
    //         //     ? '[name].[contenthash].bundle.js'
    //         //     : '[name].bundle.js',
    //     },
    //     resolve: {
    //         // 配置externals:防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖
    //         extensions: ['.css', '.js', '.vue', '.less', '.html','.scss'],
    //         // symlinks: false, //如果项目不使用 symlinks(例如  npm link  或者  yarn link),
    //         // alias: {
    //         //     '@': resolve('./src'),
    //         //     '@img': resolve('./src/assets/images'),
    //         //     '@modules': resolve('./src/modules'),
    //         // },
    //     },
    //     cache: {
    //         type: 'filesystem', // 不用缓存很是影响速度
    //     },
    //     optimization: {
    //         moduleIds: 'deterministic', //让公共包 splitChunks 的 hash 不因为新的依赖而改变,减少非必要的 hash 变动
    //         runtimeChunk: true, //为运行时代码创建一个额外的 chunk,减少 entry chunk 体积,提高性能。
    //         minimizer: [
    //             new TerserWebpackPlugin({
    //                 parallel: 4, //并发运行的默认数量
    //                 terserOptions: {
    //                     parse: {
    //                         ecma: 8,
    //                     },
    //                     compress: {
    //                         ecma: 5,
    //                         warnings: false,
    //                         comparisons: false,
    //                         inline: 2,
    //                     },
    //                     mangle: {
    //                         safari10: true,
    //                     },
    //                     output: {
    //                         ecma: 5,
    //                         comments: false,
    //                         ascii_only: true,
    //                     },
    //                 },
    //             }),
    //             // new CssMinimizerWebpackPlugin({
    //             //     parallel: 4, //并发运行的默认数量
    //             // }),
    //         ],
    //         splitChunks: {
    //             //项目中分别有a.js, b.js, page1.js, page2.js这四个JS文件, page1.js 和
    //             //page2.js中同时都引用了a.js, b.js, 这时候想把a.js, b.js抽离出来合并成一个公共的js,
    //             // 分割代码块
    //             cacheGroups: {
    //                 vendor: {
    //                     //第三方库抽离
    //                     name: 'vendor',
    //                     chunks: 'all',
    //                     test: /node_modules/,
    //                     minChunks: 1, //在分割之前,这个代码块最小应该被引用的次数
    //                     maxInitialRequests: 5,
    //                     minSize: 0, //大于0个字节
    //                     priority: 100, //权重
    //                 },
    //                 common: {
    //                     //公用模块抽离
    //                     name: 'common',
    //                     chunks: 'all',
    //                     test: /[\\/]src[\\/]js[\\/]/,
    //                     minChunks: 2, //在分割之前,这个代码块最小应该被引用的次数
    //                     maxInitialRequests: 5,
    //                     minSize: 0, //大于0个字节
    //                     priority: 60,
    //                 },
    //                 // styles: {
    //                 //     //样式抽离
    //                 //     name: 'styles',
    //                 //     test: /\.(sa|sc|le|c)ss$/,
    //                 //     chunks: 'all',
    //                 //     enforce: true,
    //                 // },
    //                 runtimeChunk: {
    //                     name: 'manifest',
    //                 },
    //             },
    //         },
    //     },
    //     plugins: [
    //         // 提取 CSS
    //         // new MiniCssExtractPlugin({
    //         //     filename: 'css/[contenthash]-[name].css',
    //         // }),
    //         // CSS Tree Shaking
    //         // new PurgeCSSPlugin({ //添加该插件会样式错乱
    //         //     paths: glob.sync(`./src/**/*`, { nodir: true }),
    //         // }),
    //         // 进度条
    //         new ProgressBarPlugin({
    //             format: `  :msg [:bar] ${chalk.green.bold(
    //                 ':percent'
    //             )} (:elapsed s)`,
    //         }),
    //         new webpack.ProvidePlugin({
    //             Vue: isPro ? 'lvm-base' : 'lvm-dev',
    //         }),
    //         // 处理<link rel="icon" href="<%= BASE_URL %>favicon.ico">
    //         new webpack.DefinePlugin({
    //             BASE_URL: '"./"',
    //         }),
    //     ],
    //     module: {
    //         rules: [
    //             {
    //                 // 字体文件等
    //                 test: /\.(woff|woff2|eot|ttf|otf)$/i,
    //                 // 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现。即:所有匹配的文件都将被发送到输出目录,并且其路径将被注入到 bundle 中。
    //                 type: 'asset/resource',
    //                 exclude: /node_modules/,
    //                 parser: {
    //                     dataUrlCondition: {
    //                         // 超过20kb以文件形式引入,反之以base64形式引入
    //                         maxSize: 1024 * 20,
    //                     },
    //                 },
    //                 generator: {
    //                     //自定义输出目录
    //                     publicPath,
    //                     // 文件路径
    //                     filename: 'fonts/[name]-[contenthash:6].[ext]',
    //                 },
    //             },
    //             {
    //                 // 图片的转化
    //                 test: /\.(jpe?g|png|gif|bmp|svg)$/i,
    //                 type: 'asset',
    //                 include: [resolve('src')],
    //                 parser: {
    //                     dataUrlCondition: {
    //                         //自动地在 resource 和 inline 之间进行选择:小于 8kb 的文件,将会视为 inline 模块类型,否则会被视为 resource 模块类型。
    //                         maxSize: 1024 * 15,
    //                     },
    //                 },
    //                 generator: {
    //                     publicPath,
    //                     filename: 'img/[name]-[contenthash:6].[ext]',
    //                 },
    //             },
    //         ],
    //     },
    // },
    // pluginOptions: {
    //     'style-resources-loader': {
    //         preProcessor: 'less',
    //         patterns: [resolve('./theme/default/var.less')],
    //     },
    // },
    // css: {
    //     sourceMap: false,
    //     // extract: true, //是否使用css分离插件
    //     // loaderOptions: { //向 CSS 相关的 loader 传递选项。例如:
    //     //   css: {
    //     //          这里的选项会传递给 css-loader
    //     //   },
    //     //   postcss: {
    //     //           这里的选项会传递给 postcss-loader
    //     //   }
    //     // },
    // },
});