Initialize the project

  • Create a project directory
  • Initialize the NPM project
npm init -y
Copy the code
  • Initialize the Git project
Initialize the project
git init

# 添加 .gitignore
echo "/node_modules\n/build" >> .gitignore

Associate the remote repository
git remote add origin <url>
Copy the code

Webpack configuration

2.1 Basic Configuration Settings

  • Create a file/src/index.jsAs an entry file for WebPack
import React from 'react';
import reactDom from 'react-dom';

const App = (a)= > (
  <div>
    test page
  </div>
);
reactDom.render(<App/>.document.getElementById('root'));
Copy the code
  • Creating a template File/public/index.htmlThe webPack packed file will be added to this file

      
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
Copy the code
  • createwebpackConfiguration files in the development environment/webpack/webpack.config.dev.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const htmlWebpackPlugin = new HtmlWebpackPlugin({
  template: path.resolve(__dirname, '.. /public/index.html')});module.exports = {
  mode: 'development'.entry: path.resolve(__dirname, '.. /src/index.js'),
  output: {                                         
    path: path.resolve(__dirname, '.. /build'),      
    filename: 'js/[name].[hash].bundle.js',},module: {
    rules: [{test: /\.(mjs|js|jsx)$/.exclude: /node_modules/.use: ['babel-loader']],}},plugins: [
    htmlWebpackPlugin,
  ],

  resolve: {
    extensions: ['.mjs'.'.js'.'.jsx'],}};Copy the code
  • createwebpackConfiguration files in the production environment/webpack/webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const htmlWebpackPlugin = new HtmlWebpackPlugin({
  template: path.resolve(__dirname, '.. /public/index.html')});module.exports = {
  mode: 'production'.// The configuration in the development environment only changes the mode
  entry: path.resolve(__dirname, '.. /src/index.js'),
  output: {                                         
    path: path.resolve(__dirname, '.. /build'),      
    filename: 'js/[name].[hash].bundle.js',},module: {
    rules: [{test: /\.(mjs|js|jsx)$/.exclude: /node_modules/.use: ['babel-loader']],}},plugins: [
    htmlWebpackPlugin,
  ],

  resolve: {
    extensions: ['.mjs'.'.js'.'.jsx'],}};Copy the code
  • createbabelThe configuration file.babelrc
{
  "presets": [
    "@babel/preset-react"."@babel/preset-env"]}Copy the code
  • Modify thepackage.json: Adds the NPM script
"scripts": {
+ "start": "webpack-dev-server --config ./webpack/webpack.config.dev.js --open",
+ "build": "rm -rf build/* && webpack --config ./webpack/webpack.config.js"
}
Copy the code

2.2 Installing basic plug-in packages

  1. Webpack-related dependency packages and plug-ins
  • Webpack: Basic WebPack package
  • Webpack-cli: Webpack CLI tool package
  • Html-webpack-plugin: Webpack plugin used to add packaged files to the specified HTML
  • Webpack-dev-server: Webpack development environment tool to create a development environment
  • Babel-loader: weboack loader, used to compile packaged JS files
  • @babel/core: Babel dependency package, parsing JS code into AST
  • @babel/preset-react: presets related to webpack React
  • @babel/preset-env: Weboack react related presets so that the latest JS related syntax can be used
npm i webpack webpack-cli html-webpack-plugin webpack-dev-server babel-loader @babel/core @babel/preset-react @babel/preset-env -D
Copy the code
  1. React Dependent packages and packages
  • react
  • react-dom
npm i react react-dom
Copy the code

2.3 test

  1. performnpm startTest whether the project is running properly
  2. performnpm run buildTest whether the project can be packaged and compiled normally. The compiled directory structure is as follows
. ├ ─ ─ index. The HTML └ ─ ─ js └ ─ ─ main. 0 b16f9b82b7fb2c9ba47. Bundle. JsCopy the code

2.4 summarize

A basic React project has been set up, but it is far from enough to simply configure it. The above is just to show that it is very easy to build a basic React project. The rest of the work is to continuously expand the project configuration according to specific requirements. The following will start by simply extending the configuration of the project as needed, for example:

  • Webpack adds parsing of SCSS style files
  • Webpack adds image parsing
  • The project adds the ESLint configuration
  • Project add version release, Git Commit specification configuration
  • The project adds support for ANTD and configudes loading modules on demand

Add support for SCSS style files

3.1 the TODO

  1. Add support for CSS style files
  2. Added support for SCSS style files
  3. Use the mini-CSs-extract-plugin to replace the mini-CSs-extract-plugin
  4. Add CSS modularity support, yes.module.css .module.scssEnable modularity in style files

3.2 WebPack configuration modification

+ const MiniCssExtractPlugin = require('mini-css-extract-plugin');

