Most React projects are now initialized with create-React-app, and the default WebPack configuration is sufficient for normal projects. Create-react-app: Create-React-app: Create-React-app: Create-React-app: Create-React-app

How to speed up builds

If you write too much code, webPack is slow to start every time, so you can optimize the experience by removing the configuration and adding multithreading.

Get rid ofeslint-loader

The eslint-loader function displays esLint detected content on the command line, which can be removed if the code is written correctly. The webpack-dev-server startup speed is significantly improved after removal.

Remove the code above

usethread-loaderorhappypack

Thread-loader will run subsequent loaders in a worker pool to achieve multi-threaded builds. Each worker is a separate Node.js process with a 600ms limit. In addition, cross-process data exchange is restricted. Use this method in high-overhead Loaders.

{
  test: /\.(js|ts)x? $/i.use: [
    'thread-loader',
    {
      loader: 'babel-loader'.options: {
        cacheDirectory: true,}},],exclude: /node_modules/,},Copy the code

Happypack speeds up the build process through multi-threaded concurrency, but package authors are rarely maintained these days and thread-Loader is recommended. The configuration is slightly complex and not very friendly to complex JS less configurations.

**exports.plugins = [
  new HappyPack({
    id: 'jsx'.threads: 4.loaders: [ 'babel-loader']}),new HappyPack({
    id: 'styles'.threads: 2.loaders: [ 'style-loader'.'css-loader'.'less-loader']})]; exports.module.rules = [ {test: /\.js$/.use: 'happypack/loader? id=jsx'
  },

  {
    test: /\.less$/.use: 'happypack/loader? id=styles'
  },
]**
Copy the code

If you’re lazy, select Thread-Loader and add a line of code.

The react – app – rewired and customize – cra

What if you don’t want the Eject project?

React-app-rewired can modify the built-in Webpack configuration of create-React-app without eject or creating additional react-scripts, and then you’ll have all the features of create-React-app, Webpack plugins, loaders, etc. can be configured according to your needs, and it is recommended to use it together with customize-cra.

Method of use

yarn add react-app-rewired customize-cra -D
Copy the code

