“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

Preface 🎨

As we all know, as front-end engineering becomes more and more complex, modular packaging tools are playing an increasingly important role in our daily development, and WebPack is already the front-end packaging build of choice.

When it comes to WebPack, many of you may feel both familiar and unfamiliar, familiar because we use it in every project we develop. What is strange is that WebPack has complex configurations and a wide variety of features.

As a result, we are sometimes intimidated by the complexity of the configuration and discouraged from studying.

However, in an environment where technology is changing so quickly, WebPack is worth learning from.

In the following article, we’ll cover the core concepts for getting started with WebPack. Let’s learn ~🎬

📅 what is Webpack

1, in front

When we’re writing a web page, we’re going to first create an index. HTML file, and then we’re going to have some js files, so we’re going to introduce those JS files into the HTML file.

Imagine if there were a lot of js files, and we introduced them one by one, so what if we got an error? Would it be difficult to locate which file is wrong, which would make development very inefficient?

Hence Webpack. Webpack will take the code we write, do a translation, and the translated content, do a modular packaging, making the project engineering.

Next, let’s look at what WebPack is and how to install and use it.

2. What is a module packaging tool?

Webpack is sometimes mistaken for a JS translator, but webPack is not really a JS translator.

Because it only knows about statements like import, it doesn’t know any other advanced JS syntax. So if we call it a JS translator, we’re actually overestimating it.

Looking at the official definition, we can see that WebPack is a module packaging tool, and WebPack can also support commonJS module packaging specifications.

However, with the passage of time and the continuous update of technology, WebPack is no longer just a module packaging tool that can package JS, WebPack now also supports the packaging of CSS files, JPG, PNG and other files.

📐 2. How to build an environment with Webpack

1. Install node

Webpack is a module packaging tool developed based on NodeJS, which is essentially implemented by Node. So we need to install the local Node environment first. Here is a link to the official website. I suggest you download the stable version

Then check whether the node and NPM versions are successfully installed.

node -v
npm -v
Copy the code

Create the project

Start by creating a project, let’s say named Webpack-demo. Then create a folder under this item with the following command:

mkdir webpack-demo
Copy the code

3. Initialize the project

Go to the webpack-demo file and initialize the project. The command line is as follows:

cdWebpack-demo NPM init or NPM init -y // Add -y to the default automatic configuration itemCopy the code

After all Enter Enter.

You can see the structure of the project. The above operation is to create a package.json file under the webpack-demo file, and then we transform the package.json file. The specific code is as follows:

{
  "name": "webpack-demo"."version": "1.0.0"."description": "".// Make this project private
  "private":true.//"main": "index.js", // remove the entry file
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  // Write the author name
  "author": "Monday".// Keep the project private
  "license": "ISC"
}

Copy the code

Install WebPack

The first method: global installation

npm install webpack webpack-cli -g
Copy the code

The second way: install under the current project

npm install webpack webpack-cli -D
Copy the code

The recommendation here is to choose the second method for installation. So why? Is there something wrong with installing WebPack globally?

In fact, a global install installs only one version.

So if we are running two projects, and the two projects have different versions of WebPack installed, the project that installed the earlier version of WebPack may not work on our machine. Therefore, it is recommended to use the second method for installation.


After the installation is complete, we will also query the current WebPack version number to ensure that we have successfully installed it. The command line is as follows:

npx webpack -v
Copy the code

At this time, some friends will have a question, why do you need to add a NPX to find the version number.

The reason is that we are only installing in the current project, so the webpack command is not found globally. When node provides NPX, NPX will find the webPack installation package in the nodless module of the project where we are running, so this way we install our WebPack in our project. Then run webpack via NPX.

Install the specific version of WebPack

If we want to install a specific version of WebPack, we first look at the webPack version information. The command is as follows:

npm info webpack
Copy the code

After finding the specific version number, run the following command to install it:

NPM install [email protected] webpack-cli -d //4.16.5 indicates the versionCopy the code

⚙️ 3. Webpack configuration file

1. Default configuration file

Most of the time, we don’t even write the configuration file, and the project runs successfully. This is not because there is no need to write, but the Webpack team has written many default configuration files for us in advance, so that we can run the project without much configuration to meet our needs. Now, let’s write a configuration file.

