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

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

第 1 步,列出您的供应商

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

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 文件,它没有任何功能,只是导入我们使用的库。

注意: 您也可以在这里使用 ES6 风格的 import,但是我们需要用 Bable 来构建 DLL。您仍然可以像您习惯的那样,在您的主项目中使用 import 和其他所有 ES2015 语法糖。

第 2 步,构建 DLL

现在我们可以创建一个 Webpack 配置来构建 DLL。这将从您的应用程序主 Webpack 配置中完全分离,并且会影响部分文件。它不会被您的 Webpack 中间件、Webpack 服务器或其他任何东西调用(手动或通过预构建除外)。

我们称之为 webpack.dll.js

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.js

第 3 步,构建项目

**注意:**下述示例不包含 sass、assets、或热加载程序。如果您已经在配置中使用了,它们仍然可以正常工作。

现在我们需要做的就是添加 DLLReferencePlugin,并将其指向我们已经构建的 DLL。您的 webpack.dev.js 可能是如下模样:

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前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

[译] 优化 WEBPACK 以更快地构建 REACT的更多相关文章

  1. Gradle更小、更快构建APP的奇淫技巧

    本文已获得原作者授权同意,翻译以及转载原文链接:Build your Android app Faster and Smaller than ever作者:Jirawatee译文链接:Gradle更小 ...

  2. 海量数据分析更快、更稳、更准。GaussDB(for MySQL) HTAP只读分析特性详解

    本文作者康祥,华为云数据库内核开发工程师,研究生阶段主要从事SPARQL查询优化相关工作.目前在华为公司参与华为云GaussDB(for MySQL) HTAP只读内核功能设计和研发. 1. 引言 H ...

  3. CSS VS JS动画,哪个更快[译]

    英文原文:https://davidwalsh.name/css-js-animation 原作者Julian Shapiro是Velocity.js的作者,Velocity.js是一个高效易用的js ...

  4. 优化Webpack构建性能的几点建议

    Webpack 作为目前最流行的前端构建工具之一,在 vue/react 等 Framework 的生态圈中都占据重要地位.在开发现代 Web 应用的过程中,Webpack 和我们的开发过程和发布过程 ...

  5. Quick UDP Internet Connections 让互联网更快的协议,QUIC在腾讯的实践及性能优化

    https://mp.weixin.qq.com/s/44ysXnVBUq_nJByMyX9n5A 让互联网更快:通往QUIC之路 原创: 史天 翻译 云技术实践 8月15日 QUIC(Quick U ...

  6. EdgeFormer: 向视觉 Transformer 学习,构建一个比 MobileViT 更好更快的卷积网络

    ​  前言 本文主要探究了轻量模型的设计.通过使用 Vision Transformer 的优势来改进卷积网络,从而获得更好的性能. 欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结.最新技术跟 ...

  7. 让DB2跑得更快——DB2内部解析与性能优化

    让DB2跑得更快——DB2内部解析与性能优化 (DB2数据库领域的精彩强音,DB2技巧精髓的热心分享,资深数据库专家牛新庄.干毅民.成孜论.唐志刚联袂推荐!)  洪烨著 2013年10月出版 定价:7 ...

  8. 《Java程序性能优化:让你的Java程序更快、更稳定》

    Java程序性能优化:让你的Java程序更快.更稳定, 卓越网更便宜,不错的书吧

  9. 优化webpack构建时间的小技巧

    在之前工作的地方,我们一直使用webpck去构建.但是,经过长达四年的更新迭代,每个人都在同一个项目中做了不同的操作和更新,这导致我们生产构建时间达到了惊人的一分半,watch模式的rebuild也达 ...

随机推荐

  1. sqlmap(网站数据库注入)

    *教程 http://www.nxadmin.com/tools/1241.html 一.ASP网站 1. sqlmap -u “http://www.czypjx.com/News_show.asp ...

  2. linux文本处理三剑客(一)---grep

    在linux种有一句话,叫做一切皆文件.文件有个特点,它是个文本.它可以读.可以写,如果是二进制文件,它还能执行.这样的话,我们在使用linux的时候,多数时间都是要和各式各样文件打交道的.那么,熟悉 ...

  3. Docker 安装 Tomcat

    查找Docker Hub上的tomcat镜像 docker search tomcat 取官方的镜像 docker pull tomcat 使用tomcat镜像 创建目录tomcat,用于存放后面的相 ...

  4. Upgrading CentOS 6 to CentOS 7

    Upgrading CentOS 6 to CentOS 7 November 15th, 2018 — whplus PRE TASKS There are some tasks you can d ...

  5. 安装matplotlib,报错ERROR: Command errored out with exit status 1:

    使用pip install matplotlib 出现报错信息: 发现这行报错 : 我是在pycharm上安装的,可是提示我去安装 Microsoft Visual C++ ,然后去百度查了下,发现只 ...

  6. 【AtCoder】AGC005

    AGC005 A - STring 用一个栈,如果遇到S就弹入,如果遇到T栈里有S就弹出栈顶,否则T在最后的串里,最后计算出的T和栈里剩的S就是答案 #include <bits/stdc++. ...

  7. 如何使用RedisTemplate访问Redis数据结构之字符串操作

    Redis 数据结构简介 Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串).List(列表).Set(集合).Hash(散列)和 Zset(有序集 ...

  8. # 滚动Hash

    滚动Hash 假设字符串\(C=c_1*c_2*...c_m\),定义Hash函数\(H(C)=(C_1*b^{m-1}+C_2*b^{m-2}+...C_m*b^{0})mod\; h\) 从k开始 ...

  9. PHP后台开发小经验

    js页面传参数 js的参数传输是关键,尤其是当一个页面的数据需要分步骤上传时. 同样的删除功能,不会操作批量删除时可以尝试单个删除,功能差不多,实现功能的方法也千千万,先做成它是第一位. 主页面很多条 ...

  10. Codeforces 1247D. Power Products

    传送门 要满足存在 $x$ ,使得 $a_i \cdot a_j = x^k$ 那么充分必要条件就是 $a_i \cdot a_j$ 质因数分解后每个质因数的次幂都要为 $k$ 的倍数 证明显然 设 ...