Now for every front-end engineer, WebPack has become a basic skill, it basically does all the work of local development, compilation and compression, performance optimization, from this point of view, WebPack is really great, its birth means that a whole set of engineering system began to spread. And slowly unified the front-end of automatic construction so that the front-end development completely bid farewell to the previous slash-and-burn era. Now webpack is to front-end development what GCC /g++ is to C/C++, a tool you can’t get away from anyway.

But even as great as it is, there is a huge problem with WebPack being so hard to use!!

I’ve been using it since webPack 1.0 years ago, and I can’t say I’ve mastered it yet, and there are times when I really wonder if it’s because I don’t have the skills, or because WebPack itself is just too hard to use. As I worked on more front-end projects and heard more jokes, I became more convinced that it was webPack itself that made it so complex and difficult to use.

As a simple example, a vue-CLI generated scaffolding project has 14 files to develop and build, and over 800 lines of code. The actual project would only have more than that:

So, since this article is titled “Why is WebPack So hard to Use?” So let’s take a look at the root cause of webPack’s difficulty here.


First, the documentation is extremely imperfect

Yes, that’s why it’s number one.

As someone who has participated in the Translation of Webpack Chinese documents, I really want to say that even after so many years of continuous iteration of Webpack, the current document is still a lump of what. As an open source project, the design, ease of use, and extensibility of the project are all subject to debate, but there is really no excuse for poor documentation.

Unfriendly to users

For example, the plug-in system of Webpack can be said to be one of the most core functions of Webpack. Basically, in the construction of a project, most tasks are completed by various plug-ins. However, the Plugins in the official documentation are only a few sentences long: Webpack · Plugins, and you are even advised to look directly at the source code for Webpack:

To make matters worse, the existing documentation (including some of the webPack plug-ins) mostly tells you “just do it” rather than “why you need to do it” and “what will happen if you do it”.

For example, in the target configuration, the official documentation lists which targets you can build into, such as Node, Node-webkit, and electron main, but it’s all in one sentence:

Want to know how the package differs from the browser environment when target is electronic-main? Sorry, the official documentation doesn’t want to tell you, look at the source code or check stackOverflow.

As a direct result of the lack of clarity in official documentation, when you come across a problem, you don’t get a direct answer in documentation, but instead have to read countless codes, Github issues, StackOverflow, blog posts, and then iterate on your own projects several times to get a rough answer. And this so-called “problem solving”, which is often personal and empirical, means that anyone else who wants to solve the problem has to repeat the process, with a huge increase in time costs.

This is why the following three philosophical questions often arise when using Webpack:

  • Is this a Webpack problem?
  • How can I solve this problem?
  • How did I solve it?

Not being friendly to developers

How do we develop a plug-in for WebPack?

The official documentation does provide some guidance on how to develop plug-ins. It does introduce you to the basics of the WebPack plug-in, the basic concepts, and some apis, but when you’re ready to actually develop a plug-in yourself, you’ll find that it’s not enough.

Let’s take a look at some of the more mature plugins in the Webpack ecosystem today. Take the htMl-webpack-plugin, which is widely used to generate HTML files. In its source code, you’ll find that it references five plugins that come with WebPack (source code here) :

var NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
var NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
var LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin');
var LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
Copy the code

Uh huh? What are these five plug-ins for?

The official documentation doesn’t say a word about built-in Plugins, and yes, not even Plugins. It’s on the official wiki, but it’s really, really sketchy and looks like it hasn’t been updated in a while.

The uglifyjs-webpack-plugin doesn’t rely on webPack’s built-in plugins, but it also references two files within WebPack:

import RequestShortener from 'webpack/lib/RequestShortener';
import ModuleFilenameHelpers from 'webpack/lib/ModuleFilenameHelpers';
Copy the code

There is also no description of these two files. Gratifying (?) The thing is, these two files are not too complicated to use, based on their file names, or at least method libraries (which they are).

In other words, if you want to write a widely known plug-in for WebPack, you need to know everything about WebPack, which I don’t disagree with, since webPack developers and WebPack users have different requirements in terms of capabilities. But even experienced developers struggle with an open source project that is so poorly documented. Many of the things that help developers should be written openly in documentation and guidelines, not hidden in the source code.


Second, the excessive plugin system

