The configuration in Chapter 2 is almost ready to meet normal development requirements. But there is much that could be improved.

Chapter III Improvement Projects

Use the latest ES syntax

React development will inevitably use ES latest syntax. For example, common Decorators are in Stage 2 and Dynamic imports are in Stage 3. These new grammars are not covered by @babel/preset-env. Therefore, we need to configure the corresponding Babel plug-in.

Install the Babel plugin:

  • Support decorator@babel/plugin-proposal-decorators
  • Support for class attributes@babel/plugin-proposal-class-properties
  • Support for dynamic import@babel/plugin-syntax-dynamic-import

Configure. Babelrc file:

{
  "presets": ["@babel/preset-env"."@babel/preset-react"]."plugins": [
    // Note that the decorators plug-in is written before class-properties
    // The decorators plugin needs to set Legacy to true to be compatible with the previous decorator writing
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true}]."@babel/plugin-syntax-dynamic-import"]}Copy the code

Add CSS preprocessing with PostCSS

We can use Sass to enhance the programming and abstraction capabilities of CSS, and use postCSS autoprefixer to automatically prefix CSS with browser vendors.

Installation:

  • sass-loader
  • postcss-loader autoprefixer

Configuration of webpack.dev.js:

// ...
module: {
  rules: [{test: /\.scss$/.// Loader is loaded from back to front. Postcss-loader must be loaded before sass-loader
      use: ["style-loader"."css-loader"."postcss-loader"."sass-loader"]},// ...]},// ...
Copy the code

Webpack.prod.js configuration:

// ...
module: {
  rules: [{test: /\.scss$/.use: [
        MiniCssExtractPlugin.loader,
        "css-loader"."postcss-loader"."sass-loader"]},// ...]},// ...
Copy the code

Create the postcss.config.js file in the project root directory:

module.exports = {
  plugins: [require("autoprefixer")]};Copy the code

Configure the browser compatibility range

. @ Babel/preset configuration – within a babelrc env automatically for package necessary polyfill, postcss. Config. Js autoprefixer configuration in the plug-in can automatically add the necessary for CSS browser vendors prefix. How do they determine which polyfills and which browser vendor prefixes are necessary, given that different companies and even different projects are compatible with different browser versions? Projects that don’t have any compatibility requirements should rely less on Polyfill, and projects that are compatible with Internet Explorer should add more Polyfill and browser vendor prefixes. So we need to configure.browserslistrc to tell these packagers what browser range we want to be compatible with.

Create a.browserslistrc file in the project root directory:

> 1%
last 2 versions
not ie <= 8
Copy the code

This configuration basically means: browsers with more than 1% market share, the latest two versions, excluding browsers below IE8.

configuration.editorconfig

Some people prefer indentation with horizontal tabs, while others prefer 2 Spaces. Depending on the operating system used, some people have LF, others CRLF. These trivial things can be agreed upon early in the project and set into each developer editor formatting configuration. But it’s a hassle.

We create. Editorconfig in the project root directory:

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
Copy the code

This configuration tells the editor that the current item is indented with 2 Spaces, newlines are LF, and a blank line is inserted at the bottom of each file. The editor sees the. Editorconfig file in the project and formats the project file as it wants.

The advantage of using EditorConfig is that it gives you more fine-grained control over the formatting style of each project and even different file types, allowing different projects to have different formatting styles.

Once configured, the editor needs to download the EditorConfig plug-in from the plug-in market. Webstorm installs this plugin by default, so you don’t need to download it.

Configure ESLint and prettier

ESLint validates our code style and syntax errors to ensure that the style is consistent and errors can be found early in team development.

ESLint often fails because of a lack of Spaces or commas. These trivial errors can be annoying, so prettier can be used to help format code.

Installation:

  • eslint eslint-loader
  • babel-eslint
  • eslint-config-airbnb eslint-config-prettier

When installing eslint-config-Airbnb, the console will have a warning and we need to install all peer dependency according to its warning.

Webpack.com mon. Js configuration:

// ...
module: {
  rules: [{enforce: "pre".test: /\.jsx? $/.include: path.resolve(__dirname, "src"),
      use: "eslint-loader"
    },
    // ...]}// ...
Copy the code

Add.eslintrc.js to the root directory:

module.exports = {
  root: true.parser: "babel-eslint".env: {
    browser: true.es6: true.node: true
  },
  parserOptions: {
    ecmaVersion: 6.sourceType: "module"
  },
  extends: ["airbnb"."prettier"].rules: {
    "no-console": process.env.NODE_ENV === "production" ? "error" : "off"."no-debugger": process.env.NODE_ENV === "production" ? "error" : "off"}};Copy the code

Add two lint precommit scripts to package.json

// ...
"scripts": {
  "start": "cross-env NODE_ENV=development webpack-dev-server --config webpack.dev.js"."build": "cross-env NODE_ENV=production webpack --config webpack.prod.js"."lint": "cross-env NODE_ENV=production eslint --ext .jsx --ext .js --fix ./src"."precommit": "npm run lint"
},
// ...
Copy the code

When NPM run Lint is executed, ESLint will check all.js.jsx files in the./ SRC directory and try to fix some problems. Problems that ESLint cannot fix are printed to the console, at which point it is up to you to fix the problem manually.

Git executes a precommit script every time git commits code. This script tells ESLint to check the code, and if it doesn’t pass it won’t commit the code. This ensures the quality of the code in the repository. For the Precommit script to work, husky needs to be installed, and we use “cross-env” inside the script to modify environment variables, so cross-env needs to be installed.

Installation:

  • husky
  • cross-env

It is recommended that you install the ESLint plugin in the editor so that you can see ESLint error messages while writing code. After installing the ESLint plugin, it may report errors in files we don’t want it to check, so we add.eslintignore to tell the plugin to skip checking files and directories.

. Eslintignore configuration

node_modules
/dist

webpack.common.js
webpack.prod.js
webpack.dev.js
postcss.config.js
Copy the code

It is also recommended to install the prettier plug-in and configure the editor to format automatically when saving.

Hot Module Replacement

When developing React with webpack-dev-server, the page is automatically refreshed every time a file is modified. While this is much more convenient than the traditional manual page refresh, in some cases it is not convenient enough. For example, when developing a form modal window, refreshing the page will cause the modal window to close and the information filled in the form to be lost.

Webpack’s hot update addresses this pain point by updating the interface without refreshing it.

Webpack4 supports hot updates by default, we just need to turn this on.

Enable hot update in webpack.dev.js:

// ...
devServer: {
  hot: true.// Enable hot update
  historyApiFallback: true
},
// ...
Copy the code

We use react-hot-loader to support react hot updates.

Installation:

  • react-hot-loader

Add the react-hot-loader plugin to.babelrc:

{
  "presets": ["@babel/preset-env"."@babel/preset-react"]."plugins": [["@babel/plugin-proposal-decorators", { "legacy": true }],
    ["@babel/plugin-proposal-class-properties", { "loose": true}]."@babel/plugin-syntax-dynamic-import"."react-hot-loader/babel"]}Copy the code

Note that this plugin is written as react-hot-loader/ Babel.

Finally, modify the code inside app.jsx. Use the high-order components provided by the React-hot-loader to decorate our App components.

import React from "react";
// Import the hot function
import { hot } from "react-hot-loader/root"; 

// ...

function App() {
  return (
    // ...
  );
}

// Decorate App components with the hot function
export default hot(App);
Copy the code

Tree Shaking

Webpack4 turns Tree Shaking on in Production mode, but note the following

  • Using ES2015 module syntax (example:importexportModules compiled into the CommonJS specification cannot be optimized.
  • Need to be inpackage.jsonIn-file add"sideEffects"Field. The value of this field can be an array of module names to tell WebPack which modules have negative effects. The value of this field can also befalse“, indicating that all modules have no side effects. Modules identified as having side effects are not shaken by Tree.
  • Within the WebPack configurationmodeSet to"production"

code

Project code Github repository

Other chapters

  • The first chapter establishes the project prototype
  • Chapter 2 unpacks the WebPack configuration
  • Chapter III Improvement Projects