React + WebPack4 介 绍 : React + WebPack4 介 绍 : React + Webpack4 介 绍 : React + Webpack4 介 绍 : React + Webpack4 介 绍 : React + Webpack4 截 图

usereact-router-domTo manage routes, use versions later than React-Router4.x. Note that there is a big difference between the use of router4.x and react-Router4.x

npm install -S react-router-dom
Copy the code

Why did we use react-router-dom?

React-router-dom: react-router-dom: react-router-dom: react-router-dom: react-router React-router builds on the react-Router and adds features that run in the browser environment, such as the Link component, which renders an A tag, BrowserRouter, and HashRouter components. React-router-dom is obviously more functional than react-router-dom. Therefore, react-router-dom is used instead of react-router

Following up on the project of the previous article, we will create a new page for blog, Resume, and User, as shown below

Separately writtenBlog, resume, User, home(Completed in the previous article) components

Delete home/index.less and modify the contents of home/index.js:

import React from 'react'
export default class HomeIndex extends React.Component {
    render(){
        return (
            <div>
                <p>HomeIndex</p>
            </div>
        )
    }
}
Copy the code

blog/index.js

import React from 'react'

export default class BlogIndex extends React.Component {
    render(){
        return (
            <div>
                <p>BlogIndex</p>
            </div>
        )
    }
}
Copy the code

resume/index.js

import React from 'react'

export default class ResumeIndex extends React.Component {
    render(){
        return (
            <div>
                <p>ResumeIndex</p>
            </div>
        )
    }
}
Copy the code

user/index.js

import React from 'react'

export default class UserIndex extends React.Component {
    render(){
        return (
            <div>
                <p>UserIndex</p>
            </div>
        )
    }
}

Copy the code

These are the simplest components

New SRC/router. Js

import React from "react" import { Route,BrowserRouter,Link,Switch } from "react-router-dom" import HomeIndex from "./home" import BlogIndex from "./blog" import ResumeIndex from "./resume" import UserIndex from "./user" class AppRouter extends React.Component { render(){ return ( <BrowserRouter> <ul> <li><Link to="/home">home</Link></li> <li><Link to="/blog">blog</Link></li> <li><Link to="/resume">resume</Link></li> <li><Link to="/user">user</Link></li> </ul> <div> {/* Switch displays only one component. Exact indicates the exact match /. If exact is not added, / XXX will match /. */} <Switch> {/* exact */} <Route path="/home" component={HomeIndex} /> <Route exact path="/blog" component={BlogIndex}/> <Route exact path="/resume" component={ResumeIndex}/> <Route exact path="/user" component={UserIndex}/> </Switch> </div> </BrowserRouter> ) } } export default AppRouter;Copy the code

Here, the react-router-dom history mode is used to write a simple navigation. Click each navigation to jump to the corresponding page. Run NPM run dev and open HTTP :localhost:8081

React-router-dom is basically used.

Because we are using it in conjunction with the project, the details of the react-router-dom will not be explained in detail. If you want to learn more about the basic usage, please check the official documentation. As the project gets more complex, we’ll talk about nested routines, jumping between pages, and so on.

Finally, we need to clear the default style of the page tag. You can get a copy of the code online, it’s everywhere. Then create static/ CSS /reset.min. CSS in the project root directory and import it in the index.html template

<link rel="stylesheet" href="/static/css/reset.min.css">
Copy the code

To run, you will find that I couldn’t find/static/CSS/reset. Min. CSS. Since we’re only importing files in index.html, we’re not dealing with static files in Webpack, so we need to build the contents of the static directory into the package via webpack plugins; The copy-webpack-plugin is needed here

npm install -D copy-webpack-plugin
Copy the code

