Project initialization

$ npm init
Copy the code

Install webpack

  • This creation is based on WebPack4
$ npm install --save-dev
Copy the code

Create a WebPack configuration file

  • Create a build folder in the root directory and add a js file named webpack.base.conf.js
// webpack.base.conf.js file const path = require('path');
const DIST_PATH = path.resolve(__dirname, '.. /dist');
module.exports = {
        entry: {
            app: './app/index.js'
        },
        output: {
            filename: "js/bundle.js",
            path: DIST_PATH
        }
};
Copy the code

Merge the WebPack base configuration and the configuration of different environments

  • Install webpack-merge first:
$ npm install --save-dev webpack-merge
Copy the code
  • Add another js file to the build folder called webpack.prod.conf.js
// 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 app directory in the root directory, then create the index.js file

var element =document.getElementById('root');
element.innerHTML = 'hello, world! ';
Copy the code
  • Create a public folder in the root directory and create a new index.html file
// index.html <! DOCTYPE html> <html lang="en">
  <head>
      <meta charset="UTF-8"</title> </head> <body> <div id="root"></div>
        <script src=".. /dist/js/bundle.js"></script>
  </body>
</html>
Copy the code

Current project directory tree

  |- /app
    |- index.js
  |- /node_modules
  |- /public
    |- index.html
  |- /build
    |- webpack.base.conf.js
    |- webpack.prod.conf.js
  |- package.json
  |- package-lock.json
Copy the code

Install webpack – cli

  • In webpack 4.0, the webpack command tool has been migrated to webpack-CLI module, so you need to install Webpack-CLI
$ npm install --save-dev webpack-cli
Copy the code

The package.json file scripts property configures a build command

  • Its value is: webpack — config build/webpack. Prod. Conf., js, the following is the code for scripts
// package.json
"scripts": {
    "build": "webpack --config build/webpack.prod.conf.js"."test": "echo \"Error: no test specified\" && exit 1"
},
Copy the code

Install the React

$ npm install --save react react-dom
Copy the code
  • Change the code of index.js in app directory
import React from "react";
import ReactDom from "react-dom"; ReactDom.render( <h1>hello, world! </h1>, document.getElementById("root"));Copy the code
  • Note that import is part of the ES6 specification, so you need to translate ES2015+ syntax, install and configure Babel and related dependencies
$ npm install --save-dev babel-loader babel-core babel-preset-env babel-preset-react
Copy the code
  • The root directory creates the. Babelrc file and configures the presets.
{
  "presets": [["env",
      {
        "targets": {
          "browsers": [
            "1%" >."last 5 versions"."ie >= 8"]}}],"react"]}Copy the code
  • Modify the webpack.base.conf.js file
// webpack.base.conf.js
const path = require('path');
const APP_PATH = path.resolve(__dirname, '.. /app');
const DIST_PATH = path.resolve(__dirname, '.. /dist');
module.exports = {
    entry: {
        app: './app/index.js'
    },    
    output: {
        filename: 'js/bundle.js',
        path: DIST_PATH
    },
    module: {
        rules: [
            {
                test: /\.js? $/, use:"babel-loader",
                include: APP_PATH
            }
        ]
    }
};
Copy the code
  • Run NPM run build

Add the plug-in

  • The index.html under public should be automatically added to the dist directory and reference resources automatically loaded into the file via the html-webpack-plugin
$ npm install html-webpack-plugin --save-dev
Copy the code
  • Configure the plugins property in webpack.prod.conf.js
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = merge(baseWebpackConfig, {
    mode: 'production',
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html',
            inject: 'body',
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true}})]});Copy the code
  • Remove manually imported script tags from index.html
<! DOCTYPE html> <html lang="en">
<head>
    <meta charset="UTF-8"</title> </head> <body> <div id="root"></div>
</body>
</html>
Copy the code
  • Recompile to view NPM run build browser open to view index.html in directory dist

If all the above steps are successful, proceed to the next step

  • The generated file name is added with a Hash value to resolve caching issues
  • Modify webpack.prod.conf.js, mode: ‘production’, add the following code
// webpack.prod.conf.js
output: {
    filename: "js/[name].[chunkhash:16].js",},Copy the code
  • The files generated by the previous project need to be cleaned up before the build, because the file name will always be added if not deleted due to the change of the file name
  • Install the clean-webpack-plugin
$ npm install --save-dev clean-webpack-plugin
Copy the code
  • Modify the webpack. Prod. Conf. Js
