Webpack4+Babel7+React16+Less Simple configuration notes

I. Project initialization

Create a new project, react-init

mkdir react-init
cd react-init
Copy the code

Initialize the

yarn init -y
# or
npm init -y
Copy the code

Install Webpack

Webpack 4 installation requires two installings, one is Webpack, the other is Webpack-CLI

yarn add webpack webpack-cli -D
# or
npm i webpack webpack-cli -D
Copy the code

3. Create webPack configuration file

Create the config directory under the project root directory and create 3 configuration files in this directory.

Webpack.base.conf.js – Common configuration

Webpack.dev.conf.js — Development environment configuration

Webpack.prod.conf.js — Production environment configuration

Because common configuration items are used, another library needs to be introduced in order to be able to use the common items. Install as follows:

yarn add webpack-merge -D
# or
npm i webpack-merge -D
Copy the code

In webpack.base.conf.js, write:

const path = require('path');
const DIST_PATH = path.resolve(__dirname, '.. /dist');
const APP_PATH = path.resolve(__dirname, '.. /src');

module.exports = {
  entry: {
    app: APP_PATH+'/index.js'
  },
  output: {
    filename: "js/[name].[chunkhash].js".path: DIST_PATH
  },
  resolve: {
    extensions: [".js".".jsx".".less"].alias: {
      "@": APP_PATH
    }
  },
}
Copy the code

In webpack.dev.conf.js:

const path = require("path");
const merge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");

module.exports = merge(baseWebpackConfig, {
  mode: "development".output: {
    filename: "js/[name].[hash:16].js"
  },
  devtool: "inline-source-map"});Copy the code

In webpack.prod.conf.js:

const merge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");

module.exports = merge(baseWebpackConfig, {
  mode: "production"});Copy the code

Create the SRC directory under the root directory, then create the index.js file as the entry file for the entire project, and create the app. JSX file as the root component of the React project.

Create the public directory under the root directory, and then create the index.html file as the template file for the entire one-page project.

Index.html reads as follows:


      
<html lang="zh-cn">
<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><%= htmlWebpackPlugin.options.title %></title> -->
    <title>React-Init</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>
Copy the code

In package.json, add the command line script:

"scripts": {
  "build": "webpack --config config/webpack.prod.conf.js"
 }
Copy the code

Install React

yarn add react react-dom
# or
npm i react react-dom -S
Copy the code

Modify the SRC/app. JSX file as follows:

import React, { Component } from "react";

class App extends Component {
  render() {
    return (
      <h1>Hello React</h1>); }}export default App;
Copy the code

Modify the SRC /index.js file as follows:

import React from "react";
import ReactDom from "react-dom";

import App from "./App";

ReactDom.render(<App />, document.getElementById("root"));
Copy the code

Install Babel

In order for ES6 modularity to be supported and for browser-aware ES5 code to be translated into JSX format parsing, the corresponding Babel and Babel plug-ins must be introduced. The installation is as follows:

yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react -D
# or
npm i babel-loader @babel/core @babel/preset-env @babel/preset-react -D
Copy the code

Configure the Babel:

In webpack. Base. Conf. Js

module.exports = {
  ...
  resolve: {
    extensions: [".js".".jsx".".less"].alias: {
      "@": APP_PATH
    }
  },
  // Here are the additions
  module: {
    rules: [{test: /\.jsx? $/.use: 'babel-loader'.include: APP_PATH
      },
    ]
  }
}
Copy the code

Create a new. Babelrc file in the root directory with the following contents:

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

Add an Html template

Install htML-webpack-plugin:

yarn add html-webpack-plugin -D
# or
npm i html-webpack-plugin -D
Copy the code

This will automatically load the generated JS file into the HTML script tag, you can customize the HTML template, see the documentation on the NPM website.

Add the following configuration to webpack.prod.conf.js

. const HtmlWebpackPlugin =require("html-webpack-plugin");

