如何减少 WEBPACK + VUEJS 中的包大小 [英] How to reduce bundle size in WEBPACK + VUEJS

查看:35
本文介绍了如何减少 WEBPACK + VUEJS 中的包大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了很多关于如何减小包大小的教程,但没有对包大小产生任何影响,我不知道为什么.

I followed a lot of tutorials on how to reduce the bundle size, but nothing took any effect on the bundle size and I don't know why.

每次我向 webpack 添加一些新代码时,我的包大小都保持不变.

Every time when I add some new code to webpack, my bundle size stays the same as before.

(我的应用是使用 vue cli 3 pwa 插件、webpack...等构建的)

(My app is built with vue cli 3 pwa plugin, webpack... and so on)

如果我运行 npm run build,我会得到这个输出:

If I run npm run build, I'm getting this output:

webpack.config.js:

    const path = require('path');
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    const OfflinePlugin = require('offline-plugin');
    const webpack = require('webpack');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const WebpackChunkHash = require('webpack-chunk-hash');
    const CompressionPlugin = require('compression-webpack-plugin');

    if (process.env.NODE_ENV === 'production') {
        module.exports.plugins = (module.exports.plugins || []).concat([
            // or use push because it's faster
            new webpack.DefinePlugin({
                'process.env': {
                    'process.env.NODE_ENV': '"production"',
                },
            }),
            new webpack.optimize.UglifyJsPlugin({
                mangle: true,
                compress: {
                    warnings: false, // Suppress uglification warnings
                    pure_getters: true,
                    unsafe: true,
                    unsafe_comps: true,
                    screw_ie8: true,
                },
                output: {
                    comments: false,
                },
                exclude: [/\.min\.js$/gi], // skip pre-minified libs
            }),
            new webpack.HashedModuleIdsPlugin(),
            new WebpackChunkHash(),
            new CompressionPlugin({
                asset: '[path].gz[query]',
                algorithm: 'gzip',
                test: /\.js$|\.css$|\.html$/,
                threshold: 10240,
                minRatio: 0,
            }),
        ]);
    }

    const config = (module.exports = {
        mode: 'production',
        devtool: '', // Removed dev-tools mapping
        entry: [
            './src/app.js',
            {
                vendor: ['offline-plugin/runtime'],
            },
        ],
        output: {
            filename: '[name].bundle.js',
            path: path.resolve(__dirname, 'build/client'),
            publicPath: 'build/client',
        },
        resolve: {
            extensions: ['.js', '.vue', '.json'],
            alias: {
                vue$: 'vue/dist/vue.esm.js', // Use the full build
            },
        },
        module: {
            rules: [
                {
                    test: /\.vue$/,
                    use: 'vue-loader',
                },
                {
                    test: /\.css$/,
                    use: [
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                                // you can specify a publicPath here
                                // by default it use publicPath in webpackOptions.output
                                publicPath: '../',
                            },
                        },
                        'vue-loader',
                    ],
                },
            ],
        },
        optimization: {
            runtimeChunk: {
                name: 'runtime',
            },
            splitChunks: {
                chunks: 'all',
                maxInitialRequests: Infinity,
                minSize: 0,
                cacheGroups: {
                    vendor: {
                        test: /[\\/]node_modules[\\/]/,
                        name(module) {
                            // get the name. E.g. node_modules/packageName/not/this/part.js
                            // or node_modules/packageName
                            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];

                            // npm package names are URL-safe, but some servers don't like @ symbols
                            return `npm.${packageName.replace('@', '')}`;
                        },
                    },
                },
            },
        },
        plugins: [
            new webpack.ContextReplacementPlugin(/moment[\\/]locale$/, /^\.\/(en|zh-tw)$/),
            new webpack.optimize.ModuleConcatenationPlugin(),
            new BundleAnalyzerPlugin(),
            new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]),
            new OfflinePlugin({
                AppCache: false,
                // important for working 200 respons => index.html ./
                externals: ['./'],
                ServiceWorker: {
                    events: true,
                },
            }),
            new webpack.optimize.CommonsChunkPlugin({
                name: 'vendor',
                minChunks: function(module) {
                    return module.context && module.context.indexOf('node_modules') !== -1;
                },
            }),
            new MiniCssExtractPlugin({
                // Options similar to the same options in webpackOptions.output
                // both options are optional
                filename: '[name].css',
                chunkFilename: '[id].css',
            }),
        ],
        });

        if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 
          'test') 
         {
          config.plugins = [...config.plugins, new BundleAnalyzerPlugin()];
         }

推荐答案

来自 webpack 团队的 Sean.有几件事我会推荐.

Sean from the webpack team. There's a couple of things I would recommend.

  1. 升级到 webpack 4(我可以告诉你是 3,因为你使用的是 CommonsChunkPlugin()).webpack 4 附带了大量的大小和构建时间性能.新的 vue-cli 默认使用它.

  1. Upgrade to webpack 4 (I can tell you are on 3 because you are using CommonsChunkPlugin()). webpack 4 shipped with a massive amount of size and build time performances. The new vue-cli uses it by default.

代码拆分您的路线和组件.代码拆分使您可以延迟加载 JavaScript,直到以后需要它为止.这种技术减少了将要创建的初始包中的代码量.这是我对此的演讲:与 Sean Thomas Larkin 一起使用 Vue 进行代码拆分模式.

Code Split your routes, and components. Code-splitting lets you lazy load JavaScript until it is needed at a later time. This technique reduces the amount of code in the initial bundles that would be created. Here's a talk I gave about this: Code Splitting Patterns with Vue with Sean Thomas Larkin.

与使用代码拆分相比,尝试使用 webpack 配置永远不会获得真正的加载时性能!!!

Trying to play around with the webpack configuration is never going to get you real load-time performance compared to using code-splitting!!!

这篇关于如何减少 WEBPACK + VUEJS 中的包大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