In the build/webpack base. Config. Js ` add public plugin plugins,

Plugins :[new CopyWebpackPlugin([{from: utils. Resolve ('../static')), // copy from which directory to: "static", // copy to that directory. ['. * ']}]]Copy the code

Rerun and you will find that the default styles are cleared!

The introduction of antd

The tutorial is detailed here. This project uses the on-demand loading method to reduce the packaging volume.

useantd+react-router-domEncapsulating navigation components

Let’s take a look at the list of written projects

Due to the increasing amount of code, detailed code is not given here. If necessary, please click the source code to download Release 1.0.0 version

Here’s what these directories are for

The pages directory is the component of the page under the blog module. Here we create two new pages to add. List.js Blog list index.js is a component that manages the child routes of the BOLG module. The code is as follows

import React from 'react' import BlogListPage from "./pages/list" import AddBlogPage from "./pages/add" import { Route }  from 'react-router-dom' export default class BlogIndex extends React.Component { render(){ return ( <div> <p>BlogIndex</p> <Route path="/blog/list" component={BlogListPage} /> <Route path="/blog/add" component={AddBlogPage} />  </div> ) } }Copy the code



If this attribute is added to the parent route, the child route cannot match.



If you type /blog/add path, there will be no Route matching. It will only match if you enter the /blog path. Multi-level routing can be managed by fuzzy matching path.

Navigationbar.js is the NavigationBar. Slidemenu.js is the side menu. Resume is the immediate module. Router.config. js is the route and the left menu of the project. Router.js is the route and the overall layout of the project

The effect of the implementation:

Note: 1. You will notice that the HTML tag of this project uses the class attribute instead of the className attribute. The React HTML tag does not support the class attribute. It only recognizes the className attribute. Here we need to install a plug-in

npm install -D babel-plugin-react-html-attrs
Copy the code

Then add “react-html-attrs” to the pulgins array of the.babelrc file

We use the Class component to write the React component. We can also use the function component to write the React component if necessary. When we use class and add attributes to class, the project will get an error at compile time

export default class BlogIndex extends React.Component {
    state = {
        test:"name"
    }
    click = ()=>{   
    }
}
Copy the code

Error as follows:

The solution:

npm install -D @babel/plugin-proposal-class-properties
Copy the code

Then add “@babel/plugin-proposal-class-properties” to the pulgins array of the.babelrc file

usemobxManagement data

React mobx: Mobx mobx: Mobx mobx: Mobx React Install the two required packages first

npm install -S mobx mobx-react
Copy the code

Mobx mobx-React is a combination of MOBx and React. It provides a Provider to manage MOBx data in a unified manner. Inject a Mobx instance for the React component; The Observer implements mobx bi-directional binding between the React component and MOBX data (similar to react-Redux connect), etc

createmobxInstance and inreactImport file import

Create a mobx instance that manages the user list page by creating store/ userlist. js in the user directory

import { observable,action } from "mobx" class UserListStore { @observable name; constructor(){ this.name = "my name is user list;" ; } } export default new UserListStore();Copy the code

Create a store/index.js directory under SRC to manage the mobx instance of your project:

import UserListStore from "./.. /user/store/UserList" const store = { UserListStore } export default store;Copy the code

After modifying SRC /index.js, import the file

import { Provider } from "mobx-react"
import store from "./store"
Copy the code

Use Provider, store

<Provider {... store}> <AppRouter /> </Provider>Copy the code

Rerun the project, error as expected. Why is that? Those familiar with MOBx know that mobx features decorators to modify properties and methods in MOBx instances, and that React-Mobx is also used through decorators.

Decorators can be associated with methods via the @ keyword. To add additional functionality to properties, methods, and classes. The effect of decorator is actually very large, such as Java Spring is the most widely used, students who want to learn can go to the relevant information.

We need to configure support for decorators in the project

NPM install -d @babel/plugin-proposal-decorators, add to the pulgins array in the.babelrc file

["@babel/plugin-proposal-decorators",{"legacy": true}], // Configure support for decoratorsCopy the code

Modify “@babel/plugin-proposal-class-properties” to

["@babel/plugin-proposal-class-properties",{"loose":true}Copy the code

Note that this configuration must come after @babel/plugin-proposal-decorators, otherwise it will still get an error.

reactUse in componentsmobx

throughinjectThe need tomobxInstance injection intoreactcomponent

Modify the SRC/user/pages/list. Js

import React from 'react' import {withRouter} from 'react-router-dom' import {Button} from "antd" import { inject, observer } from "mobx-react" @inject("UserListStore") class UserListPage extends React.Component { push = ()=>{ this.props.history.push("/user/add? name=231"); } render(){ const {UserListStore} = this.props; Return (<div> <p>UserListPage</p> <p> component: {userListStore.name}</p> <Button onClick={this.push}>} export default withRouter(UserListPage);Copy the code

foundmobxIn theUserListStoreInstance injection intothis.propsIn the

In the class component, modify the component using @Observer and add the setName method

setName = ()=>{
    const {UserListStore} = this.props;
    UserListStore.setName("ha ha ha")
}
Copy the code

Add a button to change the name

<Button onClick={this.setName}>Copy the code

Click the button and you will see that {userListStore. name} becomes ha ha ha. This indicates that the component data bidirectional binding has been successful

Test package, everything is fine!

To introduce the Mobx code, download the source releases 1.0.1

Set upmockService (Node)

In order to better simulate the front – end separation scenario, a new service is constructed

The mock directory is created in the project root, where koA is used to build a Node service. Koa builds the Node service relatively easy, here will not say how to build the node service. If you need to check out the React project I wrote earlier, which integrates express+ Mock to simulate interface data, the express framework is replaced by the KOA framework. Then CD mock, execute NPM run dev, and the service starts normally. The port is 8082.

Focusing on mocks, here we use MockJS to simulate data and need to install mockJS in the mock directory

npm install -S mockjs
Copy the code

Directory structure:

Let’s create a new user module. User /data.js emulated the records of the database. Here the simulation produces 10 user records, and as long as they are generated, there is no change to user/data.js

const Mock = require("mockjs") const data = Mock.mock({ 'list|1-10': [{ 'id|+1': 1, 'user_id|100-200': 1, 'status|1': True, / / state 'user_name' : '@ cname, / / name' avatar ': "@ image (' 150 x150 ', '# 4 a7bf7', 'img', 'the PNG', 'the Tiger')", / / avatar 'create_time' : '@ datetime (" MM - dd yyyy - HH: MM: ss ")', / / creation date}}); Module. exports = data; // exports = exports;Copy the code

The contents of user/index.js are as follows

const Router = require("koa-router") const router = new Router(); const Mock = require("mockjs") const userlist = require("./data").list; router.get("/api/user/list",async (ctx)=>{ ctx.body = {code:0,message:"success",userlist} }); router.post("/api/user/add",async (ctx)=>{ let data = ctx.request.body; data.id = userlist[userlist.length-1].id + 1; Const mock = mock. Mock ({user_id '|' 100-200:1, the 'status' | 1' : false, / / state 'avatar' : "@ image (' 150 x150 ', '# 4 a7bf7', 'img', 'the PNG', 'the Tiger')", / / avatar 'create_time' : '@dateTime (" YYYY-MM-DD HH: MM :ss")', // create date}) data = object. assign(data,mock); userlist.push(data) ctx.body = {code:0,message:"success"} }); module.exports = router;Copy the code

Here you simulate requesting a list of users (no paging), adding a user interface.

Postman requests interface data, as shown below

reactThe project requestmockdata

Install in front end projects

npm install -S axios
Copy the code

Because it involves cross-domain, we need to add the proxy under the devServer property of webpack.dev.config.js in our development environment

Proxy: {/ / interface request broker "/ API" : {secure: false target: "http://127.0.0.1:8082"}},Copy the code

Then need to be modified in the SRC/user/store/UserList js, list here for requesting user interface, and assignment to the instance of the UserList properties

import { observable,action } from "mobx"
import axios from "axios"

class UserListStore {

    @observable userList;

    constructor(){
        this.userList = [];
    }

    @action
    async getUserList(){
        const config = {method:"get",url:"/api/user/list"};
        const result = await axios(config);
        if(result.data.code === 0){
            const userList = result.data.data;
            this.userList = userList;
        }
    }
}

export default new UserListStore();
Copy the code

Call the SRC /user/pages/list.js page, and render the user list

componentDidMount(){
    const {UserListStore} = this.props;
    UserListStore.getUserList();
}
render(){
    const {UserListStore} = this.props;
    return (
        <div>
            {
                UserListStore.userList.map((item,index)=><p key={index}>{item.user_name}</p>)
            }
        </div>
    )
}
Copy the code

The diagram below:

Mock + Data request source releases 1.0.2

Here, React family bucketreact+react-router+mobx+axiosThe use ofmockSimulating back-end data is complete. What follows is the editing of business logic pages (omitted here), and packaging optimizations (covered in the next article). Of course, there are still many imperfections in the project (module organization, division of directory structure, encapsulation of request instances, separation of attempts from business logic, style management, etc., which are closely related to business logic, but will not be explained here).

So let’s do thatnpm run build, packed successfully. However, there is a problem, the js package is as high as 1M, it is terrible. Right now the project is simple, but as the business logic gets more complex and pages grow, the js packages will get bigger and bigger. In the next article we will optimize the packaging step by step, from lazy loading of routes, pulling out styles, and pulling out public third-party packages

React + WebPack4 build a front-end project (3) package optimization

React +webpack4+ React – Router5 + React -loadable+mobx

React + WebPack4 Build front-end projects (1) Build infrastructure projects

React + WebPack4 设 置 Front-End project

React + WebPack4 Build front-end project (3) Package optimization

If you often order take-out small friends, xiaobian to recommend a benefit. You can get a large takeaway red envelope for free every day, get it every day, no longer need to open a membership, save a breakfast every day.Click for detailsThe attached small program code is shown below: