Welcome to pay attention to the rich way Web development team, lack of conformity

In fact, to tell the truth, there are many reasons for the origin of this article. I’ve done quite a few projects before that. There are new projects and there are old projects. Make improvements through constant research on old projects. Then apply the new build to the new project with your own understanding. Over time, there was a set of webPack front-end building specifications that felt like a good fit.

So let’s talk a little bit about webpack4+ build.

Multi-entry basically means that the main front-end JS function files are different when accessing different pages. The best comparison and difference is the SPA single page application, where each page introduces the same JS file.

My desired build is:

  1. All in one go (fun coding process)
  2. Great freedom from back-end language constraints (decoupling)
  3. Multi-entry (multi-entry, multi-page)

In one go, this means that the project starts when you do git Clone, pull code, until you git push code. In between, everything that has nothing to do with code is done in one go, and you don’t need to configure too much. What we want to achieve is the ultimate experience of coding. The only thing developers are expected to care about is whether the code they write is OK.

That also means webPack builds need to do more work.

Moving away from back-end languages is not a good thing, it just depends on the project. In the most recent project I wrote, I used vue + Node.js. Using vue generally means that there is very little other node.js template code (e.g. jade, swig) in the template file, and very little front-end code. That is, a shell page, SPA single page application should be more familiar.

That’s the shell page, and it’s not really coupled to the backend language. That also means THAT I can decouple the back-end code to a great extent. What does that mean?

If you think about it, there are only two things you need to focus on during development: pages and static resources. The code that is coupled to the back end is only the page. As mentioned above, with VUE as SPA, the page is not actually coupled to the back end.

In other words, it facilitates the decoupling of the front and back ends. All of the front-end resources can be isolated, as long as you make sure that, after you build, you can generate the page, the static resources to the specified project directory.

So the build here is done by Webpack.

It has been indicated in the figure above:

  1. Client: stores the front-end resource directory
  2. Server: a directory for storing back-end resources. In this case, the backend is Node.js
  3. Static: indicates the directory of static resources. That’s where the JS/CSS files are placed

This leads to a question worth thinking about first, what is the purpose of webapck construction? What is the purpose of construction when it comes to engineering projects?

Combined with the directory structure diagram above, the purpose of WebPack is to package and compile static resources; So in engineering, is to build the front-end resource client directory resources through Webpack to the specified static and server/views directory.

So that’s a great degree of decoupling.

How to change from a single portal Webpak build to a multi-portal build? This is the problem that this article needs to solve today, and it is also the problem that I need to solve all the time, and it is also the original intention of writing this article.

Let’s start with the current situation for this multi-entry program construction problem.

Note: Everything below is described on a single-entry basis, and the demo is here: the Webpack case

Webpack build status

I’ve only done single entry builds for WebPack builds for a long time. Also known as SPA. This does not affect the operation of the project, because the project has a single function, a clear goal, the resource file will not be too large, so after packaging and compression, the resulting file will not be too large, appropriate split can be.

As shown, the build is simple, single entry, single page. All files are imported via main.js and its imported submodules, forming a single entry. As a classic SPA project, with an entry page called index.html, the front-end jump is accomplished by the collaboration of front-end and back-end routes.

It’s easy to understand what you need webPack to do:

  1. Introduce module resolution of corresponding files. Such as:vue-loader.babel-loader.css-loaderEtc.
  2. Extract CSS for external introduction throughlinkTags introduced
  3. File compression
  4. Large file splitting
  5. Public files are extracted as separate files
  6. throughhtml-webpack-pluginInject all dependent static resources, such as JS and CSS, into the template file, and save the generated target file to the specified server template file directory

As I said, the last file that the front-end needs to process is probably 3 HTML, JS, and CSS.

Demo Details Address –>> Single-entry case

Webpack4 + multi-entry construction ideas

Now that you know how single-portal builds work. So let’s think about how to play webPack multi-entry builds.

Forget about webPack configuration. In terms of demand, it is not the expectation:

  1. There are a lot of entry files
  2. There are many HTML template files generated. This is going to generate thetaserver/viewsdirectory
  3. Static resources such as JS/CSS required by its own module can be imported into THE HTML template file, and other modules are not imported to avoid redundant code

The static resource js/ CSS is generated and saved to the static directory.

This means that the pagea.js entry file shown above, once built with Webpack, will only inject pagea.html. Pageb.html is not injected.

In fact, there is one difficulty: how to make the HTML template file of the corresponding entry file introduce JS/CSS only related to this module.

Webpack4 + multi-entry build configuration combat

That is no nonsense, how to configure in actual combat? I’m afraid I’m not the only one wondering. In fact, every problem above has a solution here.

As shown in the figure, you can see the multi-entry configuration. It is super simple to add the corresponding module entry.

