1 Features of Webpack

Images from the Internet

Webpack is a powerful packaging tool. In Webpack everything is modular. The Banner image on the Webpack website perfectly illustrates this concept. Webpack recursively analyzes module dependencies, starting with an entry file, and packages these modules into one or more files based on their dependencies.

Almost all front-end construction and development today uses Webpack. Because Webpack has a strong community ecosystem, Webpack is downloaded more than a million times a month. Loader and Plugin support Webpack to integrate with mainstream front-end frameworks and languages, such as Vue, React and TypeScript.

  • Support all modularity ES6 modules, CommonJS modules, AMD modules and other standard modules can be packaged.
  • Code Splitting can be divided into multiple chunks and loaded on demand, which means that our site does not need to wait for the complete download of the whole JS resource to interact, which can greatly improve the speed.
  • Powerful and flexible plug-in system Webpack provides many built-in plug-ins, including its own architecture on the plug-in system can meet all packaging needs.
  • Loader Uses loader to preprocess non-JS resources. Webpack can package all static resources.

2 Webpack construction process

The Webpack build process is an event flow mechanism. The entire build process can be viewed as an assembly line, with each step responsible for a single task and then moving on to the next step. Webpack publishes events at each stage, giving built-in and custom plug-ins the opportunity to intervene in the Webpack build process and control the results of the Webpack build. The basic build flowchart for Webpack is as follows:

  • Initialize theRead the parameters in the Webpack configuration file and shell script, merge the parameters, initialize the Webpack, and generateCompilerObject.
  • Begin to compileperformCompilerThe run method of the
  • Start from the entry file, call the Loader in the configuration to compile modules and sort out the dependencies between modules until all modules are compiled.
  • Resource outputBased on the dependencies between the entry and the module, the contents of the previous compilation are assembled into one by onechunk(code block), and then thechunkAdds to the list of resources waiting for output.
  • After determining output resources, write the resources to the file system of the disk based on the specified output path and file name.

3 Core Concepts

The entrance

Entrance is the starting point of Webpack construction. Webpack starts from the entrance file in the construction process, compiles modules recursively, and analyzes the dependency relationship between modules, and finally obtains the dependency graph. Webpack assembles modules from this dependency diagram and outputs them to the final bundle file.

The Entry property can be configured in the Webpack configuration file to specify entry files, which can be one or more.

Let’s look at an example:

// Webpack .config.js
module.exports = {
  entry: './src/app.js'
};
Copy the code

Scenarios with multiple entry configurations are common in multi-page applications. If more than one entry can be configured like this:

// Webpack .config.js
module.exports = {
  entry: {
    pageOne: './src/pageOne/app.js',
    pageTwo: './src/pageTwo/app.js'}};Copy the code
The output

Configuring the Output option instructs Webpack how and where to print our static resource files.

Let’s see how output is used with an example:

// Webpack .config.js
module.exports = {
  output: {
    filename: 'bundle.js',
    path: './dist'}};Copy the code

In the example above, we indicate that the final output file of Webpack is called bundle.js and the output directory is./dist.

loader

The use of the loader

Webpack itself cannot handle non-JS resources, but we can introduce CSS, images, fonts and other non-JS files into Webpack. Such as:

// app.js
import Styles from './styles.css';
Copy the code

So how does Webpack work?

Loader is used in Webpack to convert non-JS files. Loader can preprocess files when we import or load modules to convert non-JS file contents into JS codes.

Loader can be used in three ways:

  • The configuration is specified in the webpack.config.js file
  • inlineAt the end of eachimportStatement specified on the line
  • CLI is specified in shell commands.

In practical applications, most of them are used by configuration. On the one hand, you can intuitively see what loader is used by a certain type of file in the configuration file. On the other hand, it is convenient for maintenance in the case of complex projects.

Let’s take a look at the use of loader with a simple example:

// Webpack .config.js
module.exports = {
 module: {
    rules: [
      { test: /\.css$/, use: 'css-loader'}}};Copy the code

We need to tell Webpack to use CSS-Loader to preprocess CSS files when they are encountered. Since CSS-Loader is an independent NPM module, we need to install it before using it:

npm install --save-dev css-loader
Copy the code

The commonly used loader

Webpack can handle any non-JS language, and thanks to the rich loaders provided by the community, the loaders used in daily development can be found in the community. Some common Loaders are briefly described here.

  • Babel-loader translates ES2015+ code to ES5.
  • Ts-loader translates TypeScript code into ES5.
  • css-loaderparsing@importurl()And resolves the dependency of the reference.
  • style-loaderInject in HTML<style>The tag adds CSS to the DOM. Usually withcss-loaderUse in combination.
  • Sass-loader loads sASS/SCSS files and compiles them to CSS.
  • Postcss-loader Loads and translates CSS files using postCSS.
  • Html-loader exports HTML as a string.
  • Vue-loader loads and translates VUE components.
  • url-loaderfile-loaderSame, but can be returned if the file is smaller than the configured limitdata URL.
  • File-loader retrieves the file to the output directory and returns the relative path.
plugin

Use of plug-ins

Plug-ins are a very important feature of Webpack, and Webpack itself is built on top of the plug-in system. The plug-in mechanism greatly enhances Webpack’s capabilities and adds enough flexibility to Webpack. With plug-ins, we can introduce our own actions during the Webpack build process and interfere with the build results.

Let’s look at the use of plug-ins with an example:

// Webpack .config.js
const HtmlWebpack Plugin = require('html-Webpack -plugin');
const Webpack  = require('Webpack ');

const config = {
  plugins: [
    new Webpack .optimize.UglifyJsPlugin(),
    new HtmlWebpack Plugin({template: './src/index.html'}})]; module.exports = config;Copy the code

In the example, we use two plug-ins, one is the built-in UglifyJsPlugin plug-in, which compresses JS to reduce the size of files. One is the HtmlWebpack Plugin, an external plug-in that automatically generates entry files and injects the latest resources into HTML.

Common plug-ins

  • The HtmlWebpack Plugin automatically generates entry files and injects the latest resources into HTML.
  • The CommonsChunkPlugin is used to create a separate file and is often used to extract common modules from multiple modules.
  • DefinePlugin is used to define global constants to be used at compile time.
  • DllPlugin splits bundles to reduce unnecessary builds.
  • The ExtractTextWebpack Plugin extracts text from the bundle into a separate file. A common scenario is to extract CSS from bundles into separate CSS files.
  • HotModuleReplacementPlugin in running process to replace, add or remove modules, without having to reload the entire page.
  • UglifyjsWebpack Plugin compresses JS to reduce the size of files.
  • The CopyWebpack Plugin copies individual files or entire directories to the build directory. A common scenario is to copy still images from a project directly to the built directory without a build.

4 How to use Webpack

Let’s take a look at using Webpack with a simple example. It is assumed that you have installed the latest version of NodeJS and NPM, as you may encounter various problems with older versions.

4.1 installation

Create webpack-demo directory, initialize NPM, and install Webpack and webpack-CLI in webpack-demo directory:

mkdir Webpack -demo && cd Webpack -demo
npm init -y
npm install Webpack  Webpack -cli --save-dev
Copy the code

Webpack-cli Runs Webpack on the CLI. A local installation of Webpack and webpack-CLI is recommended, since the Webpack upgrade will affect all projects with a global installation.

Next we will add some new directories and files to the project:

├─ ├─ SRC ├─ ├.txt ├─ ├.txtCopy the code

Index.html reads as follows:

<! doctype html> <html> <head> <title>Webpack -demo</title> </head> <body> <script src="./src/index.js"></script>
  </body>
</html>
Copy the code

SRC /index.js contains the following contents:

function createEl() {
  var element = document.createElement('div')
  element.innerHTML = 'hello world'

  return element;
}

document.body.appendChild(createEl());
Copy the code

4.2 First Build

Run from the command line:

./node_modules/. Bin /Webpack Hash: 2353b0d3d427eAA8a18A Version: Webpack 4.29.6 Time: 175ms Built at: 2019-04-03 22:08:36 Asset Size Chunks Chunk Names main.js 1 KiB 0 [emitted] main Entrypoint main = main.js [0] ./src/index.js 175 bytes {0} [built]Copy the code

As you can see, we didn’t specify the packaged entry and output exit in the configuration file, nor did we specify configuration parameters on the command line, but we added main.js to the./dist directory. This is because the default entry value in the Webpack configuration is./ SRC and the default exit directory is./dist.

Webpack - demo ├ ─ ─ package. Json ├ ─ ─ dist | └ ─ ─ the main, js ├ ─ ─ index. The HTML └ ─ ─ the SRC └ ─ ─ index, jsCopy the code

Main.js is added to the project directory after the build.

<! doctype html> <html> <head> <title>Webpack -demo</title> </head> <body> <script src="./dist/main.js"></script>
  </body>
</html>
Copy the code

We will now change the script reference in index.html to the built file./dist/main.js. Preview in the browser and if everything is ok you should see the text Hello World printed on the page.

4.3 Using a Configuration File

For simple builds, Webpack can do almost zero configuration. However, for complex single-page applications, Webpack configuration files are needed to provide personalized functionality.

First we add webpack.config.js to the project root directory:

// Webpack .config.js
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')}};Copy the code

In the configuration file, the entry file is specified as./ SRC /index.js, the output directory is specified as./dist, and the output file is named bundle.js. The directory structure is updated as follows:

Webpack - demo ├ ─ ─ package. Json ├ ─ ─ Webpack. Config. Js ├ ─ ─ index. The HTML ├ ─ ─ dist | └ ─ ─ bundle. Js └ ─ ─ the SRC └ ─ ─ index, jsCopy the code

Json file to call./node_modules/.bin/Webpack.

// package.json
{
  "scripts": {
    "build": "Webpack "}}Copy the code

Execute the build command again:

NPM run build > Webpack [email protected] build C: work\tech\ webpack-demo > Webpack Hash: d0fa6b1e011af414e622 Version: Webpack 4.29.6 Time: 157ms Built at: 2019-04-03 22:42:50 Asset Size Chunks Chunk Names bundle.js 1 KiB 0 [emitted] main Entrypoint main = bundle.js [0] ./src/index.js 175 bytes {0} [built]Copy the code

Change the script reference link in index.html to./dist/bundle.js, preview the page in your browser, and, unsurprisingly, output hello World.

4.4 Using Plug-ins

We found that in the process of construction, if the name of the resource changed after construction, the reference to the resource in index.html would be changed passively, which was very inconvenient. We introduced HtmlWebpack Plugin to help us automatically generate the entry file. Automatically injects the generated resource file into index.html.

Installation:

npm install --save-dev html-Webpack -plugin
Copy the code

Configuration:

const path = require("path");
const HtmlWebpack Plugin = require("html-Webpack -plugin");
module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist")
  },
  plugins: [new HtmlWebpack Plugin()]
};

