什么是webpack? (What is webpack?)
If you are arriving at this page without prior knowledge of webpack, let me help you out with a few aspects. It is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging. You can use webpack to make your bundle more productive. What do I mean by productive? Depends on the needs of your project. Take, for example, caching your statics. If we do not update file paths, then the browser will still serve cached resources to users.
如果您在没有webpack的先验知识的情况下到达此页面,请让我在几个方面帮助您。 它是一个模块捆绑器。 它的主要目的是捆绑JavaScript文件以供在浏览器中使用,但它也能够转换,捆绑或打包。 您可以使用webpack来提高打包效率。 我所说的生产力是什么? 取决于项目的需求。 以缓存静态变量为例。 如果我们不更新文件路径,那么浏览器仍将向用户提供缓存的资源。
散列 (Hashing)
Nowadays, we use webpack to build our resources as it’s very easy to use. So here comes the concept of hashing in webpack, which allows us to generate new hashes for each chunk across the new build. You can set up a basic webpack config that will do above for you.
如今,我们非常容易使用webpack来构建资源。 因此,出现了Webpack中哈希的概念,它使我们能够为新构建中的每个块生成新的哈希。 您可以设置一个基本的webpack配置,该配置将为您完成。
Hash: 9dsn348s34378y99
哈希:9dsn348s34378y99
Version: webpack 1.10.1
版本:webpack 1.10.1
Time: 76ms
时间:76ms
Asset Size Chunks Chunk Names
资产规模块名称
main. 9dsn348s34378y99.js 1.43 kB 0 [emitted] main
主要。 9dsn348s34378y99.js 1.43 kB 0 [emited] main
vendor. 9dsn348s34378y99.js 1.43 kB 1 [emitted] vendor
供应商。 9dsn348s34378y99.js 1.43 kB 1 [发出]供应商
[0] ./src/index.js 46 bytes {0} [built]
[0] ./src/index.js 46字节{0} [内置]
[0] ./src/vendor.js 40 bytes {1} [built]
[0] ./src/vendor.js 40字节{1} [内置]
What’s the problem with this config implementation? The hash 9dsn348s34378y99 will be recreated with another random hash every build. To increase the performance of our application, we can only update the chunks that were previously changed in the development side, so that next time the user opens our app after a new deployment, the user doesn’t have to download all the assets again from the server. They should only fetch resources which we have made changes for.
这个配置实现有什么问题? 每次构建时,将使用另一个随机哈希重新创建哈希9dsn348s34378y99。 为了提高我们的应用程序的性能,我们只能更新以前在开发方面更改的块,这样,下次用户在新部署后打开我们的应用程序时,用户不必从以下位置再次下载所有资产服务器。 他们只应获取我们进行了更改的资源。
Webpack provides three types of hashing:
Webpack提供三种类型的哈希:
- hash 杂凑
chunkHash
chunkHash
contentHash
contentHash
I will briefly explain the difference between these hashes.
我将简要解释这些哈希值之间的区别。
杂凑 (Hash)
Hash is corresponding to build. Each chunk will get the same hash across the build. If anything changes in your build, the corresponding hash will also change.
哈希对应于构建。 每个块将在整个构建过程中获得相同的哈希值。 如果您的构建中有任何更改,则相应的哈希也将更改。
chunkHash (chunkHash)
chunkhash
is based on the webpack entry point. Each entry defined will have its own hash. If anything changes for that particular entry point, then only the corresponding hash will change.
chunkhash
基于webpack入口点。 定义的每个条目将具有其自己的哈希。 如果该特定入口点有任何更改,则仅相应的哈希将更改。
contentHash (contentHash)
contenthash
is a specific type of hash created in ExtractTextPlugin
and is calculated by extracted content, not by full chunk content.
contenthash
是在ExtractTextPlugin
创建的一种特定类型的哈希,由提取的内容而不是完整的块内容计算得出。
代码分割 (Code Splitting)
Have you seen this message in your CLI?
您是否在CLI中看到此消息?
“WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.”
“警告入口点大小限制:以下入口点的合并资产大小超过了建议的限制(244 KiB)。 这可能会影响网络性能。”
If yes, probably you are having performance issues with your bundle size — webpack is trying to tell you that your bundle is big. How can we proceed to leverage the performance of your application and avoid this kind of warning? Analyzing the bundle size is the way to go.
如果是,则可能是您的捆绑包大小存在性能问题-webpack试图告诉您捆绑包很大。 我们如何继续利用您的应用程序的性能并避免此类警告? 分析捆绑包的大小是解决之道。
The first thing you need to do is to measure your bundle size. How can we do that?
您需要做的第一件事是测量捆绑包的大小。 我们该怎么做?
You should always measure the impact of a problem before diving into some premature optimizations. We can use devtool
inside webpack.config.js
to enable the source-map
to inspect our JavaScript bundles and then take actions accordingly, e.g.:
你应该总是 在进行一些过早的优化之前,先测量问题的影响。 我们可以在webpack.config.js
使用devtool
来启用source-map
来检查我们JavaScript包,然后采取相应的措施,例如:
Add to your package.json
a script called analyze
, e.g.:
添加到您package.json
一个脚本调用analyze
,例如:
We can then run:
然后我们可以运行:
npm run build
npm run analyze
You are probably going to see something like this:
您可能会看到以下内容:
As you can see in the bundle file, Bluebird, Lodash, and MobX are heavyweights in your application. This is a good starting point to check which scripts you want to code-split from your bundle file and generate different bundle files. Code-splitting your app can help you lazy-load just the things that are currently needed by the user, which can dramatically improve the performance of your app. While you haven’t reduced the overall amount of code in your app, you’ve avoided loading code that the user may never need and reduced the amount of code needed during the initial load.
从捆绑文件中可以看到, Bluebird , Lodash和MobX是应用程序中的重量级人物。 这是检查要从捆绑文件中拆分代码的脚本并生成不同捆绑文件的一个很好的起点。 对应用程序进行代码拆分可以帮助您仅延迟加载用户当前需要的内容,从而可以显着提高应用程序的性能。 尽管您并未减少应用程序中的代码总数,但避免了加载用户可能永远不需要的代码,并减少了初始加载期间的代码量。
As this article is about webpack essentials, I will not dig into code splitting. This article is merely a brief explanation about what’s useful in webpack, but I promise I will create a special article just on code splitting.
由于本文是有关webpack的要点,因此我不会深入研究代码拆分。 本文只是对webpack中有用的内容的简要说明,但是我保证我将创建一篇专门介绍代码拆分的文章。
开发与生产模式 (Development vs. Production Mode)
webpack makes it easier to deploy multiple environments (development, test, and production) with only the code and data specifically needed for each. Since webpack v4, we have available the functionality of mode
that uses a set of built-in configuration optimizations accordingly. You can pass it as an argument inside of your CLI.
webpack使得仅使用每个特定的代码和数据即可轻松部署多个环境(开发,测试和生产)。 从webpack v4开始,我们提供了mode
功能,该功能相应地使用了一组内置配置优化。 您可以在CLI内部将其作为参数传递。
webpack — mode=development
webpack —模式=开发
According to the webpack official website, this is what happens when you set the option accordingly:
根据webpack的官方网站,当您相应地设置选项时,会发生以下情况:
Development — Sets process.env.NODE_ENV
on DefinePlugin
to value development
. Enables NamedChunksPlugin
and NamedModulesPlugin
.
开发 -将DefinePlugin
上的process.env.NODE_ENV
设置为值development
。 启用NamedChunksPlugin
和NamedModulesPlugin
。
Production — Sets process.env.NODE_ENV
on DefinePlugin
to value production
. Enables FlagDependencyUsagePlugin
, FlagIncludedChunksPlugin
, ModuleConcatenationPlugin
, NoEmitOnErrorsPlugin
, OccurrenceOrderPlugi
, SideEffectsFlagPlugin
, and TerserPlugin
.
生产 —将DefinePlugin
上的process.env.NODE_ENV
设置为值production
。 启用FlagDependencyUsagePlugin
, FlagIncludedChunksPlugin
, ModuleConcatenationPlugin
, NoEmitOnErrorsPlugin
, OccurrenceOrderPlugi
, SideEffectsFlagPlugin
和TerserPlugin
。
webpack摇树 (webpack Tree Shaking)
Tree shaking, at least webpack’s implementation of the feature, is pretty good at eliminating as much unused code as possible. For example, imports that are imported but not used are eliminated.
摇树,至少是webpack对该功能的实现,非常擅长消除尽可能多的未使用代码。 例如,消除了导入但未使用的导入。
In the example above, only the divide
function is being called. The subtract
function is never used and will be removed in the final bundle.
在上面的示例中,仅调用了divide
函数。 从未使用过subtract
功能,它将在最后的捆绑软件中删除。
Even specific properties from imported objects that are never accessed are removed.
甚至从从未访问过的导入对象中删除特定属性。
However, tree shaking doesn’t eliminate all unused code. The details of what is and isn’t eliminated are beyond the scope of this article, but it should be noted that the use of tree shaking doesn’t solve the problem of unused code entirely.
但是,摇树并不能消除所有未使用的代码。 消除和不消除的细节不在本文讨论范围之内,但应注意的是,使用树状摇动并不能完全解决未使用代码的问题。
副作用 (Side effects)
A side effect is a code that performs some action when imported that’s not necessarily related to any export. A good example of a side effect is a polyfill. Polyfills typically don’t provide an export to be used in the main script but rather add to the project as a whole.
副作用是在导入时执行某些动作的代码,该动作不一定与任何导出有关。 副作用是一个很好的例子。 Polyfill通常不提供要在主脚本中使用的导出,而是将其整体添加到项目中。
Tree shaking can’t automatically tell which scripts are side effects, so it’s important to specify them manually, as we will see below.
摇树并不能自动判断哪些脚本是副作用,因此手动指定它们很重要,如下所示。
我们如何使用它? (How can we use it?)
You can simply set the mode to production in your webpack.config.js
configuration file or use the argument in CLI, as I mentioned above. This will, among other optimizations, enable tree shaking.
您可以在webpack.config.js
配置文件中简单地将模式设置为生产,或者使用CLI中的参数,如上所述。 除其他优化外,这将使树摇动。
webpack is a powerful tool that can help us to develop more robust applications. There's a ton of features. In this article, I tried to mention the most important without going too deep into any of those other aspects.
webpack是一个功能强大的工具,可以帮助我们开发更强大的应用程序。 有很多功能。 在本文中,我尝试提及最重要的内容,而没有深入探讨其他任何方面。
Reliable source: https://webpack.js.org/
可靠来源: https : //webpack.js.org/
翻译自: https://medium.com/better-programming/webpack-essentials-updated-for-2020-4a0aa019ca3