Build react+typescript+antd project from scratch

Step 1: create a project through create react app

npx create-react-app ai_video_project_frontend --template typescript


When you open the project in vscode, you can see that the react project is successfully generated and the suffix of the component is tsx. At this time, it indicates that the prototype of react+typescript project is successfully created

In the project root directory, run npm run start to start the project successfully

npm run start

Step 2: import antd

npm install antd -S

After installation, run npm run start again to start the project. If an error is found, you will be prompted with Could not find a declaration file for module 'react'

This is actually create react app 4 X version bug
The solution is as follows:

  1. Create react-app-env.exe in the project root directory d. TS file

    /// <reference types="react-scripts" />
    /// <reference types="node" />
    /// <reference types="react" />
    /// <reference types="react-dom" />
    
    declare namespace NodeJS {
      interface ProcessEnv {
        readonly NODE_ENV: 'development' | 'production' | 'test';
        readonly PUBLIC_URL: string;
      }
    }
    
    declare module '*.bmp' {
      const src: string;
      export default src;
    }
    
    declare module '*.gif' {
      const src: string;
      export default src;
    }
    
    declare module '*.jpg' {
      const src: string;
      export default src;
    }
    
    declare module '*.jpeg' {
      const src: string;
      export default src;
    }
    
    declare module '*.png' {
      const src: string;
      export default src;
    }
    
    declare module '*.webp' {
        const src: string;
        export default src;
    }
    
    declare module '*.svg' {
      import * as React from 'react';
    
      export const ReactComponent: React.FunctionComponent<React.SVGProps<
        SVGSVGElement
      > & { title?: string }>;
    
      const src: string;
      export default src;
    }
    
    declare module '*.module.css' {
      const classes: { readonly [key: string]: string };
      export default classes;
    }
    
    declare module '*.module.scss' {
      const classes: { readonly [key: string]: string };
      export default classes;
    }
    
    declare module '*.module.sass' {
      const classes: { readonly [key: string]: string };
      export default classes;
    }
    
    // declare module 'react-imageview';
    
    
  2. Delete node_modules folder and re execute npm install

  3. Execute npm run start again and the project runs successfully

Next, we continue to introduce antd
On app Add import 'ant D / dist / ant D css';, At the same time, the required antd components, such as Button, are introduced

import React from 'react';
import './App.css';
import 'antd/dist/antd.css';
import { Button } from 'antd';

function App() {
  return (
    <div className="App">
      <Button type="primary">Button</Button>
    </div>
  );
}

export default App;

You can see the effect:

At this point, the introduction of antd is completed

Step 3: configure packaging commands for different environments, such as test environment and production environment

  1. Install cross env

    npm i cross-env -D
    
  2. Configure package JSON command

    "scripts": {
        "serve": "cross-env REACT_APP_ENV=development node scripts/start.js",
        "build": "cross-env REACT_APP_ENV=production node scripts/build.js",
        "uat": "cross-env REACT_APP_ENV=uat node scripts/build.js",
        "sit": "cross-env REACT_APP_ENV=sit node scripts/build.js"
      },
    
  3. establish. env ,. env.development ,. env.production ,. env.uat ,. env.sit,
    .env

    REACT_APP_ENV=development
    

    .env.development

    REACT_APP_ENV=development
    

    .env.production

    REACT_APP_ENV=production
    

    .env.uat

    REACT_APP_ENV=uat
    

    .env.sit

    REACT_APP_ENV=sit
    

  4. Get the current environment variable from the project

    console.log(process.env.REACT_APP_ENV)
    