+ const miniCssExtractPlugin = new MiniCssExtractPlugin({
+ filename: 'style/[name].[hash].css',
+ chunkFilename: 'style/[id].[hash].css',
+});

+ const cssRegex = /\.(css|scss)$/;
+ const cssModuleRegex = /\.module\.(css|scss)$/;

module.exports = {
  module: {
    rules: [              
+ {
+ test: cssRegex,
+ exclude: cssModuleRegex,
+ sideEffects: true,
+ use: [
+ {
+ loader: MiniCssExtractPlugin.loader,
+ options: {
+ hmr: process.env.NODE_ENV === 'development',
+},
+},
+ { loader: 'css-loader', options: { importLoaders: 1 } },
+ 'sass-loader',
+],
+},
+ {
+ test: cssModuleRegex,
+ use: [
+ {
+ loader: MiniCssExtractPlugin.loader,
+ options: {
+ hmr: process.env.NODE_ENV === 'development',
+},
+},
+ {
+ loader: 'css-loader',
+ options: {
+ modules: {
+ localIdentName: '[local]__[hash:base64]',
+},
+},
+},
+ 'sass-loader',
+],
+}
    ],
  },

  plugins: [
+ miniCssExtractPlugin,]};Copy the code

3.3 Installation Dependencies

  • css-loader
  • sass-loader
  • node-sass: scss
  • mini-css-extract-plugin
npm i mini-css-extract-plugin css-loader sass-loader node-sass -D
Copy the code

3.4 Code Testing

  1. createsrc/index.css
.css {
  padding-top: 20px;
}
Copy the code
  1. createsrc/index.module.css
.module-css {
  padding-right: 20px;
}
Copy the code
  1. createsrc/index.scss
.scss {
  padding-bottom: 20px;
}
Copy the code
  1. createsrc/index.module.scss
.module-scss {
  padding-left: 20px;
}
Copy the code
  1. Modify thesrc/index.js
import React from 'react';
import reactDom from 'react-dom';
+ import css from './index.module.css';
+ import scss from './index.module.scss';
+ import './index.css';
+ import './index.scss';

const App = () => (
+ <div className={`
+ css
+ scss
+ ${css['module-css']}
+ ${scss['module-scss']}
+ `} >
    test page
  </div>
);
reactDom.render(<App/>, document.getElementById('root'));
Copy the code
  1. Run the project to test that the style loads correctly

Add support for pictures

Url-loader is used for image processing. The plugin relies on file-loader

4.1 webpack modify

module.exports = {
  module: {
    rules: [              
+ {
+ test: /\.(png|jpg|gif|woff|svg|eot|ttf)$/,
+ use: [{
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: 'assets/[hash].[ext]',
+},
+}].
+},],}};Copy the code

4.2 Dependent Installation

npm i url-loader file-loader -D
Copy the code

4.3 test

SRC /index.js to see if it works

import React from 'react';
import reactDom from 'react-dom';
import Img from './1519971416-JDHjSqWCph.jpg';

const App = (a)= > (
  <div>
    <img src={Img} />
  </div>
);
reactDom.render(<App/>, document.getElementById('root'));
Copy the code

Five, esling configuration

5.1 WebPack Configuration Modification

Here you only need to add eslint-loader after babel-loader, with special attention to their order

module.exports = {
  module: {
    rules: [  
      {
        test: /\.(mjs|js|jsx)$/,
        exclude: /node_modules/,
+ use: ['babel-loader', 'eslint-loader'],},],}};Copy the code

5.2 Added under The Project.eslintrc.jsThe configuration file

module.exports = {
  parser: 'babel-eslint'.// Development environment Settings: No error will be reported when using global variables in the drop-down environment, such as Window, for undefined variables
  env: {
    browser: true.node: true     
  },

  // Define global variables. No error will be reported if the following global variables are used directly
  globals: {
    _: true.lodash: true,},// List of plug-ins
  plugins: [
    'react'.'import'.'react-hooks',].// Inheritance rules
  extends: [
    'eslint:recommended'.'plugin:react/recommended',].// Custom rule list
  rules: {
    // Enforces a semicolon after each statement
    "semi": [1."always"].}}Copy the code

5.3 Adding a File under the Project.eslintignore