Change the package. The json

  /* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test --env=jsdom",
+ "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts eject"
}
Copy the code

Create the config-overrides. Js file in the root directory and change it to the configuration you want

const {
  override,
  addDecoratorsLegacy,
  disableEsLint,
  addBundleVisualizer,
  addWebpackAlias,
  adjustWorkbox
} = require("customize-cra");
const path = require("path");

module.exports = override(
  // enable legacy decorators babel plugin
  addDecoratorsLegacy(),

  // disable eslint in webpack
  disableEsLint(),

  // add webpack bundle visualizer if BUNDLE_VISUALIZE flag is enabled
  process.env.BUNDLE_VISUALIZE == 1 && addBundleVisualizer(),

  // add an alias for "ag-grid-react" imports
  addWebpackAlias({
    ["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")}),// adjust the underlying workbox
  adjustWorkbox(wb= >
    Object.assign(wb, {
      skipWaiting: true.exclude: (wb.exclude || []).concat("index.html")})));Copy the code

Customized use

Add less

Create-react-app enables SASS preprocessor compilation by default. To use less, you need to manually add sASS preprocessor compilation. In addition to CSS modules, its built-in this type of file that is used / \. The module \. (SCSS | sass) $/ or / \. The module \. CSS $/ testing. If you want to enable CSS modules on.css or.less directly, you need to write two loader processing rules for SRC and node_modules, because files under node_modules do not need to enable CSS modules.

Create-react-app built-in rules

Install dependencies related to less

yarn add less less-loader -D
Copy the code

Less, CSS files under the SRC folder, and open the CSS modules, to note here, it is not configured for node_modules style file, don’t need to open under the node_modules CSS modules, or cause problems.

// webpack.config.js
{
  test: /\.(le|c)ss$/i.use: [
    isProd
      ? {
          loader: MiniCssExtractPlugin.loader,
        }
      : 'style-loader',
    {
      loader: 'css-loader'.options: {
        modules: {
          localIdentName: isProd ? '[hash:base64]' : '[path][name]__[local]--[hash:base64:5]',},},}, {loader: 'less-loader'.options: {
        javascriptEnabled: true,
      },
    },
  ].filter(Boolean),
  include: srcPath,
},
Copy the code

Configuration of node_modules

{
  test: /\.(le|c)ss$/i.use: [
    isProd
      ? {
          loader: MiniCssExtractPlugin.loader,
        }
      : 'style-loader'.'css-loader',
    { loader: 'less-loader'.options: { javascriptEnabled: true } },
  ].filter(Boolean),
  include: [/node_modules/],},Copy the code

Source code analysis summary

terser-webpack-plugin

Newer versions of scaffolding use terser-webpack-plugin to compress JS code and UglifyJS is no longer recommended.

Terser introduced it this way: Uglip-ES is no longer maintained, and Uglip-JS does not support ES6+ syntax.

Simple to use

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  optimization: {
    minimize: true.minimizer: [new TerserPlugin()],
  },
};
Copy the code

File-loader is placed at the end, and the file is automatically compiled tostatic/mediadirectory

In webpack.config.js, file-loader is the last one in oneOf’s array, indicating that if any file does not match any of the previous loaders, file-loader takes over. Exclude indicates that it does all of this, renames the file by default, and copies it to the build/static/media/ directory.

Do not add loader after file-loader, because all remaining files will be processed by file-loader

// "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename.
// In production, they would get copied to the `build` folder.
// This loader doesn't use a "test" so it will catch all modules
// that fall through the other loaders.
{
  loader: require.resolve('file-loader'),
  // Exclude `js` files to keep "css" loader working as it injects
  // its runtime that would otherwise be processed through "file" loader.
  // Also exclude `html` and `json` extensions so they get processed
  // by webpacks internal loaders.
  exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
  options: {
    name: 'static/media/[name].[hash:8].[ext]',}},// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
Copy the code

The difference between file-loader and url-loader

Options. name is the same as file-loader. File-loader is the degraded version of url-loader. Url-loader will convert the file to base64 encoding and insert it into HTML, not as a separate file. This will reduce the number of requests made by the page. Then use file-loader to rename and copy the file to the build/static/media directory.

// "url" loader works like "file" loader except that it embeds assets
// smaller than specified limit in bytes as data URLs to avoid requests.
// A missing `test` is equivalent to a match.
{
  test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
  loader: require.resolve('url-loader'),
  options: {
    limit: imageInlineSizeLimit, // Built-in is 10000 bytes
    name: 'static/media/[name].[hash:8].[ext]',}},Copy the code

Momentjs redundant multilingual document

If using Momentjs in Ant Design or directly using momentjs, the default is to type in all the multi-language packages (node_modules/moment/local/*.js), which will increase the volume of the package, but we won’t be using so many languages, so we need to exclude them.

plugins:[
    ...,
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
]
Copy the code

env

Create-react-app presets parameters to process.env with.env. XXX. For details, see react-scripts/config/env.js.

The core code

Load the configuration from the following files
const dotenvFiles = [
  `${paths.dotenv}.${NODE_ENV}.local`.// Local use is recommended
  `${paths.dotenv}.${NODE_ENV}`.//.env.production or.env.developmentNODE_ENV ! = ='test' && `${paths.dotenv}.local`.// Local use is recommended
  paths.dotenv, // .env
].filter(Boolean);
Copy the code
// Apply the Settings of the.env file to process.env
dotenvFiles.forEach(dotenvFile= > {
  if (fs.existsSync(dotenvFile)) {
    require('dotenv-expand') (require('dotenv').config({
        path: dotenvFile, }) ); }});Copy the code

REACT_APP_ will be injected into the global process.env via new webpack.defineplugin (env.stringified).

// env.js
const REACT_APP = /^REACT_APP_/i;

function getClientEnvironment(publicUrl) {
  const raw = Object.keys(process.env)
    .filter(key= > REACT_APP.test(key))
    .reduce(
      (env, key) = > {
        env[key] = process.env[key];
        return env;
      },
      {
        // Preset two
        NODE_ENV: process.env.NODE_ENV || 'development'.PUBLIC_URL: publicUrl,
      }
    );
  // Stringify all values so we can feed into Webpack DefinePlugin
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) = > {
      env[key] = JSON.stringify(raw[key]);
      returnenv; }, {})};return { raw, stringified };
}
Copy the code

So you can happily set some variables

// .env
REACT_APP_IS_ENV_FILE=TRUE

// .env.development
REACT_APP_IS_DEV_ENV_FILE=TRUE

// .env.local
REACT_APP_IS_LOCAL_ENV_FILE=TRUE
Copy the code

Print in the browser

babel-preset-react-app

Babel-react-app is a package under create-react-app that is the default Babel preset to create-react-app and can be used to process JS and TS. In this way, there is no need for additional configuration of TS-Loader. In addition, it supports some built-in FUNCTIONS of TS (decorators, etc.), which can be used easily.

Introducing babel-preth-react-app in our Webpack configuration simplifies configuration.


Welcome to my nuggets and public accounts, algorithms, TypeScript, React and their source ecology.