Plug-in system is the core of Webpack, in fact, most of the functions of Webpack are completed by internal plug-ins or third-party plug-ins. The WebPack ecosystem is built on plugins.

But the plugin system also has many problems.

Number of plug-ins

To start with, how many plug-ins does a project built with WebPack need?

Taking a standard VUE-CLI-generated scaffolding project as an example, there are seven third-party plug-ins:

"copy-webpack-plugin": "^ 4.0.1." "."extract-text-webpack-plugin": "^ 3.0.0"."friendly-errors-webpack-plugin": "^ 1.6.1." "."html-webpack-plugin": "^ 2.30.1"."webpack-bundle-analyzer": "^ 2.9.0"."optimize-css-assets-webpack-plugin": "^ 3.2.0"."uglifyjs-webpack-plugin": "^ 1.1.1".Copy the code

And 7 built-in WebPack plugins:

  • HashedModuleIdsPlugin
  • ModuleConcatenationPlugin
  • CommonsChunkPlugin
  • DefinePlugin
  • HotModuleReplacementPlugin
  • NamedModulesPlugin
  • NoEmitOnErrorsPlugin

There are 14 plug-ins in total, and if we calculate that each plug-in has an average of 2-3 configuration items (this is already a low calculation), there are more than 30 configurations in 14 plug-ins. This is already a very basic configuration used in modern WebPack development and construction, and real projects will only be more than this.

Note that more than 30 configuration items can be more complex than 30 lines of code. Because configuration items are already highly abstract, a configuration has far more side effects than a line of code. For example, here is the configuration of the CommonsChunkPlugin commonly used to extract common modules:

new webpack.optimize.CommonsChunkPlugin({
    name: 'app'.async: 'vendor-async'.children: true.minChunks: 3
})
Copy the code

If you’re not a webpack veteran, you’ll be surprised to see these four configurations:

  • nameWhat should I fill in? Can we just call it anything?
  • asyncWhat is? Asynchronous modules? Why is that a string?
  • childrenIs a what? Why not?ArrayBut aboolean?
  • minChunksWhat is this number?chunkWhat is it?

Then you go to the CommonsChunkPlugin documentation, and after 15 minutes of hard reading, you’ll see that none of these four configurations is easy, and that each change can have a big impact on the build.

The bad news is that there are more than 30 such configurations in the project!

So every time I changed a build for a project, it basically looked like this:

Configuration-oriented plug-ins

Before we get into this topic, answer two questions:

  • Does the order of webPack plug-ins affect the build result?

  • What would be affected if the order of the plug-ins were different?

As a matter of fact, I searched the official documentation for these two issues, and there was no mention of how the order of plugins affects anything. Instead, I found a question on StackOverflow: Webpack: Does the order of plugins matter?

So the answer is: the order of the plugins matters, but it’s not clear.

It’s not just the order of the plugins that’s the problem; it’s hard to know what impact a plugin has on the build unless you’re extremely familiar with the plugin or its author. Why is that? The root cause is that webPack’s plug-ins are configuration-oriented, not process-oriented

What is process oriented? If you know or have used the gulp automation tool, you will remember the concept of gulp pipes, which take the source data (JS/CSS/HTML source code, images, fonts, etc.) from the source, then pass the data through one pipe after another, and output it as the result of the build. In pseudocode, it would look something like this:

gulp.src('Some source files').pipe(handle a).pipe(handle b).pipe(handle C).pipe(handle D).dest('Build result')
Copy the code

This pipelining, or process-oriented, build is very easy to debug or modify because each step of the build is shown in order. The mental burden of trying to modify any of these steps is low because its processing mechanism is very pure function.

With WebPack, however, it looks something like this:

Plugins: plugins 1, plugins 2, plugins 3}Copy the code

Here, plugins one, two, and three are completely configuration oriented and do not tell you any order of execution, they may be triggered at every point in time that WebPack is built, and you can only guess roughly from their functionality when it is working. That’s why modifying some webPack configurations can be a hassle and a pain in the ass when trying to undo a headset cord that’s been in your bag for a long time.

Of course, there are benefits to this configuration of plug-ins. Configuration represents a high degree of integration, and when you only have 1-3 plug-ins, the mental burden of maintaining these configurations is acceptable and more convenient than maintaining a process-oriented configuration. But when the number of plug-ins exceeds this, the complexity of the build increases exponentially. As we mentioned earlier, a modern WebPack project has at least 14 plug-ins and at least 30 configurations. In this case, process-oriented is better than configuration-oriented. This is why I have always felt that Gulp + Webpack is the right solution.

