The React project uses ‘@’ to replace SRC paths with console.log(), route lazy loading, and CDN to optimize redux usage

Redux Route is used and parameters are transmitted

1. Use craco to configure path alias ‘@’

In a React scaffolding project: the CRA(create-react-app) hides all the engineered configurations in the React-scripts package, so there is no configuration information or configuration files in the project.

If you want to change the default CRA configuration, there are several options:

  1. 【 recommended 】 Use third-party libraries to modify, for example,@craco/craco
  2. By performingyarn ejectCommand, releasereact-scriptsTo the project (note: this operationThe irreversible!!!!!!!!!)

1.craco:

Craco is a custom configuration tool for create-React-app.

2. Procedure of using Craco

  1. The installation package. npm i -D @craco/craco

  2. In the project root directory, create the configuration file: craco.config.js. Custom changes can be made in the configuration file.

    Configure path alias in craco.config.js:

const path = require('path')
module.exports = {
  webpack: {
    alias: {
      The '@': path.join(__dirname, 'src')}}}Copy the code

3. Modify the script command in package.json

Package. The json:

// Change the start, build, and test commands to craco mode

"scripts": {
  "start": "craco start"."build": "craco build"."test": "craco test"."eject": "react-scripts eject"
}
Copy the code
  1. In your code, you can pass@To represent thesrcThe absolute path to the directory
  2. Restart the project for the configuration to take effect

2. Vscode identifies @ and prompts the path

When vscode opens the React project configured with Craco, @ path will not be prompted. You need to configure jsconfig.json file in the root directory:

// VSCode automatically reads the configuration in 'jsconfig.json' to let VSCode know that @ is the SRC directory
{
  "compilerOptions": {
    "baseUrl": ". /"."paths": {
      "@ / *": ["src/*"]}}}Copy the code

3.React Project packaging and optimization

1. Project packaging:

  1. Open the terminal in the project root directory and enter the package command:npm run build(See package.json file for the actual command)
  2. After the packaging is complete, the packaged content is placed in the Build folder under the project root

2. Project Preview:

  1. Install local service pack globally:npm i -g serve, the package providesserveCommand to start the local service
  2. Execute the command in the project root directory:serve -s ./buildStart the server in the build directory
  3. Preview the project in your browser

3. Package volume analysis

By analyzing the package volume, we can know which parts of the project are too large and how to optimize them

  1. Install analysis package volume package:npm i source-map-explorer
  2. In the scripts TAB of package.json, add the command to analyze the package volume:
"scripts": {
  "analyze": "source-map-explorer 'build/static/js/*.js'",}Copy the code
  1. Package the project:npm run build(Skip this step if you have already packed)
  2. Run the analysis command:npm run analyze
  3. Analyze the package volume in the diagram from the page that opens in your browser

4. Optimized the production environment

Depending on whether the thunk middleware in REdux is optimized for production, see Redux in React for redux and Thunk middleware

let middlewares

if (process.env.NODE_ENV === 'production') {
  // In production environment, only thunk middleware is enabled
  middlewares = applyMiddleware(thunk)
} else {
  middlewares = composeWithDevTools(applyMiddleware(thunk))
}
Copy the code

5. Lazy route loading

  1. inAppRoot component, importSuspensecomponent
  2. inRouterInternal, useSuspenseComponent wraps component content
  3. forSuspenseComponent providesfallbackProperty to specify loading placeholder content (slow loading is what the page displays)
  4. The importlazyFunction and modify the lazy load mode to import the routing component
// Import lazy and Suspense components
import { lazy, Suspense } from 'react'

// lazy imports the page component
const Login = lazy(() = > import('./pages/Login'))
const Layout = lazy(() = > import('./pages/Layout'))

const App = () = > {
  return (
    <Router>
      <Suspense
        fallback={
          <div
            style={{
              textAlign: 'center',
              marginTop: 200
            }}
          >loading... // The fallback property configures what is displayed at load time</div>
        }
      >
        <div className="app">
          <Route path="/login" component={Login}></Route>
          <Route path="/home" component={Layout}></Route>
        </div>
      </Suspense>
    </Router>)}export default App
Copy the code

6. Remove the console console

The terser-webpack-plugin package is used to remove console.log().

Webpack V5 comes out of the box with the latest version of the Terser-Webpack-plugin. If you are using WebPack V5 or later and want to customize the configuration, you still need to install the Terser-webpack-plugin. If you use Webpack V4, you must install the version of Terser-webpack-Plugin V4.

Note: before configuration, you need to confirm which version of Webpack to use. Install the corresponding version package: NPM I [email protected]

In the craco.config.js file, the configuration is as follows (the craco.config.js file has craco configured on it):

const path = require('path')
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
  webpack: {
  // Configure to identify the @ path
    alias: {
      The '@': path.join(__dirname, 'src')},plugins: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: process.env.NODE_ENV === 'production'
            // Remove all content from the console in production}}})]}}Copy the code

7. Configuration CDN

Complete craco.js file

const path = require('path')
const TerserPlugin = require('terser-webpack-plugin')
const { whenProd, getPlugin, pluginByName } = require('@craco/craco')
module.exports = {
  webpack: {
  / / @
    alias: {
      The '@': path.join(__dirname, 'src')},/ / removed from the console. The log ()
    plugins: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: process.env.NODE_ENV === 'production'
            // Remove all content from the console in production}}})].// CDN
    configure: (webpackConfig) = > {
      let cdn = {
        js: [].css: []}// Configure webPack
      whenProd(() = > {
        // Will only be executed in production
        webpackConfig.externals = {
          react: 'React'.'react-dom': 'ReactDOM'.redux: 'Redux'
        }
        cdn = {
          js: [
            'https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.production.min.js'.'https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js'.'https://cdn.bootcdn.net/ajax/libs/redux/4.1.0/redux.min.js'].css: []}})const { isFound, match } = getPlugin(
        webpackConfig,
        pluginByName('HtmlWebpackPlugin'))if (isFound) {
        // The HTML plugin was found
        match.options.cdn = cdn
      }
      return webpackConfig
    }
  }
}

Copy the code

Import the corresponding file in the public folder index. HTML

<! DOCTYPE html><html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="# 000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />

    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
 
    <title>React App</title>
    <% htmlWebpackPlugin.options.cdn.css.forEach(cdnURL => { %>
      <link rel="stylesheet" href="<%= cdnURL %>"></link>The < %}) % ></head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
   
    <% htmlWebpackPlugin.options.cdn.js.forEach(cdnURL => { %>
      <script src="<%= cdnURL %>"></script>The < %}) % ></body>
</html>

Copy the code