Step 4: configure routing

  1. Install react router Dom and @ types / react router DOM

    npm i react-router-dom @types/react-router-dom -S
    
  2. Create a views folder under src directory, and create page components in views, such as Index

  3. Create a router folder under src directory, configure the routing of each functional module under the folder, and create index Tsx, which uniformly introduces and exposes the routing of each functional module
    Function module commonrouter tsx:

    import { lazy } from "react";
    
    const Index = lazy(() => import("../views/Index/Index"));
    
    const CommonRouter: any = [
      {
        path: "/",
        component: Index,
        exact: true,
        title: "home page",
      },
    ];
    
    export default CommonRouter;
    
    


    index.tsx introduces the routing configuration of all functional modules for unified exposure

    import CommonRouter from "./CommonRouter";
    
    const routerConfig: any = [...CommonRouter]
    
    export default routerConfig;
    

  4. App. Route and customized route configuration are introduced into TSX

    import React, { Suspense, Component, Fragment } from "react";
    import { Route, Switch, Redirect, withRouter as realWithRouter } from "react-router-dom";
    // Here is the routing profile
    import routes from "./router/index";
    import 'antd/dist/antd.css';
    
    type StateType = {
      [propName: string]: any;
    };
    type PropType = {
      [propName: string]: any;
    };
    interface App {
      state: StateType;
      props: PropType;
    }
    
    // Get routing information
    const withRouter: any = realWithRouter;
    @withRouter
    class App extends Component {
      render() {
        return (
          <Fragment>
            <Suspense fallback={<div></div>}>
              <Switch>
                {routes.length > 0 &&
                  routes.map((route: any) => {
                    //Traversal routing array
                    const { path, component: C, exact } = route;
                    return (
                      <Route
                        exact={exact}
                        key={path}
                        path={path}
                        render={(props: any) => {
                          return <C {...props} />;
                        }}
                      />
                    );
                  })}
                {/* Automatically match to when entering / by default/ */}
                <Redirect exact from="/" to={"/"} />
                {/* The default invalid path is automatically matched to the first page */}
                <Redirect to="/" />
              </Switch>
            </Suspense>
          </Fragment>
        );
      }
    }
    
    export default App;
    
    
  5. Root directory index This is defined in TSX

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    import { BrowserRouter as Router } from "react-router-dom";
    
    
    ReactDOM.render(
      <React.StrictMode>
        <Router>
          <App />
        </Router>
      </React.StrictMode>,
      document.getElementById('root')
    );
    
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();
    
    

    At this point, the routing configuration is complete

Step 5: configure less

  1. Exposure configuration

    npm run eject
    

    At this time, there are more config folders in the project

  2. Install less and less- loader@5.0.0 (less loader must install the specified version 5.0.0)

    npm install less less-loader@5.0.0 -S
    
  3. Follow sass and modify the webpack. Config directory config. js

    ① Search cssRegex, add two lines of code and add less related rules

    // style files regexes
    const cssRegex = /\.css$/;
    const cssModuleRegex = /\.module\.css$/;
    const sassRegex = /\.(scss|sass)$/;
    const sassModuleRegex = /\.module\.(scss|sass)$/;
    const lessRegex = /\.less$/;
    const lessModuleRegex = /\.module\.less$/;
    

    ② Modify the getStyleLoaders function and add code

    {
      loader: require.resolve('less-loader'),
      options: lessOptions,
    },
    

    ③ Search cssRegex and add less configuration under css configuration

    // Opt-in support for LESS (using .less extensions).
    // By default we support LESS Modules with the
    // extensions .module.less
    {
      test: lessRegex,
      exclude: lessModuleRegex,
      use: getStyleLoaders(
        {
          importLoaders: 1,
          sourceMap: isEnvProduction
            ? shouldUseSourceMap
            : isEnvDevelopment,
        },
        'less-loader'
      ),
      // Don't consider CSS imports dead code even if the
      // containing package claims to have no side effects.
      // Remove this when webpack adds a warning or an error for this.
      // See https://github.com/webpack/webpack/issues/6571
      sideEffects: true,
    },
    // Adds support for CSS Modules, but using LESS
    // using the extension .module.less
    {
      test: lessModuleRegex,
      use: getStyleLoaders(
        {
          importLoaders: 1,
          sourceMap: isEnvProduction
            ? shouldUseSourceMap
            : isEnvDevelopment,
          modules: {
            getLocalIdent: getCSSModuleLocalIdent,
          },
        },
        'less-loader'
      ),
    },
    
  4. Restart the project, create the less file and import it


    The style takes effect, indicating that the less configuration is successful

Step 6: configure sass

The react project created through create react app actually has sass configured by default, so let's try to introduce sass files into the project first



The style takes effect, indicating that sass configuration is successful