# Set the files to ignore
/src/assets/*
Copy the code

5.4 Installation Dependencies

  • eslint
  • babel-eslint
  • eslint-loader
  • eslint-plugin-import
  • eslint-plugin-react
  • eslint-plugin-react-hooks
npm i eslint babel-eslint eslint-loader eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks -D
Copy the code

5.5 test

Modify the SRC/index. Js

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

const App = (a)= > (
  <div>
    test page
  </div>
)
reactDom.render(<App/>.document.getElementById('root'));
Copy the code

Rerun the project and throw a warning if the configuration is ok

5.6 Adding an NPM Script to automatically repair some codes with improper syntax

  "scripts": {
+ "eslint:fix": "eslint --fix ./src"
  },
Copy the code

NPM run ESLint :fix Fixes some of the non-conforming code in the project that can be fixed automatically by executing NPM run ESLint :fix

Introduce Antd and configure load on demand

Here we add the babel-plugin-import plug-in for the.babelrc configuration to enable antD loading on demand

6.1 to modify.babelrc

Note: When configuring the plug-in, you can set the instance name import-antd so that you can use the same plug-in multiple times, if you need to use babel-plugin-import for other component libraries

{
+ "plugins": [
+ ["import", {
+ "libraryName": "antd",
+ "libraryDirectory": "es",
+ "style": "css"
+ }, "import-antd"]
+],
  "presets": [
    "@babel/preset-react",
    "@babel/preset-env"
  ]
}
Copy the code

6.2 Dependent Installation

npm i antd
npm i babel-plugin-import -D
Copy the code

6, 3 test

Refer to the style in SRC /index to see if it works

import React from 'react';
import reactDom from 'react-dom';
+ import { Button } from 'antd';

const App = () => (
  <div>
+ 
  </div>
);
reactDom.render(<App/>, document.getElementById('root'));
Copy the code

7. Version release, Git Commit specification verification configuration

This section is based on my other article, Commit specification validation configuration and version release configuration. The following is a simple configuration method

7.1 Installing dependency Packages

#Husky packages installed
npm install husky --save-dev

#Commitlint requires package installation
npm install @commitlint/config-angular @commitlint/cli --save-dev

#Commitizen packages installed
npm install commitizen --save-dev
npm install commitizen -g

#Standard - version package installation
npm install standard-version --save-dev
Copy the code

7.2 Configuring commitLint and Commitizen

#Generate the Commitlint configuration file
echo "module.exports = {extends: ['@commitlint/config-angular']};" > commitlint.config.js
#Commitizen initialization
commitizen init cz-conventional-changelog --save-dev --save-exact
Copy the code

7.3 update package. Json

Script description:

  1. Release: Customizes the version to be released, for example:NPM run release -- 1.0.0
  2. Release :100: Execute the script, and if the current version is 1.0.0 the version will be promoted to 2.0.0
  3. Release :010: Execute the script, and if the current version is 1.0.0 the version will be upgraded to 1.1.0
  4. Release :001: Execute the script, and if the current version is 1.0.0 the version will be upgraded to 1.0.1
{
  "scripts": {
+ "commit": "git-cz",
+ "release": "standard-version --release-as",
+ "release:100": "npm run release -- major",
+ "release:010": "npm run release -- minor",
+ "release:001": "npm run release -- patch",
  },
+ "husky": {
+ "hooks": {
+ "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
+}
+}
}
Copy the code

7.4 commit way

  • Available when commitizen is installed globallygit czornpm run commitTo submit the code
  • This parameter can be used when Commitizen is not globally installednpm run commitTo submit the code

7.5 Release process

#1. Switch to the specified branch
git checkout master
#2. Update the code
git pull origin master
#3. Version release: Generate changelog. md and create a tagNPM run release -- --release-as 1.0.0#4. Update the tag to the remote branch
git push --follow-tags origin master
Copy the code

Eight, more configuration

8.1 Webpack Copies public Files

+ const CopyWebpackPlugin = require('copy-webpack-plugin');

+ const copyWebpackPlugin = new CopyWebpackPlugin(
+ [{ from: path.resolve(__dirname, '../public') }]
+);

module.exports = {
  plugins: [
+ copyWebpackPlugin,]};Copy the code

8.2 Defining global variables

+ const { DefinePlugin } = require('webpack');

+ const definePlugin = new DefinePlugin({
+ _DEV_: false,
+ GLOBAL_SERVICE: {
+ HOST: JSON.stringify('https://www.qianyin925.com:4000'),
+ GRAPHQL_URL: JSON.stringify('/graphql'),
+},
+});

module.exports = {
  plugins: [
+ definePlugin,]};Copy the code

8.3 Automatically loading dependencies

+ const { ProvidePlugin } = require('webpack');

+ const providePlugin = new ProvidePlugin({
+ _: 'lodash',
+ lodash: 'lodash',
+});

module.exports = {
  plugins: [
+ providePlugin,]};Copy the code

8.4 Webpack defines path aliases

module.exports = {
  resolve: {
+ alias: config.alias || {},}};Copy the code

8.5 Cross-env Sets environment variables

Advantages: Compatible with multiple platforms

{
  "scripts": {
+ "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"}}Copy the code

8.6 Raw-loader Used to Load text contents (. TXT and. Md files)

module.exports = {
  module: {
    rules: [
+ {
+ test: /\.(text|md)$/,
+ use: 'raw-loader',
+},]}};Copy the code