[译] 优化 WEBPACK 以更快地构建 REACT

若是您的 Webpack 构建缓慢且有大量的库 —— 别担忧,有一种方法能够提升增量构建的速度!Webpack 的 DLLPlugin 容许您将全部的依赖项构建到一个文件中。这是一个取代分块的很好选择。该文件稍后将由您的主 Webpack 配置,甚至能够在共享同一组依赖项的其余项目上使用。典型的 React 应用程序可能包含几十个供应商库,这取决于您的 Flux、插件、路由和其余工具(如 lodash)。咱们将经过容许 Webpack 跳过 DLL 中包含的任何引用来节省宝贵的构建时间。css

本文假设您已经熟悉典型的 Webpack 和 React 设置。若是没有,请查看 SurviveJS 在 Webpack 和 React 方面的优秀内容,当您的构建时间逐步增长时,请回到本文。前端

第 1 步,列出您的供应商

构建和维护 DLL 的最简单的方法是在您的项目中建立一个 JS 文件 —— vendors.js,其中引入您使用的全部库。例如,在咱们最近的项目中,咱们的 vendors.js 文件内容以下:node

require("classnames");
require("dom-css");
require("lodash");
require("react");
require("react-addons-update");
require("react-addons-pure-render-mixin");
require("react-dom");
require("react-redux");
require("react-router");
require("redux");
require("redux-saga");
require("redux-simple-router");
require("redux-storage");
require("redux-undo");
复制代码

这是咱们将要“构建”的 DLL 文件,它没有任何功能,只是导入咱们使用的库。react

注意: 您也能够在这里使用 ES6 风格的 import,可是咱们须要用 Bable 来构建 DLL。您仍然能够像您习惯的那样,在您的主项目中使用 import 和其余全部 ES2015 语法糖。android

第 2 步,构建 DLL

如今咱们能够建立一个 Webpack 配置来构建 DLL。这将从您的应用程序主 Webpack 配置中彻底分离,而且会影响部分文件。它不会被您的 Webpack 中间件、Webpack 服务器或其余任何东西调用(手动或经过预构建除外)。webpack

咱们称之为 webpack.dll.jsios

var path = require("path");
var webpack = require("webpack");

module.exports = {
    entry: {
        vendor: [path.join(__dirname, "client", "vendors.js")]
    },
    output: {
        path: path.join(__dirname, "dist", "dll"),
        filename: "dll.[name].js",
        library: "[name]"
    },
    plugins: [
        new webpack.DllPlugin({
            path: path.join(__dirname, "dll", "[name]-manifest.json"),
            name: "[name]",
            context: path.resolve(__dirname, "client")
        }),
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.optimize.UglifyJsPlugin()
    ],
    resolve: {
        root: path.resolve(__dirname, "client"),
        modulesDirectories: ["node_modules"]
    }
};
复制代码

这是典型的 Webpack 配置,除了 webpack.DLLPlugin 之外,它包含 name、context 和 mainifest 路径。mainifest 很是重要,它为其余 Webpack 配置提供了您到已经构建模块的映射。context 是客户端源码的根,而 name 是入口的名称,在本例中是“供应商”。继续尝试使用命令 webpack --config=webpack.dll.js 运行这个构建。最后,您应该获得一个包含模块的排列映射 —— dll\vendor-manifest.json 已经包含了您全部供应商库的精简包 ——  dist\dll\dll.vendor.jsgit

第 3 步,构建项目

**注意:**下述示例不包含 sass、assets、或热加载程序。若是您已经在配置中使用了,它们仍然能够正常工做。github

如今咱们须要作的就是添加 DLLReferencePlugin,并将其指向咱们已经构建的 DLL。您的 webpack.dev.js 多是以下模样:web

var path = require("path");
var webpack = require("webpack");

module.exports = {
    cache: true,
    devtool: "eval", //or cheap-module-eval-source-map
    entry: {
        app: path.join(__dirname, "client", "index.js")
    },
    output: {
        path: path.join(__dirname, "dist"),
        filename: "[name].js",
        chunkFilename: "[name].js"
    },
    plugins: [
        //Typically you'd have plenty of other plugins here as well new webpack.DllReferencePlugin({ context: path.join(__dirname, "client"), manifest: require("./dll/vendor-manifest.json") }), ], module: { loaders: [ { test: /\.jsx?$/, loader: "babel", include: [ path.join(__dirname, "client") //important for performance! ], query: { cacheDirectory: true, //important for performance plugins: ["transform-regenerator"], presets: ["react", "es2015", "stage-0"] } } ] }, resolve: { extensions: ["", ".js", ".jsx"], root: path.resolve(__dirname, "client"), modulesDirectories: ["node_modules"] } }; 复制代码

咱们还作了一些其余事来提升性能,包括:

  • 确保咱们有 cache: true
  • 确保 Babel 在查询中加载程序有 cacheDirectory:true
  • 在 bable loader 中使用 include(您应该在全部的 loader 中这样作)
  • 将 devTool 设置为 eval,由于咱们正在为构建时间优化 #nobugs

第 4 步,包含 DLL

此时,您已经生成了一个供应商 DLL 文件,而且您的 Webpack 构建并生成 app.js 文件。您须要在模版中提供并包含这两个文件,但 DLL 应该是第一位的。您可能已经使用 HtmlWebpackPlugin 设置了模版。由于咱们不关心热重载 DLL,因此除了在主 app.js 以前包含 <script src="dll/dll.vendor.js"></script> 以外,您实际上不须要作任何事。若是您使用的是 webpack-middleware 或者您本身定制化的服务器,则还须要确保为 DLL 提供服务。此时,一切都应该按原样运行,可是使用 Webpack 进行增量构建的速度应该很是快。

第 5 步,构建脚本

咱们可使用 NPM 和 package.json 添加一些为咱们构建的简单脚本。要清除 dist 文件夹,请继续运行 npm i rimraf --saveDev。如今能够添加到您的 package.json 中了:

"scripts": {
    "clean": "rimraf dist",
    "build:webpack": "webpack --config config.prod.js",
    "build:dll": "webpack --config config.dll.js",
    "build": "npm run clean && npm run build:dll && npm run build:webpack",
    "watch": "npm run build:dll && webpack --config config.dev.js --watch --progress"
  }
复制代码

如今您能够运行 npm run watch。若是您喜欢手动运行 build:dll,则能够将其从监视脚本中删除,以便更快地启动。

就这样,伙计们!

我但愿这能让您深刻了解 InVision 如何使用 Webpack 的 DLLPlugin 来提升构建速度。若是您有任何问题或想法,欢迎发表评论。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索