Let’s start by looking at the project structure. When we create a project, our source code is usually in the SRC folder, the packaged files are usually in the dist file, and the webPack configuration file is named webpack.config.js and is placed in the root directory of the project.

├ ─ ─ dist placed after packaging file ├ ─ ─ the SRC placed project source code ├ ─ ─ webpack. Config. Js webpack configuration file ├ ─ ─ package - lock. Json ├ ─ ─ package. The jsonCopy the code

After looking at the project structure, let’s take a look at how webPack configuration files need to be configured. The specific code is as follows:

// Core module of node
const path = require('path');

module.exports = {
    // When set to development, code will not be compressed; When set to Production, the code is compressed.
    mode:'production'.// Put the entry file, specify how to package, which file to package
	entry: './src/index.js'.//entry: {
    // main: './src/index.js'
    / /},
	// Output, indicating how and where webPack should be output
	output: {
		filename: 'bundle.js'.// Which file to put the packaged file under
        // __dirname indicates the root directory of the project
		path: path.resolve(__dirname, 'dist')}}Copy the code

The webpack configuration file must be named webpack.config.js, or can it be named something else?

The answer is yes, but we need a special treatment. Normally, if we name it webpack.config.js, we can use NPM Webpack to run our project directly. Instead of naming it webPackConfig.js, we can package our specific project using the following command line.

 npx webpack --config webpackconfig.js 
Copy the code

The command line above means: let webpack pack for us, which file to pack? Use webPackConfig.js as the configuration file to help us package.

Use NPM Script to simplify our packaging code

After reading the above content, I believe that friends have a basic understanding of Webpack.

Don’t you think it would be a bit cumbersome to use NPX WebPack to pack your files?

So, let’s look at one more thing: using NPM Script to simplify our packaging code.

In our project root directory, we will have a package.json file with the following code:

{
  "name": "webpack-demo"."version": "1.0.0"."description": ""."private": true."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Monday"."license": "ISC"."devDependencies": {
    "webpack": "^ 5.39.1"."webpack-cli": "^ 4.7.2." "}}Copy the code

I’m going to go to the scripts section, and then I’m going to make a change to the Script section. The specific code is as follows:

 "scripts": {
    /* Webpack is packaged under node_module */
    "bundle": "webpack"
  },
Copy the code

After that, we have configured an NPM script in package.json, which is called bundle. After that, the bundle layer will help us execute webpack and package.

After writing this, we no longer need to use NPX Webpack to run Webpack, but use NPM run bundle to do the command packaging.

3. Talking about WebPack packaging output

With that said, let’s summarize some of the output of the console after webPack packaging.

output Specific meaning
hash Represents the unique hash value of this package
version Represents the version of WebPack used in this package
time How long it took the current project to complete the package
assets Which file is the bundle, such as bundle.js
size Size of the packaged file
chunks Place the ID value of the corresponding file and the ID value of other files imported by the corresponding file
chunk Names Main corresponding to the entry configuration

Four, the Loader 🔑

1. Introduction

By default, Webpack knows how to package JS modules, but it doesn’t know how to package JPG files.

In this case, we need to configure the webpack.config.js file to configure the file-loader. We added a new module to the configuration. The specific code is as follows:

module: {rules: [{test:/\.jpg$/,
        use:{
            loader:'file-loader'}}}]Copy the code

Let’s take a forward look at how WebPack packages static files like JPG.

First the webpack will go to the SRC directory, new an index.js file, so now we will package this file.

So, I’m running NPM run bundle on the command line. When you run NPM run bundle, you’re actually executing the script in package.json, which helps you run Webpack, and webpack does the packaging. At this point, WebPack will find its corresponding configuration and help us package according to this configuration.

So let’s see, if we’re dealing with a JS file, webPack will pack by default. But? What if it’s a JPG? Webpack was at a loss. Webpack didn’t know JPG code.

Therefore, we can refer to a module module to help us package. This module is called file-Loader, and file-loader is the loader that helps us complete the packaging process.

So what does the underlying file-loader actually do for us?

When we package the JPG file, Webpack moves the JPG file under the dist file and gives the JPG file a new name. It then returns the name as a return value to the variable we introduced into the module.

This is a process of file- Loader.

Of course. File-loader can handle more than file images such as JPG. In theory, it can also handle many types of static resources.

2. What is Loader

After describing file-loader, I believe you have a basic understanding of Loader. Now let’s go through the basic definitions of loader. The details are as follows:

Webpack itself does not know what to do with some files, but Loader does. Therefore, when you encounter some non-JS files, you usually turn to the Loader. So we need to ask WebPack to refer to the Loader module to identify non-JS files.

Webpack only understands JavaScript and JSON files, which are available out of the box. Loader enables WebPack to process other types of files and convert them into valid modules for use by applications and to be added to the dependency graph. Essentially, a Loader is a JavaScript module that is exported as a function.

3. Use Loader to package static resources

(1) Custom named image

What if we now want to custom name the packaged image?

We will improve the module in webpack.config.js. The specific code is as follows:

module: {rules: [{test:/\.jpg$/,
        use:{
            loader:'file-loader'.options: {
                / / placeholder placeholder
                name: '[name]_[hash].[ext]'}}}}]Copy the code

By configuring options, you can achieve the effect of custom image naming.

(2) Package various types of picture files

Let’s say we’re not limited to packaging JPG files, but we want to package other image files as well. So we can configure it like this:

module: {rules: [{test:/\.(jpg|png|gif)$/,
        use:{
            loader:'file-loader'.options: {
                / / placeholder placeholder
                name: '[name]_[hash].[ext]'}}}}]Copy the code

Use regular expressions to add new image types.

(3) Package it to the image file

Suppose we now want to put the packaged file under the image file. What should we do? The specific code is as follows:

module: {rules: [{test:/\.(jpg|png|gif)$/,
        use:{
            loader:'file-loader'.options: {
                / / placeholder placeholder
                name: '[name]_[hash].[ext]'.// Assign JPG, PNG, and GIF images to the images file in the dist directory
                outputPath: 'images/'}}}}]Copy the code

(4) url – loader

After using file-loader, let’s look at another knowledge: URl-loader. Url-loader can be almost as effective as file-loader. The specific use method is as follows:

npm i url-loader -D
Copy the code
module: {rules: [{test:/\.(jpg|png|gif)$/,
        use:{
            loader:'url-loader'.options: {
                name: '[name]_[hash].[ext]'.outputPath: 'images/'}}}}]Copy the code

We just need to install url-Loader and replace file-loader with URl-loader in the configuration.

It is worth noting, however, that there are some caveat to using urL-Loader for packaging.

When you package a JPG file, unlike file-Loader, url-Loader converts the image to a Base64 string and puts it directly into bundle.js in our dist directory, rather than generating a separate image file.

The advantage is that you can access it directly instead of going to the folder, saving an HTTP request.

The downside is that if the JS file is very large, then the generated JS file will also be very large, and it will take a long time to load the JS file.

So, what is the best way to use url-Loader?

If the image we introduced is small, only 1~2KB in size, then it is a good choice to package the image in BASE64 form in JS file, there is no need to send the HTTP request again for such a small image.

If the image is large, use file-loader instead of URl-loader, and package the image into the dist directory, not bundle.js. Otherwise, the bundle.js file will become very large, making the load time very long and not good for maintenance.

Alternatively, we can add limit directly to the URL -loader. The specific code is as follows:

module: {rules: [{test:/\.(jpg|png|gif)$/,
        use:{
            loader:'url-loader'.options: {
                name: '[name]_[hash].[ext]'.outputPath: 'images/'.//20480=>20KB
                limit: 20480}}}}]Copy the code

As we can see from the above code, when using url-loader, we can add a limit attribute to it. If the image file size is larger than 20KB, we use url-Loader to package it. When it is larger than 20KB, place the image file under the images file dist.

4. Use Loader to package static resources (styles)

(1) Package CSS files

For example, if we now want an image to be 150 by 150, we need to modify the image by writing down the style. So how does WebPack package CSS files?

We can use csS-Loader and style-Loader to package files. The configuration is as follows:

npm install sass-loader node-sass --save-dev
Copy the code
module: {rules: [{test:/\.(jpg|png|gif)$/,
        use:{
            loader:'file-loader'.options: {
                / / placeholder placeholder
                name: '[name]_[hash].[ext]'.outputPath: 'images/'}}}, {test:/\.css$/,
        use:['style-loader'.'css-loader']]}}Copy the code

Css-loader will help us figure out the relationships between the CSS files, and eventually merge one CSS file into one CSS. So what’s the role of the style-loader?

After obtaining the CSS file generated by the CSS-Loader, the style-Loader will mount the content to the head section of the page and mount the style to

in the head.

(2) Package the sass file

If you want to package a sass file, you can use the following three loaders: sass-Loader, style-Loader, and CSs-Loader. The configuration is as follows:

npm install sass-loader node-sass --save-dev
Copy the code
module: {rules: [{test:/\.(jpg|png|gif)$/,
        use:{
            loader:'file-loader'.options: {
                / / placeholder placeholder
                name: '[name]_[hash].[ext]'.outputPath: 'images/'}}}, {test:/\.scss$/,
        use:[
            'style-loader'.'css-loader'.'sass-loader']]}}Copy the code

It is worth noting that loaders are executed from bottom to top and from right to left.

So when we execute a sass file, we first execute sass-loader, then css-loader, and then style-loader.

(3) Compatibility problems

Sometimes if we want to be compatible with multiple browsers, we might add a vendor prefix such as -webkit- to CSS files. However, webPack does not recognize these prefixes. At this time we learned about a new loader, postcsS-Loader, which can automatically add vendor prefix information for us. The specific use mode is as follows:

Postcss-loader: postcss-loader: postcss-loader: postCSs-loader

npm i postcss-loader -D
Copy the code

After the installation is complete, we create a new file in the project root directory called postcss.config.js and configure the file as follows:

First install autopreFixer:

npm install autoprefixer -D
Copy the code

After the installation is complete, we can now use it in the postcss.config.js file as follows:

module.exports = {
    Plugin: [require('autoprefixer')]}Copy the code

Next we use postcss-Loader under the webpack.config.js file. The specific code is as follows:

module: {rules: [{test:/\.(jpg|png|gif)$/,
        use:{
            loader:'file-loader'.options: {
                / / placeholder placeholder
                name: '[name]_[hash].[ext]'.outputPath: 'images/'}}}, {test:/\.scss$/,
        use:[
            'style-loader'.'css-loader'.'sass-loader'.'postcss-loader']]}}Copy the code

In this way, WebPack can prefix the styles that need to be prefixed by vendors when packaging our static files.

5. Add configuration items

Let’s say we want to add a configuration item to one of the loaders. For example, if we want to add a configuration item to csS-Loader, we can do the following to the code. The specific code is as follows:

module: {rules: [{test:/\.(jpg|png|gif)$/,
        use:{
            loader:'file-loader'.options: {
                / / placeholder placeholder
                name: '[name]_[hash].[ext]'.outputPath: 'images/'}}}, {test:/\.scss$/,
        use:[
            'style-loader', 
            {
                loader: 'css-loader'.options: {
                    // Postcss-loader and sass-loader must be used first
                    importLoaders: 2}},'sass-loader'.'postcss-loader']]}}Copy the code

As you can see from the code above, when we want to add configuration items to the CSS-Loader, instead of using the string form, we convert the string to an object. In the object, we fill in the corresponding loader and options configuration, so that we have the desired requirements.


Sometimes, if we introduce CSS globally on a single page, it can easily lead to style conflicts. So how do you deal with that?

To achieve this, we can use the modules in CSS-Loader to realize the modularity of CSS, aiming to let the CSS file has its own module. How do you use it?

module: {test:/\.scss$/,
        use:[
            'style-loader', 
            {
                loader: 'css-loader'.options: {
                    // Postcss-loader and sass-loader must be used first
                    importLoaders: 2.modules: true}},'sass-loader'.'postcss-loader']]}}Copy the code