Gulp is a Task runner and Webpack is a Module bundler. Both of them have some irreplaceable features.


Is configuration a silver bullet?

In everyday business, especially in some operational businesses of large companies, we often see the phrase “such and such business has been fully configured.” In this context, configuration represents low maintenance cost, high flexibility, and high encapsulation.

In the tech world, configuration is also a good thing. Many tools claim to be fully configured. Just add a configuration file to your project and you can do a lot of things with that tool.

So is configuration the end of all tool evolution? Does it solve all our problems?

There is a familiar phrase in software engineering: “There is no silver bullet,” referring to the fact that complex software engineering problems cannot be solved with simple answers. The same is true for front-end engineering builds.

How to solve front-end engineering construction? Webpack gives the answer: webpack + Loader + plugin, make all resources build configurable. This was impressive in its day, when a simple configuration file took care of all of your resource builds.

But as time went on, a front-end project became more complex to build, webPack configurations became more and more difficult to maintain, and scaffolding tools such as create-React-app and VUE-CLI emerged. Build on webPack to help you automatically generate webPack configurations. At this point, WebPack becomes more of a “low-level” tool, and the scaffolding is your actual “build tool,” or the configuration that the scaffolding provides is your actual build configuration.

Why is that?

The root of the problem is that the webpack now provide the configuration of the encapsulation is no longer enough, it is faced with a large front end engineering today is much more complicated, the only configuration doesn’t like a few years ago to block most of the construction details for us, so it was born on the basis of the scaffold so many tools to help us further encapsulation complexity.

So we can now answer the title of this paragraph: Is configuration the silver bullet for complexity? Of course not, because configurations become more complex and harder to maintain as they increase in complexity, until a certain threshold is passed and they need to be further encapsulated to create new configurations.


Fourth, the future of front-end engineering construction

As I said in the previous chapter, as complexity increases, complexity needs to be encapsulated to bring the mental cost of maintaining the configuration down to an acceptable level. And with front-end build tools, the cut-off trend is exactly the same:

  • In the ancient days of the front end, we didn’t need to build, because at this time the front end project was very simple, the original HTML/JS/CSS was enough to meet the needs, and manual processing of these resources was convenient and fast.
  • As the front end became more complicated and manual processing became less efficient, automated tools such as Grunt and Gulp were born. These tools mask the details of resource processing and allow it to be automated.
  • As build processes grow, resources grow, ECMAScript language features become more complex, and development/test/production environments begin to differentiate, tools like Gulpfile/Grunt are no longer enough. What we need is a complete configured build solution. Webpack is one such solution.
  • As WebPack configurations become more complex and expensive to maintain, there are many scaffolding tools that help you generate webPack configurations and encapsulate the complexity of WebPack.

So what will the next generation of front-end building tools look like?

The scaffolding tools that are widely used today, after all, rely on WebPack, and what we really need is a build tool that is more integrated and packaged (or even zero configuration). In more detail, the next generation of front-end build tools are bound to have some of the following features:

  • There are more built-in functions, such as Babel, dev-Server, HMR, sourceMap, etc.
  • Less or no configuration;
  • Lower cost differentiating between development, test and production environments;
  • Better performance, integration of lengthy build processes, support for multi-core cpus, etc.
  • Support for new modules: asynchronous modules, WebAssembly modules, etc.

In fact, these are some of the new webPack 4.0 features, and the Parcel I saw a while back has some of them (although it still looks pretty raw right now). There will only be more of these building tools in the future.


conclusion

This article has been in the works for a long time, but recently I came across a lot of problems with WebPack, which gave me the motivation to make fun of it.

Why is Webpack so hard to use? The answers given here can be summarized in two points:

  • Poor documentation makes it difficult for users and developers to address problems;
  • The number of plugins required for a project is too large and configuration oriented, resulting in an exponential increase in maintenance costs.

Will these problems improve in the future? Of course. In fact, this article is suspected of being a headline party. A more accurate title would be:

Why is WebPack so hard to use today?

Because all of the issues mentioned in this article will be improved in WebPack 4.0.

The forehead… As for its documentation… Forget it. Forget it. “O__O”…