Can’t you learn webpack? Look at this!

  babel, react.js, webpack

image

Webpack has been popular for a long time, but many students are still confused when using webpack. When they see so many documents, various configurations, various loader and plugin, they immediately become confused. I am no exception, so that I have known little about the webpack for a long time. However, in order to continue to do a good job in the front end, webpack is a hurdle that must be crossed. in fact, it is not difficult to master webpack, but we have not found the right method. This article is my own experience in learning webpack, for your reference.

What is webpack?

One sentence summary: webpack is aModule bundler. The focus is on the two key words “module” and “packaging”. What is a module? Let’s review the former front-end development method. js file passedscriptTags are introduced statically. js files do not have strong dependencies. If file 1 uses some methods or variables of file 2, file 1 must be loaded after file 2. With the increase of projects, the dependency relationship between js files becomes more and more complicated, and the maintenance difficulty becomes higher and higher. This dilemma is driving front-end engineers to explore new development models. We get inspiration from the development models of back-end and app. Why can’t we introduce the concept of “module” so that js files can be referenced each other? In order for module 1 to use the functions of module 2, it is only necessary to explicitly refer to module 2 in module 1 without worrying about their arrangement order. Based on this concept,CommonJSAndAMDSpecifications were created, and then front-end module loading tools such as require.js and system.js and node’s module system were available until now.es6 module.

The introduction of modules solves the problem of relying on references between files, while packaging solves the problem of too many files. When the scale of the project increases and the number of modules is in the thousands, if the browser wants to load so many files, the speed of page loading will inevitably be affected. bundler can pack multiple associated files together, thus greatly reducing the number of files and improving the page loading performance. Providing modular development methods and compiling and packaging functions are the core of webpack, and many other functions are developed around them.

Core concept

Module

For webpack, modules are not just javascript modules, they include any type of source files, whether pictures, fonts, json files are modules. The Webpack supports the following ways to reference modules:

Dependency Graph

The so-called dependency graph is an internal logic graph recursively generated by the webpack according to the dependency relationship between each module. With this dependency graph, the webpack can pack all the required modules into a bundle file.

Entry

The starting file for drawing the dependency graph is called entry. The default entry is./src/index.js, or we can configure it in the configuration file. Entry can be one or more.

Individual entry:

module.exports = {
 entry: './src/index.js'
 }

Or ..

module.exports = {
 entry: {
 main: './src/index.js'
 }
 };

Multiple entry, one chunk

We can also specify multiple independent files as entry, but package them into a chunk. this method is calledmulti-main entry, we need to pass in an array of file paths:

module.exports = {
entry: ['./src/index.js', './src/index2.js', './src/index3.js']
}

However, the flexibility and extensibility of the modified method are limited, so it is not recommended.

Multiple entry, multiple chunk

If there are multiple entries, and each entry generates a corresponding chunk, we need to pass in object:

module.exports = {
 entry: {
 app: './src/app.js',
 admin: './src/admin.js'
 }
 };

This writing method has the best flexibility and expansibility, and supports merging with other partial configuration. For example, separate the development environment from the production configuration, separate the common configuration, and merge the environment configuration and the common configuration when running in different environments.

Output

When there is an entrance, there is an exit. As the name implies, the export is the output of the webpack package. Output defines the path and file name of the output. The default output path for Webpack is./dist/main.js. Similarly, we can configure output in the configuration file:

module.exports = {
 entry: './src/index.js',
 output: {
 path: __dirname + '/dist',
 filename: 'bundle.js'
 }
 };

The case of multiple entry

When there are multiple entries, an entry should correspond to an output, and the output file name needs to be usedSubstitutionsDeclare to ensure the uniqueness of the file name, for example, use the name of the portal module:

module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
}

In the end./distGenerated below the pathapp.jsAndsearch.jsTwo bundle files.

Loader

The Webpack itself only supports loading js and json modules. The concept of the webpack is to enable all files to be referenced and loaded and generate dependency graphs, so loader came out. Loader enables webpack to handle other types of files (such as pictures, font files, xml). We can define a loader like this in the configuration file:

webpack.config.js

module.exports = {
module: {
rules: [
{
test: /\.txt$/,
use: 'raw-loader'
}
]
}
};

among themtestDefines the files or file types that need to be converted.useDefines the type of loader that converts the file. This configuration is equivalent to telling the webpack to use theraw-loaderConvert the file and package it into a bundle.

