The full text is introduced

React+ WebPack this article introduces how to build a React+ Webpack project from 0 to understand the basic usage of Webpack.

1. Run the webpack command through NPM scripts

In the previous article, we used./node_modules/.bin/webpack to do the packing, which was very inconvenient, but here’s a way to do the building with NPM scripts

Modify package.json file, add “build”: “webpack” to “scripts” object

 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."build": "webpack"
},
Copy the code

Then execute NPM run build to perform the Webpack packing task. This works by creating a soft link in the node_modules/.bin directory using a shell script.

2. Start the configuration

2.1 Use babel-Loader to parse React and ES features

Start by creating a default webpack configuration file wenpack.config.js in the root directory. Then install the React dependencies required by the React project. Once installed, we’ll write a React component.

/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';

const MyComp = () = > {
    return <div>React & Webpack</div>
}

ReactDOM.render(
    <MyComp />.document.getElementById('app'))Copy the code

Execute packing command, no accident, error reported. Error message:

This is because WebPack only supports JS and JOSN out of the box, and we need to support the other file types and convert them to valid modules via loaders. The laoders skill is a function that takes the source file as an argument and returns the result of the transformation. Considering our project, we need to install the following dependencies:

  1. Babel-loader converts ES6, ES7 and other JS new feature syntax.
  2. Dependencies of @babel/core and @babel/preset-env babel-loader
  3. @babel/preset-react Parsing configuration of the react syntax

Add configuration file for Babel. Babelrc

{
    "presets": [
        "@babel/preset-env"."@babel/preset-react"]}Copy the code

Add the use of babel-loader for js files to webpack.config.js configuration:

const path = require('path')
module.exports = {
    entry: './src/index.js'.output: {
        filename: 'main.js'.path: path.join(__dirname, 'dist')},module: {
        rules: [{test: /\.js$/,
                use: 'babel-loader'}}}]Copy the code

In this case, execute the package command again, and the execution is successful. Add the HTML file to the packaged output dist folder and load the packaged JS file to see the effect:

<! DOCTYPEhtml>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>React & Webpack</title>
</head>

<body>
    <div id="app"></div>
    <script src="./main.js"></script>
</body>

</html>
Copy the code

Perfect parse package run ~

2.2 Parsing the CSS and LESS

Often in the project, we also need to use style files to modify our page styles, which is not supported by Webpack out of the box, so we also need to use Laoder to parse style files.

  • Parsing the CSS:

Install dependencies:

  1. Style-loader mounts the content generated by CSS-loader to the heade section of the page in style
  2. Css-loader analyzes the relationship between CSS modules and synthesizes a CSS

Add configuration in webpack.config.js

const path = require('path')
module.exports = {
    ...
    module: {
        rules: [{test: /\.js$/,
                use: 'babel-loader'
            },
        +   {
        +       test: /\.css$/,
        +       use: ['style-loader'.'css-loader'[+}]}}Copy the code

Laoder is loaded from right to left, so CSS-loader is written after style-loader to add styles to elements and import CSS files

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

const MyComp = () = > {
    return <div className="red">React & Webpack</div>
}

ReactDOM.render(
    <MyComp />.document.getElementById('app'))//index.css
.red {
    color: red;
}
Copy the code

Refresh the browser after the package is complete, and you can see that the style was successfully assigned and the font color changed to red.

  • Parsing the less

You only need to install less-loader dependencies and less dependencies (less-loader depends on less) when using a less-loader and invoke the loader when parsing less files.

const path = require('path')
module.exports = {
    ...
    module: {
        rules: [
            ...
        +   {
        +       test: /\.css$/,
        +       use: ['style-loader'.'css-loader'] +}, + {+ test:/\.css$/,
        +       use: ['style-loader'.'css-loader'.'less-laoder'[+}]}}Copy the code

2.3 Parsing text pictures

Install dependencies:

  1. File-loader parses images and text resources

Add configuration in webpack.config.js

const path = require('path')
module.exports = {
    ...
    module: {
        rules: [
            ...
        +   {
        +       test: /\.(png|jpg|jpeg|gif)$/,
        +       use: 'file-loader'+}]}}Copy the code

Final operation results in 2.2 and 2.3 above:

3. Webpack file listening

In the previous steps, each time we changed the project code, we had to manually perform a packaged update, which was tedious and time-consuming. Webpack, currently one of the most popular module packagers, naturally takes this pain point into account. Webpack supports a file listening mode that automatically reexecutes packaging commands when a file changes. Enable the Watch mode. This means that after the initial build, WebPack will continue to listen for changes to any parsed files.

3.1 Configuration Modes

Webpack enables file listening in two ways:

  • Webpack supports passing –watch arguments in the CLI.
// package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."build": "webpack --watch"
},
Copy the code
  • Set watch to true in configuring webpack.config.js

3.2 Principle Analysis

The principle of Webpack file monitoring is polling to determine whether the last editing time of a file has changed. After a file has changed, it will not immediately tell the listener, but cache it first and wait for the aggregateTimeout. Webpack aggregates any other changes made during that time into a rebuild.

module.export={
    // Default is false, file listening is not enabled
    watch: true.watchOptions: {
        // Do not listen to the file or folder
        ignored: /node_modules/.// How long to wait after listening for changes before executing, in ms
        aggregateTimeout: 300.// Polling frequency, 1000 times per second by default
        poll: 1000}}Copy the code

4. Webpack hot update

This still requires a manual refresh of the browser to synchronize the code changes, so is there a way to do this without refreshing the browser? Apparently there is. There are two ways to implement hot updates in Webpack: one is to implement hot updates with webpack-dev-server (WDS), which, unlike packaging, does not output files but puts them in memory, making it a faster build. WDS generally need to match HotModuleReplacementPlugin plug-ins are used together. Method two uses Webpack-dev-Middleware (WDM) to implement hot updates.

4.1 Use of WDS

Installation depends on webpack-dev-server (if you install Webpack5 + like me, and webpack-CLI version is 4+, then you need to manually downgrade webpack-CLI version to 3, otherwise an error is reported. Add dev to the scripts of package.json as follows: Cannot find module ‘webpack-cli/bin/config-yargs

// package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."build": "webpack --watch".// --open automatically opens the default browser
    "dev": "webpack-dev-server --open"
},
Copy the code

Change mode to development and add devServer in webpack.config.js. In addition also need to use webpack HotModuleReplacementPlugin plug-ins, hot update webpack for enhancement.

const path = require('path')
const webpack = require('webpack')

module.exports = {
    ...
    mode: 'development'.devServer: {
        port: 9000.contentBase: path.resolve(__dirname, './dist'),
        hot: true
    },
    module: {
        rules: [...]. }}Copy the code

Then execute NPM run dev to change the code and check the browser for hot updates.

4.2 Use of WDM

WDM is implemented with the help of Node, and files from Webpack output are transferred to the server, which is generally suitable for more flexible customization scenarios.

const express = require(' express')
const webpack = require('webpack')
const webpackDevMiddleware = require('webpack-dev-middleware')
const app = express()
const config = require('./webpack.config.js)
const compiler = webpack(config)

app.use(webpackDevMiddleware(compiler), {
    publicPath: config.output.publicPath
})

app.listen(8080.() = > {
    console.log('app listening on port 8080')})Copy the code