Copy the code

In the configuration file, we import the plug-in, and in the Plugins option, we instantiate the plug-in and add it to the array. The plugin automatically generates index.html, so the index.html file in the original directory can be deleted.

Webpack - demo ├ ─ ─ package. Json ├ ─ ─ Webpack. Config. Js ├ ─ ─ dist | └ ─ ─ bundle. Js └ ─ ─ the SRC └ ─ ─ index, jsCopy the code

Execute the build command again:

$NPM run build > Webpack [email protected] build C: work tech webpack-demo > Webpack Hash: 39dc7567ef99a69140e7 Version: Webpack 4.29.6 Time: 1241ms Built at: 2019-04-03 22:53:44 Asset Size Chunks Chunk Names bundle.js 1 KiB 0 [emitted] main index.html 182 bytes [emitted] Entrypoint main = bundle.js [0] ./src/index.js 175 bytes {0} [built]Copy the code

After executing the command, we found that we had an extra index.html file under./dist. And resource references in index.html are automatically updated to .

4.5 Using loader to Process CSS Files

In order for Webpack to handle imported CSS files, we need to install and configure style-loader and CSS-loader.

npm install --save-dev style-loader css-loader
Copy the code

Modify the Webpack configuration as follows:

const path = require("path");
const HtmlWebpack Plugin = require("html-Webpack -plugin");
module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist")
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader"."css-loader"]
      }
    ]
  },
  plugins: [new HtmlWebpack Plugin()]
};

