preface

This is the fourth article in the Webpack Study Notes series, the previous path:

  • If you meet me for the first time, please give me your advice
  • Webpack Study Notes ii: Basic property management
  • Webpack Study Notes (3) : Environment configuration

Through the previous three articles, you can basically build a Webpack project development environment from scratch. In this article, we use WebPack instead of the React scaffolding to build the React project.

Webpack5 + React Configuration procedure

The configuration in this article is not based on any previous project, but rather re-establishes a project file. The server used in the development process is webpack-dev-server server. React + WebPack5

Initialize the project

  1. Create a new project folder and switch the terminal directory under the project folder
  2. runnpm initCommand to generate a package.json file
  3. Install webpack, webpack-CLI, and webpack-dev-server to set up the WebPack development environment
npm install --save-dev webpack webpack-cli webpack-dev-server
Copy the code
  1. Install dependency packages that support CSS files
// Install these dependency packages as required. NPM install --save-dev CSs-loader sas-loaderCopy the code

Install react and react-dom

Install the React and React-dom packages using the NPM command

npm install --save react react-dom
Copy the code

Install Babel dependencies

Install babel-loader @babel/ core@babel /preset-env @babel/preset-react

npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
Copy the code

Install plug-ins used in development

Install plug-ins that generate HTML files, plug-ins that open browsers, plug-ins that extract text from bundles into separate files, and plug-ins that package directory files cleanly

npm install --save-dev html-webpack-plugin open-browser-webpack4-plugin mini-css-extract-plugin happypack
Copy the code

Adding a Configuration File

The environment in this article is separate from the development and production environment, so there are three webPack-related configuration files.

  1. Install webpack – merge
npm intall --save-dev webpack-merge
Copy the code
  1. Add three files in the root directory and write three configuration files respectively
  • webpack.base.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HappyPack = require('happypack')
const os = require('os')
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })

function concatPath(relatedPath) {
    return path.join(__dirname, relatedPath)
}

const webpackConfBase = {
    mode: "development".entry: concatPath('.. /app/app.jsx'),
    output: {
        path: concatPath('.. /dist'),
        filename: '[name].[fullhash:4].js'.chunkFilename: 'chunks/[name].[fullhash:4].js',},module: {
        rules: [{test: /\.js[x]? $/,
                use: 'babel-loader'
            },
            {
                test: /\.(sc|sa|c)ss$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader'.'sass-loader']]}},plugins: [
        new HappyPack({
            // Use the id to identify the class file that happypack processes
            id: 'happyBabel'.// How to handle the same usage as the loader configuration
            loaders: [{
              loader: 'babel-loader',}],// Indicates a shared process pool. That is, multiple Instances of HappyPack use child processes in the same shared process pool to handle tasks to prevent excessive resource usage.
            threadPool: happyThreadPool,
            // Allow HappyPack to output logs
            verbose: true,}).new HappyPack({
            // Use the id to identify the class file that happypack processes
            id: 'happyStyle'.// How to handle the same usage as the loader configuration
            loaders: [MiniCssExtractPlugin.loader, 'css-loader? sourceMap=true'.'sass-loader? sourceMap=true'].// Indicates a shared process pool. That is, multiple Instances of HappyPack use child processes in the same shared process pool to handle tasks to prevent excessive resource usage.
            threadPool: happyThreadPool,
            // Allow HappyPack to output logs
            verbose: true,}).// Extract the text (CSS) from the bundle into a separate file
        new MiniCssExtractPlugin({
            // The configuration item is the same as webPackoptions. output
            // All configurations are optional
            filename: '[name].[fullhash:4].css'.chunkFilename: '[id].[fullhash:4].css',})],}module.exports = webpackConfBase;
Copy the code
  • webpack.dev.js
const path = require('path');
const webpack = require('webpack');
const { merge } = require('webpack-merge');
const webpackConfigBase = require('./webpack.base.config');
// open browser-webpack4-plugin // Open browser-webpack4-plugin // Open browser-webpack4-plugin // Open browser-webpack4-plugin
const OpenBrowserPlugin = require('open-browser-webpack4-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const PORT = 8888;
function concatPath(relatedPath) {
    return path.join(__dirname, relatedPath);
}

const webpackConfigDev = {
    plugins: [
        // Define the environment variable as the development environment
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('development'),
            IS_DEVELOPMETN: true,}).// Inject the packaged resources into an HTML file
        new HtmlWebpackPlugin({
            inject: 'body'.title: 'React APP'.filename: 'index.html'.template: concatPath('.. /app/index.html')}),new OpenBrowserPlugin({
            url: `http://localhost:${PORT}`,})],devtool: 'source-map'.devServer: {
        contentBase: concatPath('.. /app'),
        historyApiFallback: false.hot: false.host: '0.0.0.0'.port: PORT,
    },
}

module.exports = merge(webpackConfigBase, webpackConfigDev);
Copy the code
  • webpack.prod.js
const webpack = require('webpack');
const path = require('path');
const { merge } = require('webpack-merge');
const webpackConfigBase = require('./webpack.base.config');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
// Used to clear the last packed file in the packing directory
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

function concatPath(relatedPath) {
    return path.join(__dirname, relatedPath)
}

const webpackConfigProd = {
    mode: "production".// Extract common modules shared between chunks
    optimization: {
        runtimeChunk: {
            name: 'manifest'
        },
        minimizer: [].// [new UglifyJsPlugin({...})]
        splitChunks: {chunks: 'async'.minSize: 30000.minChunks: 1.maxAsyncRequests: 5.maxInitialRequests: 3.name: false.cacheGroups: {
                vendor: {
                    name: 'vendor'.chunks: 'initial'.priority: -10.reuseExistingChunk: false.test: /node_modules\/(.*)\.js/
                },
                styles: {
                    name: 'styles'.test: /\.(scss|css)$/,
                    chunks: 'all'.minChunks: 1.reuseExistingChunk: true.enforce: true}}}},plugins: [
        // Define the environment variable as the development environment
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production'),
            IS_DEVELOPMETN: false,}).// Inject the packaged resources into an HTML file
        new HtmlWebpackPlugin({
            inject: 'body'.title: 'React APP'.filename: 'index.html'.template: concatPath('.. /app/index.html')}),// Parse the code
        new BundleAnalyzerPlugin({ analyzerPort: 3011 }),
        new CleanWebpackPlugin({
            protectWebpackAssets: true,})],}module.exports = merge(webpackConfigBase, webpackConfigProd)
Copy the code
  1. create.babelrcFile to configure Babel
{
    "compact": false."presets": [
        "@babel/preset-env".// Babel starts the plug-in
        "@babel/preset-react" // Compile the React syntax plugin]."plugins": [
        "@babel/transform-runtime"]}Copy the code

Add scripts command

"scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js"."build": "webpack --config webpack.prod.js"
}
Copy the code

In front of the blackboard, underline

The babel-loader version does not contain the following information: The default installation is Babel 8.x, This version is compatible with @babel/core @babel/preset-env @babel/preset-react and the previous versions of Babel 7.x are able-core and babel-preset-env, etc.