entry:{// Import file
  pagea:'./client/pagea/index.js'.pageb:'./client/pageb/index.js'
}
Copy the code

There are two entry files pagea.js and pageb.js in the demo.

For this how to make the corresponding entry file HTML template file, introduce js/ CSS only relevant to this module.

This can be solved by htML-webpack-plugin. You can configure multiple htML-Webpack-Plugin instance objects first, and then specify what chunks files each instance object needs to import.

new HtmlWebpackPlugin({
    filename: '. /.. /.. /server/views/pagea.html'.chunks: ['pagea'].template: path.resolve(__dirname , './client/template.html')}),new HtmlWebpackPlugin({
    filename: '. /.. /.. /server/views/pageb.html'.chunks: ['pageb'].template: path.resolve(__dirname , './client/template.html')})Copy the code

The configuration here is simple. The pagea.html configuration only imports pagea.js. When you need to import more than one, you just need to add the corresponding module name to the array.

That’s it. Let’s see what happens.

Run NPM install to download the required modules and then run the webpack command to build them.

Webpack please install globally, requires V4.5 +.

As you can see, the webpack compilation generates the pagea.html and pageb.html we want. And the JS file injection is normal.

Now run the NPM run develop command to start the Node.js service. Open 127.0.0.1:4000 in your browser and you’ll see the page.

Pagea.html and pageb.html, import normal, and work fine. Done !!!!

Demo details Address –>> Multi-entry case

Webpack4 + optimization

Just when you think things are calm, the challenge begins. To achieve multiple entry, in fact, the feeling is quite simple. To do well, in fact, the distance is still very far. The next section has little to do with multi-mouth construction. Mainly webpack4+ based optimization points, that is, the solution to the related problems encountered.

Split Chunks

When the project was small, everything felt so good. Nothing happened. However, once the project becomes complex, many problems that have not been encountered before will be exposed.

When I tried to introduce vue and Tui-chart chart modules in Pagea.js, I found that the packaged files were too large, reaching 2.2MB, even though they were the same after compression.

It is time to introduce file splitting, since the CommonChunks module is not recommended after Webpack4 +, so use the new officially recommended SplitChunks module.

By adding the following to the Webpack plugin:

new webpack.optimize.SplitChunksPlugin({
    chunks: 'all'.minSize: 30000.minChunks: 1.maxAsyncRequests: 5.maxInitialRequests: 3.automaticNameDelimiter: The '-'.name: true.cacheGroups: {
        vue: {
            test: /[\\/]node_modules[\\/]vue[\\/]/.priority: - 10.name: 'vue'
        },
        'tui-chart': {
            test: /[\\/]node_modules[\\/]tui-chart[\\/]/.priority: - 20.name: 'tui-chart'}}})Copy the code

There are several ways to add splitChunks. The above is just one of them.

Module reuse is achieved by setting public modules in cacheGroups. It is important to note that when chunks are introduced in an htML-webpack-plugin instance, the corresponding modules need to be added.

new HtmlWebpackPlugin({
    filename: '. /.. /.. /server/views/pagea.html'.chunks: ['vue'.'tui-chart'.'pagea'].template: path.resolve(__dirname , './client/template.html')})Copy the code

The pagea.html above needs to introduce not only Pagea, but also Vue and Tui-chart in order to do so.

From the figure above, we can see that the js file size is still considerable.

MiniCssExtract Extract as external CSS

Speaking of JavaScript volume splitting, there is also a problem with CSS. That is, I didn’t do it with the link tag in the demo above. This is going to solve the problem.

Webpack4 + provides a new module called MiniCssExtract. This module can handle the problems introduced by the.CSS external chain.

First configure in rules:

{
  test: /\.s? [ac]ss$/./ / postcss - loader depend on postcss - config. Js
  use: [MiniCssExtractPlugin.loader,'css-loader'.'postcss-loader'.'sass-loader']}Copy the code

Mainly to the original style – loader replace MiniCssExtractPlugin. Loader. If you need to differentiate the environment, you can do different introductions.

Then you need to introduce plugins as follows:

new MiniCssExtractPlugin({ // Extract as external CSS code
    filename:'[name].css? v=[contenthash]'
})
Copy the code

When it’s all done. Execute related commands.

As you can see, the generated HTML file successfully imports the required files.

Was it successful? Haha…

Check it out !!!!!! Be sure to check…

Demo Details Address –>> Multi-entry optimization example

conclusion

In general, the webpack4+ build doesn’t differ much from the other versions, except for the use of modules. But for me, it solved the multi-entry build problem I was struggling with. But this is also a demo, not a complete build. There are a lot of things missing, but the foundation is there, so you can build on it and optimize to get to the build configuration you want.

Finally, there is a question, that is, all the generated files packaged into the version library?

Here I give the so-called answer in this article: Pony’s Big front end road — a Preliminary exploration of Node.js