// webpack.prod.conf.js
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = merge(baseWebpackConfig, {
    mode: 'production',
    output: {
        filename: "js/[name].[chunkhash:16].js",
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html',
            inject: 'body',
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
            },
        }),
        new CleanWebpackPlugin(['.. /dist'], { allowExternal: true]}}));Copy the code

Public code is separated from business code

  • Modify the entry property of webpack.base.conf.js to extract the framework code
entry: {
      app: './app/index.js',
      framework: ['react'.'react-dom'],},Copy the code
  • Modify webpack.prod.conf.js to add the following code to separate framework code from business code
  • App.js still contains the framework code, although the previous steps extract the framework code to generate two files
optimization: {
        splitChunks: {
            chunks: "all",
            minChunks: 1,
            minSize: 0,
            cacheGroups: {
                framework: {
                    test: "framework",
                    name: "framework",
                    enforce: true}}}}Copy the code
  • CacheGroups object, which defines modules that need to be removed
  • The test attribute is the key value. It can be a string, a regular expression, or a function. If a string is defined, the entry module name will be matched, and the module containing it will be removed from the other modules
  • Name is the name of the extracted framework module, which is the same as the name of the imported file module. In this way, the extracted framework module overwrites the extracted framework module

Integrating webpack — dev server

  • The development environment enables service monitoring for file changes and updates the latest content in real time
$ npm install --save-dev webpack-dev-server
Copy the code
  • Add the webpack.dev.conf.js file to build
const path = require('path');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');

module.exports = merge(baseWebpackConfig, {
    mode: 'development',
    output: {
        filename: "js/[name].[hash:16].js",
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html',
            inject: 'body',
            minify: {
                html5: true
            },
            hash: false
        }),
        new webpack.HotModuleReplacementPlugin()
    ],
    devServer: {
        port: '8080',
        contentBase: path.join(__dirname, '.. /public'),
        compress: true.historyApiFallback: true,
        hot: true,
        https: false,
        noInfo: true,
        open: true,
        proxy: {}
    }
});
Copy the code
  • Add content to the package.json scripts property
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js".Copy the code
  • npm run dev
  • Automatically open the browser to open the portal page for real-time updates

Export the CSS file independently

  • Install CSS dependencies
  • Sass less preprocessing
$ npm install extract-text-webpack-plugin $ npm install style-loader css-loader postcss-loader autoprefixer --save-dev $  npm install less sass less-loader sass-loader stylus-loader node-sass --save-devCopy the code
  • Change the webpack.base.conf.js file
// webpack.base.conf.js
{
    test: /\.css$/,
    use: [
        {
          loader: "style-loader"// Insert HTML <style> tags}, {loader:"css-loader"// get reference resources such as @import,url()}, {loader:"postcss-loader",
              options: {
                    plugins:[
                       require('autoprefixer')({
                           browsers:['last 5 version']})]}}]}, {test:/\.less$/,
   use: [
         {  loader: "style-loader"  },
         {  loader: "css-loader" },
         {
            loader: "postcss-loader"Options: {plugins:[require('autoprefixer')({
                              browsers:['last 5 version']
                          })
                  ]
            }
         },
         {  loader: "less-loader"}]}, {test:/\.scss$/,
      use:[
             {  loader: "style-loader"  },
             {
                      loader: "css-loader",
             },
             {  loader: "sass-loader" },
             {
               loader: "postcss-loader",
              options: {
                    plugins:[
                         require('autoprefixer')({
                           browsers:['last 5 version']})]}}]},Copy the code
  • Image and path processing
$ npm i file-loader url-loader --save-dev
Copy the code
  • Change the webpack.base.conf.js file
// webpack.base.conf.js
{
    test: /\.(png|jpg|gif|woff|svg|eot|woff2|tff)$/,
    use: 'url-loader? limit=8129'// Notice the latter onelimitExclude: /node_modules/}. Exclude: /node_modules/}Copy the code

The build times wrong

Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
    at Chunk.get (F:\react\createApp\node_modules\webpack\lib\Chunk.js:824:9)
Copy the code
  • Error “extract-text-webpack-plugin” is used in Webpackage 4.0
  • The solution
$ npm install extract-text-webpack-plugin@next
Copy the code

Background image path problem

  • Because the CSS file is separated, it will cause you to look for images under the IMAGES folder in the CSS folder
  • Solution Change the publicPath property to ‘/’ to find resources in absolute path mode
{
    test:/\.(png|jpg|gif)$/,
    use:[{
        loader:'url-loader',
        options: {
              // outputPath:'.. / '// Print ** folder publicPath:'/',
              name: "images/[name].[ext]".limitIf the file size is smaller than 500B, write JS}}]},Copy the code