6

项目中有 500 多个 ts 文件。每次 webpack 启动 watch 都要 40 多秒。修改代码后编译也要 12-16 秒。实在是太慢了,所以尝试优化一下。

总构建时间( run build): 45672ms
watch 时,修改代码后构建: 12秒

使用 webpack-visualizer 分析 webpack 都打包了什么。

webpack-visualizer 可将webpack打包的文件大小可视化,并展现依赖关系。
webpack-visualizer 使用方法
分析生成的文件可见。文件总大小 1.42M 中,其中 vue 占用了 500K+

图片描述
但是 webpack 中已排除 vue ,打包中不应包含 vue 模块。

  externals: {
    'vue': 'Vue',
    'vuex': 'Vuex',
    'vue-router': 'VueRouter'
  }

猜测是 import 时 使用了大写的 import Vue from Vue
应该改为 import Vue from vue ,改为 小写后,果然好了。。。
打包的文件变为 838 kB,打包时间为 41351ms
关于 externals的更多信息,可以参照webpack externals详解

优化 ts 构建

项目中使用的ts-loader来处理TypeScript,但是速度比较慢。
可以采用两种方式来优化:awesome-typescript-loaderthread-loader\Harrypack+cache-loader\hard-source-webpack-plugin+tsloader
这两种方式都使用到了多核+ 缓存来加快构建。
下面分别对比了两种优化方式。

使用 thread-loader + cache-loader + ts-loader

总构建时间( run build): 27秒
watch 时,修改代码后构建:8 秒

这里有个官方的例子
webpack.config.js 中修改 loader 和添加插件。

{
    module: {
        rules: [
            {
                test: /\.ts$/,
                exclude: /node_modules|vue\/src/,

                use: [
                    { loader: 'cache-loader' },
                    {
                        loader: 'thread-loader',
                        options: {
                            workers: require('os').cpus().length - 1,
                        },
                    },
                    {
                        loader: 'ts-loader',
                        options: {
                            happyPackMode: true, // IMPORTANT! use happyPackMode mode to speed-up compilation and reduce errors reported to webpack
                            appendTsSuffixTo: [/\.vue$/],
                            transpileOnly: true,
                        }
                    }
                ]
            },
            //...
        ],

    },
    // ...
    plugins: [
        new ForkTsCheckerWebpackPlugin({ checkSyntacticErrors: true }),
    ]
}

使用 awesome-typescript-loader

总构建时间( run build): 27秒
watch 时,修改代码后构建:6.5 秒

{
    module: {
        rules: [
            {
                test: /\.ts$/,
                exclude: /node_modules|vue\/src/,
                loader: 'awesome-typescript-loader',
            },
            //...
        ],

    },
    // ...
    plugins: [
    ]
}

注: 这两种方式都采用独立线程来检查 ts 语法错误。实际编译速度可能更快。比如 awesome-typescript-loader watch 状态,修改后编译为 2 秒。但是加上语法检查要6秒。其实第二秒时已经编译好了。

参考文章

  1. [webpack 构建性能优化策略小结](https://segmentfault.com/a/11...
  2. awesome-typescript-loader

meteor199
319 声望4 粉丝