Copy the code

In this way, when Webpack matches files with a.css suffix, csS-loader and style-loader are used.

Next we will add a new style file main.css in the./ SRC directory. In style, set the font color of the text to red.

// main.css
div{color: red}
Copy the code

Then we reference main.css in. / SRC /index.js:

import "./main.css";

function createEl() {
  var element = document.createElement("div");
  element.innerHTML = "hello world";

  return element;
}

document.body.appendChild(createEl());
Copy the code

Execute build commands:

$NPM run build > Webpack [email protected] build C: work/tech/webpack-demo > Webpack Hash: f9fcb8cfd689f4b96ce6 Version: Webpack 4.29.6 Time: 2672ms Built at: 23:24:40 2019-04-03 Asset Size Chunks Chunk Names bundle. Js 6.85 KiB 0 [emitted] main index. The HTML 182 bytes (emitted) Entrypoint main = bundle.js [0]./ SRC /index.js 199 Bytes {0} [built] [1]./ SRC /main.css 1.05kib {0} [built] [2] ./node_modules/css-loader/dist/cjs.js! ./src/main.css 170 bytes {0} [built] + 3 hidden modulesCopy the code

In the browser preview, unsurprisingly, the font color has changed to red. Open the browser debugging tool and you can see that a

<style type="text/css">
  div {
    color: red;
  }
</style>
Copy the code

Through the complete example above, we demonstrated the use of several configurations of the core of Webpack, we should have a basic understanding of the use of Webpack.

There are many other useful configuration items in Webpack that I don’t have space to cover in detail. You can consult the official documentation to configure and practice.

conclusion

This section gives you an overview of Webpack. With loader, Webpack can handle all resources, JS, non-JS, can. With plug-ins, we can influence the Webpack build by adding its own behavior to each event node during the Webpack build process. Understanding the use of Webpack can provide a foundation for us to build the basic framework of the project.

The author has just launched a practical course of front-end engineering — Perspective of Front-end Engineering.

Click on Perspective Front-end Engineering.

Taking Vue as an example, combined with the author’s engineering practice in the team, I led everyone to build a scaffold from scratch and dismantle the technical points used in building the scaffold one by one. I hope that after watching the scaffold, everyone will have a deeper understanding of scaffolding and engineering ideas.

I believe that after learning this course, you will at least learn the following:

  • Have a systematic knowledge of front-end engineering;
  • Able to independently design a set of front-end engineering solutions;
  • The breadth of knowledge has been greatly improved;
  • Access to better platforms, better pay.

If you are interested, we hope you can support us!


About the author:

Wang Chao, the current kuaigou Taxi (the former 58 express) head of the front.

He has worked in Renren and Qihoo 360 successively and has 8 years of well-known Internet working experience.

Established the kuaigou front-end team from 0 to 1, was responsible for the construction of the technical system of the team, and formed an automatic, engineering and component-based kuaigou front-end technical system based on Webpack and Vue and supplemented by node.js intermediate layer.