module.exports = merge(baseWebpackConfig, {
  mode: "production".plugins: [
    new HtmlWebpackPlugin({
      template: "public/index.html".minify: {
        removeComments: true.collapseWhitespace: true.removeAttributeQuotes: true}})});Copy the code

Now you can build and run

yarn build
# or
npm run build
Copy the code

If no errors are reported and the dist directory is generated under the root directory, the previous configuration is basically correct

Webpack optimization

During production, you can use the clean-webpack-plugin to clean the DIST folder first:

yarn add clean-webpack-plugin -D
Copy the code

Then add the following content to webpack.prod.conf.js:

. const { CleanWebpackPlugin } =require("clean-webpack-plugin"); . plugins: [new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: "public/index.html".minify: {
        removeComments: true.collapseWhitespace: true.removeAttributeQuotes: true}})].Copy the code

Add hot loading development environment

yarn add webpack-dev-server -D
Copy the code

Add the following to webpack.dev.conf.js:

. const HtmlWebpackPlugin =require("html-webpack-plugin");
const webpack = require("webpack");

module.exports = merge(baseWebpackConfig, {
  ...
  plugins: [
    new HtmlWebpackPlugin({
      template: "public/index.html".inject: "body".minify: {
        html5: true
      },
      hash: false
    }),
    new webpack.HotModuleReplacementPlugin()
  ],
  devServer: {
    port: 3000.contentBase: path.join(__dirname, ".. /public"),
    compress: true.historyApiFallback: true.hot: true.https: false.noInfo: true.open: true.proxy: {}}});Copy the code

Then in the package.json script:

"scripts": {
  "build": "webpack --config config/webpack.prod.conf.js",
  "dev": "webpack-dev-server --inline --progress --config config/webpack.dev.conf.js"
}
Copy the code

perform

yarn dev
# or
npm run dev
Copy the code

It can be accessed in an open browser at localhost:3000

8. Handle CSS and Less

With Webpack we can import CSS or less files in JS, but must use the corresponding loader to process.

yarn add css-loader mini-css-extract-plugin less less-loader postcss-loader autoprefixer -D
Copy the code

Add it to webpack.base.conf.js

. const MiniCssExtractPlugin =require("mini-css-extract-plugin"); . module.exports = { ... module: {rules: [{test: /\.jsx? $/.use: "babel-loader".include: APP_PATH
      },
      {
        test: /\.css$/.use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader".options: {
              modules: true  // Enable support for CSS modules}}]}, {test: /\.less$/.exclude: /node_modules/.use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader".options: {
              modules: true}}, {loader: "postcss-loader".options: {
              plugins: [require("autoprefixer") (the)]}}, {loader: "less-loader".options: {
              modifyVars: {
                // The custom theme content is written here}}}]},]},plugins: [
    new MiniCssExtractPlugin({
      filename: "css/[name].[hash].css".ignoreOrder: false}})];Copy the code

For Autoprefixer to work, you need to add the following to package.json:

"browserslist": [
  "last 4 version",
  "> 1%",
  "maintained node versions",
  "not dead"
]
Copy the code

Nine, the font and picture processing

Install the loader:

yarn add file-loader url-loader -D
Copy the code

Add this to webpack.base.conf.js:

module.exports = {
  ...
  module: {
    rules: [{...test: /\.(png|jpg|gif|jpeg|bmp|webp)$/.use: [{loader: "url-loader".options: {
              publicPath: "/".name: "images/[name].[ext]".limit: 512}}]}, {test: /\.(woff|svg|eot|woff2|tff)$/.use: "file-loader".exclude: /node_modules/}}],... };Copy the code

At this point, almost all the required configuration is done, so the entire configuration file should look like this:

  1. webpack.base.conf.js

    const path = require("path");
    const DIST_PATH = path.resolve(__dirname, ".. /dist");
    const APP_PATH = path.resolve(__dirname, ".. /src");
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = {
      entry: {
        app: APP_PATH + "/index.js"
      },
      output: {
        filename: "js/[name].[chunkhash].js".path: DIST_PATH
      },
      module: {
        rules: [{test: /\.jsx? $/.use: "babel-loader".include: APP_PATH
          },
          {
            test: /\.css$/.use: [
              MiniCssExtractPlugin.loader,
              {
                loader: "css-loader".options: {
                  modules: true}}]}, {test: /\.less$/.exclude: /node_modules/.use: [
              MiniCssExtractPlugin.loader,
              {
                loader: "css-loader".options: {
                  modules: true}}, {loader: "postcss-loader".options: {
                  plugins: [require("autoprefixer") (the)]}}, {loader: "less-loader".options: {
                  modifyVars: {
                    // The custom theme content is written here}}}]}, {test: /\.(png|jpg|gif|jpeg|bmp|webp)$/.use: [{loader: "url-loader".options: {
                  publicPath: "/".name: "images/[name].[ext]".limit: 512}}]}, {test: /\.(woff|svg|eot|woff2|tff)$/.use: "file-loader".exclude: /node_modules/}},resolve: {
        extensions: [".js".".jsx".".less"].alias: {
          "@": APP_PATH
        }
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: "css/[name].[hash].css".ignoreOrder: false}})];Copy the code
  2. webpack.dev.conf.js

    const path = require("path");
    const merge = require("webpack-merge");
    const baseWebpackConfig = require("./webpack.base.conf");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const webpack = require("webpack");
    
    module.exports = merge(baseWebpackConfig, {
      mode: "development".output: {
        filename: "js/[name].[hash:16].js"
      },
      devtool: "inline-source-map".plugins: [
        new HtmlWebpackPlugin({
          template: "public/index.html".inject: "body".minify: {
            html5: true
          },
          hash: false
        }),
        new webpack.HotModuleReplacementPlugin()
      ],
      devServer: {
        port: 3000.contentBase: path.join(__dirname, ".. /public"),
        compress: true.historyApiFallback: true.hot: true.https: false.noInfo: true.open: true.proxy: {}}});Copy the code
  3. webpack.prod.conf.js

    const merge = require("webpack-merge");
    const baseWebpackConfig = require("./webpack.base.conf");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    
    module.exports = merge(baseWebpackConfig, {
      mode: "production".plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
          template: "public/index.html".minify: {
            removeComments: true.collapseWhitespace: true.removeAttributeQuotes: true}})});Copy the code
  4. .babelrc

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

    {
      "name": "react-init"."version": "1.0.0"."main": "index.js"."license": "MIT"."scripts": {
        "build": "webpack --config config/webpack.prod.conf.js"."dev": "webpack-dev-server --inline --progress --config config/webpack.dev.conf.js"
      },
      "devDependencies": {
        "@babel/core": "^ 7.5.5." "."@babel/plugin-transform-runtime": "^ 7.5.5." "."@babel/preset-env": "^ 7.5.5." "."@babel/preset-react": "^ 7.0.0." "."autoprefixer": "^ 9.6.1." "."babel-loader": "^ 8.0.6"."clean-webpack-plugin": "^ 3.0.0"."css-loader": "^ 3.2.0"."file-loader": "^ 4.2.0"."html-webpack-plugin": "^ 3.2.0"."less": "^ 3.9.0"."less-loader": "^ 5.0.0"."mini-css-extract-plugin": "^ 0.8.0"."postcss-loader": "^ 3.0.0"."url-loader": "^ 2.1.0." "."webpack": "^ 4.39.1"."webpack-cli": "^ 3.3.6." "."webpack-dev-server": "^ 3.7.2." "."webpack-merge": "^ 2"
      },
      "dependencies": {
        "react": "^ 16.8.6"."react-dom": "^ 16.8.6"
      },
      "browserslist": [
        "last 4 version"."1%" >."maintained node versions"."not dead"]}Copy the code

The directory structure of the whole project is as follows:

The react - init ├ ─ ─ the config │ ├ ─ ─ webpack. Base. Conf., js │ ├ ─ ─ webpack. Dev. Conf., js │ └ ─ ─ webpack. Prod. Conf., js ├ ─ ─ public │ └ ─ ─ Index.html ├ ─ ─ the SRC │ ├ ─ ─ App. The JSX │ ├ ─ ─ App. Less │ ├ ─ ─ assets │ │ └ ─ ─ 01. Jpeg │ └ ─ ─ index. The js ├ ─ ─ the babelrc ├ ─ ─ Package. The json └ ─ ─ yarn. The lockCopy the code