There are also various other types of loader, such as those that load css filescss-loaderTo load pictures and font filesfile-loaderThat loads the html filehtml-loaderTo convert the latest JS syntax to ES5babel-loaderWait. For a complete list, please refer towebpack loaders.

Plugin

Plugin and loader are two confusing and fuzzy concepts. Loader is used to convert and load specific types of files, so the execution level of Loader is a single source file. Plugin can realize more powerful functions. plugin can monitor the key events in the process of webpack processing and deeply integrate into the compiler of webpack. It can be said that the execution level of plugin is the whole construction process. Plugin system is the backbone of webpack. webpack itself is also built based on Plugin system. webpack has rich built-in plug-ins and external plug-ins, and allows users to customize plug-ins. The plug-ins listed officially areThese.

Unlike loader, using plugin we must first reference the plugin, for example:

const webpack = require('webpack');  //used to reference webpack built-in plug-ins
 const HtmlWebpackPlugin = require('html-webpack-plugin');  //External Plug-in
 
 module.exports = {
 plugins: [
 new webpack.HotModuleReplacementPlugin(),
 new HtmlWebpackPlugin({template: './src/index.html'})
 ]
 };

Practice

After understanding the basic concepts of webpack, we will deepen our understanding through practice. Next, we use webpack to build a simple react scaffold.

Create project

First createreact-webpack-starterProject and usenpm initInitialization.

Installation dependency

Install react

npm i react react-dom

Installation of webpack

npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin style-loader css-loader

Installationwebpack-cliAfter that, you can execute the webpack command on the command line.webpack-dev-serverA simple web server is provided, and the compiling operation of the webpack is automatically executed and the browser is automatically refreshed after the file is modified, thus eliminating repeated manual operations;html-webpack-pluginFor automatic generationindex.htmlFile, and inindex.htmlAutomatically add references to bundle files in;style-loaderAndcss-loaderUsed to load css files.

Installation of babel

Due to the use of reactclass,importIn order to improve the browser compatibility of the website, we need to convert the syntax of es6 with babel.

npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader

among them@babel/coreIt is the core module of babel and contains the core functions of babel.@babel/preset-envSupport the conversion of ES6 and updated js syntax, and can select the loaded plugin according to the compatible browser type to simplify the generated code;@babel/preset-reactPlugin; required by babel to convert react is included;babel-loaderBabel loader for webpack.

Configure webpack

Create a new one under the project root directorywebpack.config.js, which reads as follows:

webpack.config.js

const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 
 module.exports = {
 entry: './src/index.js',
 output: {
 path: path.resolve(__dirname, 'dist'),
 filename: 'bundle.js'
 },
 module: {
 rules: [
 {
 test: /\.js$/,
 exclude: /node_module/,
 use: 'babel-loader'
 },
 {
 test: /\.css$/,
 Use: ['Style-Loader',' CSS-Loader']//Pay attention to the order of arrangement. The order of execution is opposite to the order of arrangement
 }
 ]
 },
 plugins: [
 new HtmlWebpackPlugin({
 template: './src/index.html'
 })
 ]
 }

among themHtmlWebpackPluginUse a custom template to generate html files. The content of the template is as follows:

./src/index.html

<!  DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>My React App</title>
</head>
<body>
<div id="app"></div>
</body>
</html>

Configure babel

Create a new one under the project root directory.babelrcFile to configure the two babel preset we installed:

.babelrc

{
 "presets": [
 "@babel/preset-env",
 "@babel/preset-react"
 ]
 }

Generate react Application Root Node

./src/index

import React from 'react';
 import ReactDOM from 'react-dom';
 import App from './components/App';
 
 ReactDOM.render(<App />, document.getElementById('app'));

./src/component/App.js

import React, { Component } from 'react';
import './App.css';

export default class App extends Component {
render() {
return (
<div>
my react webpack starter
</div>
)
}
}

./src/components/App.css

body{
 font-size: 60px;
 font-weight: bolder;
 color: red;
 text-transform: uppercase;
 }

Configurationpackage.json

Finally, inpackage.jsonAdd two scripts to the file to run the development server and package:

package.json

"scripts": {
"start": "webpack-dev-server --mode development --open --hot",
"build": "webpack --mode production"
}

Note that we have enabledwebpack-dev-serverThe module hot update function of (HMR) to further improve our development efficiency.

By this time the simplest version of react scaffold has been completed, let’s run it to see the effect:

image

Is it not as difficult as imagined? Of course, there are many other functions and features of the webpack that need to be mastered. I hope everyone can learn more smoothly after referring to this article.

Demo address in this article:https://github.com/MudOnTire/ …