【问题标题】:Webpack Build Speed performanceWebpack 构建速度性能
【发布时间】:2019-08-22 13:49:12
【问题描述】:

Webpack Bulid 运行很慢,项目后台是一个用 Vue.js 开发的社区门户...

谁能告诉我是否有任何改进的潜力,如果有,是什么?

不知道37401ms的构建过程的时间是否仍然可以通过更改代码库来更改?

const path = require('path');
const fs = require('fs');
const webpack = require('webpack');
const glob = require('glob');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const autoprefixer = require('autoprefixer');

const statsSettings = {
    all: false,
    modules: true,
    maxModules: 0,
    errors: true,
    warnings: false,
    moduleTrace: true,
    errorDetails: true,
    timings: true,
    performance: true,
    builtAt: true,
};

const {
    rootDir,
    srcDir,
    assetsDir,
    stylesDir,
    buildDir,
    sitepackageDir,
    publicPath,
} = require('./config');

const chunks = glob.sync(path.join(rootDir, srcDir, 'pages/**/index.js'))
    .reduce((obj, file) => {
        const name = path.basename(path.dirname(file));
        return {
            ...obj,
            [name]: file,
        };
    }, {});

module.exports = env => {
    return {
        mode: env.production ? 'production' : 'development',
        context: path.join(rootDir, srcDir),
        entry: chunks,
        output: {
            path: path.join(rootDir, buildDir),
            filename: '[name].js',
            publicPath: env.production ? publicPath : '',
        },
        devtool: env.production ? false : 'cheap-module-eval-source-map',
        devServer: {
            contentBase: path.join(rootDir, buildDir),
            inline: true,
            proxy: {
                '/api/v0': 'http://localhost:4000',
            },
        },
        watchOptions: {
            ignored: env.watch ? 'node_modules' : '',
            aggregateTimeout: 300,
        },
        stats: env.watch ? statsSettings : 'normal',
        module: {
            rules: [
                {
                    test: /\.vue$/,
                    include: [
                        path.join(rootDir, srcDir),
                        require.resolve('bootstrap-vue'),
                    ],
                    loader: 'vue-loader',
                },
                {
                    test: /\.js$/,
                    include: [
                        path.join(rootDir, srcDir),
                        require.resolve('bootstrap-vue'),
                    ],
                    loader: 'babel-loader',
                },
                {
                    test: /\.(css|scss)$/,
                    use: [
                        env.production ? MiniCssExtractPlugin.loader : 'vue-style-loader',
                        'css-loader',
                        {
                            loader: 'postcss-loader',
                            options: {
                                plugins: [
                                    autoprefixer({
                                        browsers: ['>1%', 'last 2 versions', 'not ie < 11'],
                                    }),
                                ],
                            },
                        },
                        {
                            loader: 'sass-loader',
                            options: {
                                includePaths: [
                                    path.join(rootDir, srcDir, stylesDir),
                                ],
                            },
                        },
                    ],
                },
                {
                    test: /\.(jpg|jpeg|png|gif|webp|svg|eot|otf|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$/,
                    loader: 'file-loader',
                    options: {
                        name: `${assetsDir}/_processed_/[name].[hash:4].[ext]`,
                    },
                },
            ],
        },
        optimization: {
            runtimeChunk: {
                name: '_runtime',
            },
            splitChunks: {
                cacheGroups: {
                    // we need to figure out if it's worth having a common chunk
                    // or if each entry chunk should be somewhat self-contained
                    common: {
                        chunks: 'initial',
                        name: '_common',
                        minChunks: 2,
                        minSize: 0,
                    },
                    vendor: {
                        test: /node_modules/,
                        chunks: 'initial',
                        name: '_vendor',
                        enforce: true,
                    },
                },
            },
        },
        resolve: {
            extensions: ['.js', '.json', '.vue'],
            alias: {
                '@app': path.join(rootDir, srcDir),
                // although we're using single file components that can be pre-compiled,
                // we want to dynamically mounting them in the DOM html.
                // this is way we need to alias 'vue' to use the runtime + compiler build here.
                // see: https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
                vue$: 'vue/dist/vue.esm.js',
            },
        },
        plugins: [
            new webpack.DefinePlugin({
                PAGES: JSON.stringify(Object.keys(chunks)),
            }),
            new VueLoaderPlugin(),
            ...plugHtmlTemplates(),
            ...plugExtractCss(env),
            ...plugCopyAssets(),
        ],
    };
};

function plugHtmlTemplates () {
    return glob.sync(path.join(rootDir, srcDir, 'pages/**/template.html'))
        .map(template => {
            const name = path.basename(path.dirname(template));
            return {
                template,
                filename: `${name}.html`,
                chunks: ['_runtime', '_vendor', '_styles', '_common', name],
            };
        })
        .map(htmlConfig => new HtmlWebpackPlugin(htmlConfig));
}

function plugExtractCss (env) {
    if (!env.production) return [];

    return [
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[name].css',
        }),
    ];
}

function plugCopyAssets () {
    const assetsSrcPath = path.join(rootDir, srcDir, assetsDir);

    if (!fs.existsSync(assetsSrcPath)) return [];

    return [
        new CopyWebpackPlugin([
            { from: assetsSrcPath, to: path.join(rootDir, buildDir, path.basename(assetsDir)) },
            // this is required for the icons to be selectable in the backend
            { from: path.join(assetsSrcPath, 'icons/'), to: path.join(rootDir, sitepackageDir, 'Resources/Public/Icons/') },
            // this is required for avatars to be available; we must not check them in in fileadmin since they would
            // prevent having the dir linked by Deployer during a deployment
            { from: path.join(rootDir, '../packages/users/Resources/Private/Images/Avatars/'), to: path.join(rootDir, buildDir, 'static/avatars/') },
        ]),
    ];
}

问题是你是否可以通过使用不同的插件或总结步骤来提高性能......

【问题讨论】:

    标签: javascript performance webpack build webpack-4


    【解决方案1】:

    我有类似的配置。我的配置构建了约 33 秒。我添加了一个缓存加载程序包,并将构建时间减少到约 17 秒。

    npm install --save-dev cache-loader
    

    配置:

    rules: [
         //rules here
         {
            test: /\.vue$/,
            use: [
             {
               loader: 'cache-loader',
               options: {}
             },
             {
               loader: 'vue-loader',
               options: vueLoaderConfig
             }
            ],
         },
         {
            test: /\.js$/,
            use: [
            {
              loader: 'cache-loader',
              options: {}
            },
            {
              loader: 'babel-loader'
            }
            ],
             include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
          }
    ]
    

    【讨论】:

    • ty vm 我使用缓存加载器从 170 秒到 33 秒,就像你展示的那样 + stats: false
    猜你喜欢
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 2016-10-30
    相关资源
    最近更新 更多