Step 7: configure react Redux

  1. Install react Redux, @ types / react Redux, Redux thunk, @ types / Redux thunk

    npm install react-redux @types/react-redux redux-thunk @types/redux-thunk -S
    
  2. Create redux core module
    For example:

    ├── src
    │   └── redux
    │       ├── action
    │       │   ├── TestAction.tsx
    │       └── asyncAction
    │       │   ├── AsyncTestAction.tsx
    │       └── reducer
    │       │   ├── reducer.tsx
    │       │   └── TestReducer.tsx
    │       └── store.tsx
    

    reducer~TestReducer.tsx / / create testreducer

    interface StateType {
      name: string;
      age: number;
    }
    
    const commonState: StateType = {
      name: '',
      age: 0,
    };
    
    const TestReducer = (state = commonState, action: any): any => {
      switch (action.type) {
        case "CHANGE_NAME":
          return {
            ...state,
            name: action.payload.name,
          };
        case "CHANGE_AGE":
          return {
            ...state,
            age: action.payload.age,
          };
        case "ASYNC_CHANGE_NAME":
          return {
            ...state,
            addressObj: action.payload.name,
          };
        default:
          return state;
      }
    };
    
    export default TestReducer;
    
    

    reducer~reducer.tsx / / create and manage the configuration of all reducers

    import { combineReducers } from 'redux';
    // Introducing other reducer s
    import TestReducer from './TestReducer';
    
    // Merge all the introduced reducers into one reducers and expose them
    export default combineReducers({
      TestReducer,
    });
    

    action~TestAction.tsx / / create a method to synchronously change state

    export const changeName = (name: string) => {
      return {
        type: 'CHANGE_NAME',
        payload: {
          name
        }
      }
    }
    
    export const changeAge = (age: number) => {
      return {
        type: 'CHANGE_AGE',
        payload: {
          age
        }
      }
    }
    
    

    asyncAction~AsyncTestAction.tsx / / create a method to change state asynchronously

    export const asyncChangeName = () => {
      return async (dispatch: any) => {
        const countDown: Promise<any> = new Promise((resolve: any, reject: any) => {
          setTimeout(() => {
            resolve({
              name: 'Obtained by simulating network request name'
            })
          }, 1000)
        })
        const data: any = await countDown;
        const params: any = {
          type: 'ASYNC_CHANGE_NAME',
          payload: {
            name: data.name
          }
        };
        dispatch(params);
      }
    }
    
    

    store.tsx / / configure store

    import { createStore, applyMiddleware } from 'redux';
    
    import thunk from 'redux-thunk';
    
    import reducer from './reducer/reducer';
    
    export default createStore(reducer, applyMiddleware(thunk));
    
  3. Entry file index Tsx configuring redux

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    import { BrowserRouter as Router } from "react-router-dom";
    
    import { Provider } from 'react-redux';
    import store from './redux/store';
    
    ReactDOM.render(
      <Provider store={store}>
        <React.StrictMode>
          <Router>
            <App />
          </Router>
        </React.StrictMode>
      </Provider>,
      document.getElementById('root')
    );
    
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();
    

  4. redux is used in components, such as app Using redux in TSX:

    import React, { Suspense, Component, Fragment } from "react";
    // Here is the routing profile
    import { Route, Switch, Redirect, withRouter as realWithRouter } from "react-router-dom";
    import routes from "./router/index";
    
    // Common style
    import 'antd/dist/antd.css';
    import './assets/style/public.less';
    
    // redux
    import { changeName, changeAge } from "./redux/action/TestAction";
    import { asyncChangeName } from "./redux/asyncAction/AsyncTestAction";
    import { connect as realConnect } from "react-redux";
    
    type StateType = {
      [propName: string]: any;
    };
    type PropType = {
      [propName: string]: any;
    };
    interface App {
      state: StateType;
      props: PropType;
    }
    
    // Get redux
    const mapStateToProps = (state: any) => {
      return {
        state,
      };
    };
    const connect: any = realConnect;
    
    // Get routing information
    const withRouter: any = realWithRouter;
    @withRouter
    @connect(mapStateToProps, { changeName, changeAge, asyncChangeName })
    class App extends Component {
      componentDidMount() {
        // Call the synchronous action and asynchronous action methods of the specified reducer in redux
        this.props.changeName('Zhang San');
        this.props.changeAge(25);
        this.props.asyncChangeName();
        // Gets the state of the specified reducer in the reducer
        console.log(this.props.state.TestReducer);
      }
    
      render() {
        return (
          <Fragment>
            <Suspense fallback={<div></div>}>
              <Switch>
                {routes.length > 0 &&
                  routes.map((route: any) => {
                    //Traversal routing array
                    const { path, component: C, exact } = route;
                    return (
                      <Route
                        exact={exact}
                        key={path}
                        path={path}
                        render={(props: any) => {
                          return <C {...props} />;
                        }}
                      />
                    );
                  })}
                {/* Automatically match to when entering / by default/ */}
                <Redirect exact from="/" to={"/"} />
                {/* The default invalid path is automatically matched to the first page */}
                <Redirect to="/" />
              </Switch>
            </Suspense>
          </Fragment>
        );
      }
    }
    
    export default App;
    
    

At this point, the react project is created and configured

Article reference

https://www.cnblogs.com/gqx-html/p/13219422.html

Keywords: Front-end React TypeScript redux antd

Added by seran128 on Mon, 03 Jan 2022 08:58:54 +0200