As you can see from the code above, you can turn on the modularized packaging of CSS with the modules:true statement. Once opened, we can import it under various files. The introduction method is as follows:

import style from './index.scss';

var img = new Image(); 
img.src = bug;
img.classList.add(style.bug);
Copy the code

As you can see from the code above, when you enable the Module, you can reference the CSS as much as you want.

How to use WebPack to package font files

There are times when you want to introduce fonts into a project, so how does WebPack package fonts? The specific code is as follows:

module: {rules: [{test: /\.(eot|ttf|svg)$/,
			use: {
				loader: 'file-loader',}}},Copy the code

As we can see from the above code, the static file formats associated with WebPack are EOT, TTF, and SVG, so we need to introduce these types. In addition, the related loader is file-loader.

After learning how to package static resources, it is recommended to review the relevant sections of the official documentation

🧲 Use plugins to make packing more portable

1, HTML – webpack – the plugin

Now that you’ve learned how to use a Loader to package static files, let’s take a look at how plugins can be used to make packaging easier in WebPack.

When we package a project, WebPack always places the packaged content in the dist directory. At this point we may need to create an index. HTML to import the core file. Doesn’t that make it a little tricky?

Therefore, WebPack gives us plugins to solve this problem.

To install the plugin, run the following command:

npm install html-webpack-plugin -D
Copy the code

Next, we will introduce the plug-in into webpack.config.js. The specific code is as follows:

const HtmlWebpackPlugin = require('html-webpack-plugin');

plugins: [new HtmlWebpackPlugin({
		// Specify which template to reference
		template: 'src/index.html'
	})]
Copy the code

Now let’s take a look at how htmlWebpackPlugin helps us do this automatically.

First, htmlWebpackPlugin automatically generates an HTML file after packaging. After that, the js file generated by the package is automatically imported into the HTML file.

So, in a way, the plugin can automatically do something for you when WebPack is running at a certain point. As soon as we finish packing, the Plugin will automatically create an HTML file for us to use directly.

2, the clean – webpack – the plugin

Sometimes it is possible to modify the filename corresponding to the output in webpack.config.js, which can easily lead to multiple file conflicts during the packaging process.

So what we want to do is, when we package, we empty the original dist folder, and then we regenerate it into a new dist folder. How to deal with it? See below.

Install the clean-webpack-plugin plugin to install the clean-webpack-plugin plugin.

npm install clean-webpack-plugin -D
Copy the code

Next, we will introduce the plug-in into webpack.config.js. The specific code is as follows:

const CleanWebpackPlugin = require('clean-webpack-plugin');

plugins: [new HtmlWebpackPlugin({
		// Specify which template to reference
		template: 'src/index.html'
	}),new CleanWebpackPlugin(['dist']]Copy the code

With the above code, we can delete the dist folder when our project is packaged and create a new folder later.

🗞️ VI. Entry and Output

Next, let’s look at some of the more core configurations of Entry and Output in WebPack.

module.exports = {
	mode:'development'.// Put the entry file, specify how to package
	entry: {main: './src/index.js'.sub: './src/index.js'
	},
	plugins: [new HtmlWebpackPlugin({
		// Specify which template to reference
		template: 'src/index.html'
	}),new CleanWebpackPlugin(['dist'])],
	// Output, indicating how WebPack should output
	output: {
		// If the resource is placed under the CDN, the CDN is introduced
		publicPath: 'http://cdn.com.cn'.// When there are multiple entry files, you can output multiple files using []
		filename: '[name].js'.// Which file to put the packaged file under
		path: path.resolve(__dirname, 'dist')}}Copy the code

Seven, SourceMap 🗺 ️

1. Introduction

Sometimes, when we’re writing code, we get bugs. Looking at the console that red error, the heart is always very not taste. At the same time, if we don’t configure WebPack well, it’s pretty scary to find errors.

For example, in development mode, our default webpack.config.js configuration looks like this:

module.exports = {
	mode:'development'.devtool: 'none'.entry: {// Package into main.js in dist directory
		main: './src/index.js'
	},
    output: {
		// Use [] to generate multiple files
		filename: '[name].js'.// Which file to put the packaged file under
		path: path.resolve(__dirname, 'dist')}}Copy the code

And then, let’s say that we now mistakenly write console.log as consele.log in our code. So now the console print looks like this:

As you can see, the error is located at line 96 in the packaged main.js file. Just think, if we have a lot of business code, the error may be moving up in the file.

This is not what we want to see. What we want to do is we want webPack to throw the error at us when it’s packaged and show us the exact file location. This is the code file where we made the error, not the packaged main.js file.

Therefore, WebPack gives us the sourceMap configuration to solve this problem.

2, sourceMap

Let’s change the devtool configuration to sourceMap. The specific code is as follows:

module.exports = {
	mode:'development'.devtool: 'source-map'.entry: {// Package into main.js in dist directory
		main: './src/index.js'
	},
    output: {
		// Use [] to generate multiple files
		filename: '[name].js'.// Which file to put the packaged file under
		path: path.resolve(__dirname, 'dist')}}Copy the code

After that, let’s take a look at the console printout:

As you can see, when you change the source-map configuration, the error is located directly in the directory of our own code, namely index.js. Instead of looking for a needle in a haystack in main.js.

3. Common sourceMap configurations

After looking at the example above, I believe you have a good idea of SourceMap. Let’s look at some common configurations for sourceMap. Take a look below:

SourceMap meaning
inline-source-map When an error is reported, both rows and columns are displayed
cheap-inline-source-map When you report an error, you just know which row is wrong, but you don’t know which column is wrong
cheap-module-source-map Production environment best practices, not only manage their own business code errors, but also other errors, such as loader, other third-party module errors and so on
eval Eval is one of the fastest ways to package, but if you’re dealing with complex business code, you might not be able to use eval as a reminder
module-eval-source-map With module, it indicates that not only the business error should be displayed, but also loader, third-party error, and so on
cheap-module-eval-source-map Development environment best practices

🧱 8. Use WebpackDevServer to improve development efficiency

1, – watch

In fact, if we didn’t use the WebpackDevServer approach, we would need to compile the NPM run bundle command every time we want to see the compiled results. Then open the index. HTML file in the dist directory to view it again. In this way, it is hard to avoid low efficiency. What do we expect?

The script in the package.json file is modified as follows:

"scripts": {
    "watch": "webpack --watch"."bundle": "webpack"
  },
Copy the code

As you can see from the above code, by adding the –watch field to webpack and then running NPM run watch, you can automatically listen to webPack every time you change the code, instead of the usual, Re-run the command to package WebPack each time you change the code.

2, webpackDevServer

However, this approach may not be friendly enough, because developers are lazy, so let the program do the work rather than manual work.

In fact, what we want to achieve is that when we run NPM run watch, it will not only automatically package us, but also open the console and simulate some of the features on the server. Then we can use webpackDevServer to achieve what we want. How to use webpckDevServer? See below for details.

(1) Install webpackDevServer

We now install webpackDevServer in the project, the specific command line is as follows:

npm install webpack-dev-server -D
Copy the code

(2) Configure the package.json file

Next we’ll configure the script for the package.json file. The specific code is as follows:

"scripts": {
    "watch": "webpack --watch"."start": "webpack-dev-server"
  },
Copy the code

(3) Configure the WebPack file

The webpack.config.js file is configured with the following code:

module.exports = {
	mode:'development'.devtool: 'source-map'.// Put the entry file, specify how to package
	entry: {main: './src/index.js'
	},
	devServer: {
		contentBase: './dist'.// When NPM run start is finished, it automatically opens the browser for us
		open: true
	},
    output: {
		// Use [] to generate multiple files
		filename: '[name].js'.// Which file to put the packaged file under
		path: path.resolve(__dirname, 'dist')}}Copy the code

So now, let’s look at how webpackDevServer can automatically open the browser. See the following figure for details:

As you can see, with webpackDevServer, not only will it listen to changes in our files and repackage them for us. It also automatically refreshes the browser and automatically opens the browser for you. So using it can greatly improve the efficiency of our code development.

(4) Configure the port number

WebpackDevServer defaults our server to port 8080. What if we want to change it to something else?

We need to modify the DevServer in webpack.config.js file. The code is as follows:

module.exports = {
	mode:'development'.devtool: 'source-map'.// Put the entry file, specify how to package
	entry: {main: './src/index.js'
	},
	devServer: {
		contentBase: './dist'.// When NPM run start is finished, it automatically opens the browser for us
		open: true.// Change the port number
        port: 3000
	},
    output: {
		// Use [] to generate multiple files
		filename: '[name].js'.// Which file to put the packaged file under
		path: path.resolve(__dirname, 'dist')}}Copy the code

We only need to add a port configuration in the devServer to achieve custom port number.

It’s also worth noting that when we use webpackDevServer to package our project, it doesn’t automatically generate the dist directory, so why? Projects packaged with webpackDevServer will be stored in our computer memory, which in some ways can effectively improve the project packaging speed, make packaging faster.

🌡️ Hot Module Replacement Hot Module Replacement

1. Introduction

Suppose we now want to implement a new element function that adds a new text item every time the button is clicked. The specific implementation code is as follows:

Index. Js file:

import './style.css';

var btn = document.createElement('button');
btn.innerHTML = 'new';
document.body.appendChild(btn);

btn.onclick = function(){
    var div = document.createElement('div');
    div.innerHTML = 'item';
    document.body.appendChild(div);
}
Copy the code

Style. The CSS file:

div:nth-of-type(odd){
    background: yellow;
}
Copy the code

At this time, the display effect of the browser is as shown in the figure below:


Let’s say we now change the color of the CSS background to, say, purple. The specific code is as follows:

div:nth-of-type(odd){
    background: purple;
}
Copy the code

At this point, when we save, the browser will refresh, and then each item will be appended again. The diagram below:

That might not be the outcome we want in this case. What we want is for all items not to be refreshed, and for the corresponding item color to be changed when the CSS style is changed. This leads to a content in webpackDevServer: Hot Module Replacement. Let’s look at the configuration related to hot module updates.

2. Update the hot module configuration

Hot Module Replacement, or HMR for short, is Hot Module Replacement.

Next we do the configuration in the webpack.config.js folder. The specific code is as follows:

// Core module of node
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');

module.exports = {
	mode:'development'.devtool: 'source-map'.// Put the entry file, specify how to package
	entry: {main: './src/index.js'
	},
	devServer: {
		contentBase: './dist'.// When NPM run start is finished, it automatically opens the browser for us
		open: true.port: 8080.// Let our webpackDevServer enable hotModuleReplacement like this
		hot: true.// Do not let the browser refresh automatically even if the HMR does not take effect
		hotOnly: true
	},
	module: {rules: [{test:/\.(jpg|png|gif)$/,
			use:{
				loader:'file-loader'.options: {
					/ / placeholder placeholder
					name: '[name]_[hash].[ext]'.outputPath: 'images/'.limit: 10240}}}, {test:/\.scss$/,
			use:[
				'style-loader', 
				{
					loader: 'css-loader'.options: {
						// Postcss-loader and sass-loader must be used first
						importLoaders: 2.modules: true}},'sass-loader'.'postcss-loader'] {},test:/\.css$/,
			use:[
				'style-loader'.'css-loader'.'postcss-loader']]}},plugins: [new HtmlWebpackPlugin({
		// Specify which template to reference
		template: 'src/index.html'
	}),new CleanWebpackPlugin(['dist']),
		new webpack.HotModuleReplacementPlugin()
	],
	// Output, indicating how WebPack should output
	output: {
		// Download middle: NPM install express webpack-dev-middleware -d
		publicPath: '/'.// Use [] to generate multiple files
		filename: '[name].js'.// Which file to put the packaged file under
		path: path.resolve(__dirname, 'dist')}}Copy the code

Through the above code we can know, configuration devServer under hot and hotOnly, and the new webpack under plugins. HotModuleReplacementPlugin (), to achieve the effect of the thermal module updates.

Let’s take a look at what the browser looks like once you’ve configured it. See the following figure for details:

As you can see, with the addition of these configurations, the item will not be refreshed again, but will be styled from the original.

📀 USE Babel to handle ES6 syntax

1. Convert ES6 syntax to ES5 syntax

Moving on, let’s see how to use WebPack and Babel to write ES6 syntax.

As you know, ES6’s grammatical specifications were only officially published in 2015. So sometimes, not all browsers support ES6 syntax. So what we want to do now is to be able to convert ES6 syntax to ES5 syntax when webPack is packaged. This way, when the project runs, the browser will not report an error.

So how do you do this? Let’s find out.

First we opened Babel’s official website and followed the steps we took to use Babel in WebPack.

Step 1: Install the babel-Loader and @babel/core libraries. The specific code is as follows:

npm install --save-dev babel-loader @babel/core
Copy the code

Babel/Core is one of Babel’s core libraries. It allows Babel to identify the contents of js code and then convert the JS code into an AST abstract syntax tree. Then the abstract syntax tree is compiled into some new syntax.

Step 2: Add the rule in the configuration item under webpack.config.js file. The specific code is as follows:

module: {
    rules: [{test: /\.m? js$/,
            exclude: /node_modules/,
            use: {
                loader: "babel-loader".options: {
                    presets: ['@babel/preset-env']}}}]}Copy the code

Step 3: Install @babel/preset-env. The specific code is as follows:

npm install @babel/preset-env --save-dev
Copy the code

Why install this module? In fact, when we use Babel-Loader to process files, babel-Loader is really just a bridge between Webpack and Babel. It just helps us open a channel, but it doesn’t help us convert ES6 syntax to ES5 syntax. So, we need some other modules to do that. This module is what we talked about earlier, PRESET -env.

Babel /preset-env contains all the syntax rules for CONVERTING ES6 to ES5, and when packaged with this module, we can convert all of our JS ES6 code to ES5. For details, see Step 2.

2, Babel – polyfill

In this way, we can achieve the effect of translating ES6 syntax into ES5 syntax. However, one thing to consider is that new syntax variables such as promise, or functions such as map in arrays, are virtually nonexistent in earlier versions of browsers. Although we have done the grammar explanation and grammar translation, but only a part of the translation. There are also some objects and functions that are not available in earlier versions of browsers.

So, not only do we use Babel /preset-env for the syntax conversion, but we also need to add the missing variables and functions to the earlier version of the browser.

To supplement, we need to use the babel-polyfill tool to supplement. Next, I’ll show you how to use this module.

Step 1: Navigate to the official documentation and install Babel-Polyfill. The specific code is as follows:

npm install --save @babel/polyfill
Copy the code

Step 2: Introduce the module. The specific code is as follows:

import "@babel/polyfill";
Copy the code

Normally, this code is placed under the project’s JS entry file.

Step 3: Modify the module under webpack.cofig.js file to reduce the package size. The specific code is as follows:

module: {
    rules: [{test: /\.m? js$/,
            exclude: /node_modules/,
            use: {
                loader: "babel-loader".options: {
				presets: [['@babel/preset-env'] and {useBuiltIns: 'usage'}}}}}Copy the code

What this code means is that when babel-Polyfill is used to fill in the earlier browser features, instead of adding all the features, it is up to our business code to decide what to add.

Also, babel-Preset has many other configuration attributes worth learning about, which I won’t talk about here. You can go to the official document to view ~

📚 11. Conclusion

As I finished writing this article, I suddenly remembered the interviewer in my last interview. Asked about Webpack at the end of the rhetorical session, he said that WebPack is usually handled by employees who are familiar with the company’s business, since front-end engineering is no joke.

At that time, I did not have a lot of feelings, but now I learned here suddenly think of that scene. Indeed, I didn’t even get the tip of the iceberg before I felt the enormity of WebPack. If there is a problem in the configuration of a small area when packaging, it may cause the whole project to be out of control. (Of course, this is not the case in general, which is a strong word…)

As you learn WebPack, make sure you know which version of WebPack you are using. For example, Monday was a bit of a blur, and it felt like version 4 and Version 5 were pretty much the same. But for Webpack, it’s a complete joke. There are 4 and 5 versions for each dependency, not just one that you want to use. If the use of careless words, intangible may be reported wrong to doubt life…

Therefore, determine which version to use when using WebPack, and also find the corresponding version to use when using NPM dependencies to reduce the occurrence of errors.

So much for webPack’s ultra primer! Hope to help you ~

🐣 Easter Eggs One More Thing

Phase to recommend

  • Vuejs Basic knowledge series
  • Vuejs principle analysis series

Set pieces

  • Pay attention to the public number Monday research office, the first time to pay attention to learning dry goods, more selected columns for you to unlock ~
  • If this article is useful to you, make sure you leave footprints before you go
  • That’s all for this article! See you next time! 👋 👋 👋