Bootstrap

React create-react-app脚手架配置

一.项目创建

打开cmd,安装全局安装 create-react-app 

npm install -g create-react-app

打开到指定路径,创建项目

create-react-app myreact

执行npm start,启动项目

:在开始配置之前,做一些准备工作,先安装react-app-rewired插件,这个插件很重要,由于react脚手架将webpack的配置文件进行了封装,我们在目录中式看不到webpack.config.js文件,官方文档给出 eject 指令,但是此命令是不可逆的,所以在不动文件结构的情况下,使用该插件,与此同时在之后的配置中也要用到这个插件。

$ npm install react-app-rewired customize-cra --save-dev

修改package.json的配置 


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

 在根目录下创建文件config-overrides.js,这里我们先配置alias文件路径别名

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

module.exports = override(
    //增加路径别名的处理
    addWebpackAlias({
        '@': path.resolve('./src')
    })
);

二.配置路由,我这里下载react-router-dom最新版本V6

npm install react-router-dom

在src下建立router.js,引入组件

import React from "react";
import { BrowserRouter, Route, Routes, Navigate } from "react-router-dom";
import Home from "@/views/Home/Home";
import About from "@/views/About/About";
import Index from "@/views/Index/Index";

export default function Router() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path='index' element={<Index />} >
            <Route path="home" element={<Home />}/>
            <Route path="about" element={<About />}/>
        </Route>
        {/* 重定向到首页 */}
        <Route path="/" element={<Navigate to="index"/>} />
        {/* 或者跳转到 NotFound */}
        {/* <Route path="*" element={<NotFound />} /> */}
      </Routes>
    </BrowserRouter>
  );
}

挂载到App.js,

import './App.css';
import Router from "@/router/router.js"
function App() {
  return (
    <div className="App">
      <Router/>
    </div>
  );
}

export default App;

这样我们路由的设置就算完成了

三.配置Redux

安装redux,最新版本4.2.1,使用redux工具包实现

npm install --save redux react-redux 
npm i --save @reduxjs/toolkit

在src下创建store.js文件

import { configureStore } from "@reduxjs/toolkit"
import DemoSlice from "./DemoSlice"
export default configureStore({
    reducer: {
        // 这里放入各个模块
        DemoSlice
    },
})

 DemoSlice文件:

import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";

const DemoSlice = createSlice({
    name: "demo",
    initialState: {
        count:0
    },
    reducers: {
        setDemoCount(state, action) {
            state.count = action.payload
        }
    }
})

export default DemoSlice.reducer;
export const { setDemoCount } = DemoSlice.actions
//创建异步方法
export const getData = createAsyncThunk("order/fetchDemoData", async (data, { dispatch }) => {
    
})

引入到页面使用

import { useSelector,useDispatch } from 'react-redux';
import { setDemoCount } from '@/redux/DemoSlice.js';
import { Button } from 'antd';
import "./Home.less"
import { Component } from 'react';

export default function Home(){
    const {DemoSlice} = useSelector(state=>state)
    const dispatch = useDispatch()
    console.log(Component);
    return (
        <div className="container">
            <span>{DemoSlice.count}</span>
            <button onClick ={()=>{
                dispatch(setDemoCount(5))
            }}>更改</button>
            <Button type="primary">123</Button>
        </div>
    )
}

 

在App.js中全局挂载

import './App.css';
import Router from "@/router/router.js"
import store from "./redux/store.js"
import {Provider} from "react-redux"
function App() {
  return (
    <Provider store={store}>
      <div className="App">
        <Router/>
      </div>
    </Provider>
  );
}

export default App;

四.配置UI组件库Antd,按需引入

下载Antd组件库

npm install antd --save

下载插件

npm install babel-plugin-import --save-dev

 配置config-overrides.js

const { override, fixBabelImports, addWebpackAlias } = require("customize-cra");
const path = require("path");

module.exports = override(
    // 针对antd 实现按需打包:根据import来打包 (使用babel-plugin-import)
    fixBabelImports("import", {
        libraryName: "antd",
        libraryDirectory: "es",
        style: true, //自动打包相关的样式 默认为 style:'css'
    }),
    //增加路径别名的处理
    addWebpackAlias({
        '@': path.resolve('./src')
    })
);

五.配置less

antd是样式使用less语法,那么less语法也要配置一下

先下载依赖,下载时注意版本问题,如果过高会报错

npm install less less-loader --dev

 配置config-overrides.js

const { override, fixBabelImports, addLessLoader, addWebpackAlias} = require("customize-cra");
const path = require("path");

module.exports = override(
    // 针对antd 实现按需打包:根据import来打包 (使用babel-plugin-import)
    fixBabelImports("import", {
        libraryName: "antd",
        libraryDirectory: "es",
        style: true, //自动打包相关的样式 默认为 style:'css'
    }),
    // 使用less-loader对源码重的less的变量进行重新制定,设置antd自定义主题
      addLessLoader({
            javascriptEnabled: true,
            modifyVars: { "@primary-color": "#1DA57A" },
      }),
    //增加路径别名的处理
    addWebpackAlias({
        '@': path.resolve('./src')
    })
);

如果不是版本问题,就是要更改配置,报错如下:

1cc4a5eec8ed41909aa38dbb6123301b.png

主要是配置问题,少了lessOptions,重新修改配置config-overrides.js

const { override, fixBabelImports, addLessLoader, addWebpackAlias} = require("customize-cra");
const path = require("path");

module.exports = override(
    // 针对antd 实现按需打包:根据import来打包 (使用babel-plugin-import)
    fixBabelImports("import", {
        libraryName: "antd",
        libraryDirectory: "es",
        style: true, //自动打包相关的样式 默认为 style:'css'
    }),
    // 使用less-loader对源码重的less的变量进行重新制定,设置antd自定义主题
      addLessLoader({
        lessOptions:{
            javascriptEnabled: true,
            modifyVars: { "@primary-color": "#1DA57A" },
        }
      }),
    //增加路径别名的处理
    addWebpackAlias({
        '@': path.resolve('./src')
    })
);

然后继续报错了:

dfadc43327494d49aee597e06fda153d.png

这次是postCss配置出了问题,继续修改配置:

const { override, fixBabelImports, addLessLoader, addWebpackAlias,adjustStyleLoaders } = require("customize-cra");
const path = require("path");

module.exports = override(
    // 针对antd 实现按需打包:根据import来打包 (使用babel-plugin-import)
    fixBabelImports("import", {
        libraryName: "antd",
        libraryDirectory: "es",
        style: true, //自动打包相关的样式 默认为 style:'css'
    }),
    // 使用less-loader对源码重的less的变量进行重新制定,设置antd自定义主题
      addLessLoader({
        lessOptions:{
            javascriptEnabled: true,
            modifyVars: { "@primary-color": "#1DA57A" },
        }
      }),
    //增加路径别名的处理
    addWebpackAlias({
        '@': path.resolve('./src')
    }),
    adjustStyleLoaders(({ use: [, , postcss] }) => {
        const postcssOptions = postcss.options;
        postcss.options = { postcssOptions };
    })
);

以上就是配置完了,但是在我成功启动之后,再次删除这两个修改的配置,恢复到原来重启也不报错了,就是第一次编译会有问题。 

六.配置代理

在src下新建文件setupProxy.js,因为是最新的配置,所以用新的写法,使用分别暴露,配置如下:

const { createProxyMiddleware } = require('http-proxy-middleware') // 分开暴露的方式

module.exports = function(app) {
    app.use(
        createProxyMiddleware('/api1', {
            target: 'http://test.cn',//目标接口或域名
            changeOrigin: true, //是否启用跨域
            pathRewrite: {'^/api1': ''},
        })
    )
}

重启项目即可 

七.配置axios请求

下载安装axios

npm install axios --save

 src创建api文件下并配置http.js文件

/**
 * 网络请求配置
 */
import axios from "axios";



axios.defaults.timeout = 100000;
if (process.env.NODE_ENV == 'development') {    
    axios.defaults.baseURL = 'https://www.baidu.com';
} else if (process.env.NODE_ENV == 'debug') {    
    axios.defaults.baseURL = 'https://www.ceshi.com';
} else if (process.env.NODE_ENV == 'production') {    
    axios.defaults.baseURL = 'https://www.production.com';
}
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8';
axios.defaults.headers.get['Content-Type'] = 'application/json;charset=utf-8;';

/**
 * http request 拦截器
 */
axios.interceptors.request.use(
    (config) => {
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

/**
 * http response 拦截器
 */
axios.interceptors.response.use(
    (response) => {
        if (response.data.errCode === 2) {
            console.log("过期");
        }
        return response;
    },
    (error) => {
        console.log("请求出错:", error);
    }
);

/**
 * 封装get方法
 * @param url  请求url
 * @param params  请求参数
 * @returns {Promise}
 */
export function get(url, params = {}) {
    return new Promise((resolve, reject) => {
        axios.get(url, {
            params: params,
        }).then((response) => {
            resolve(response.data);
        }).catch((error) => {
            reject(error);
        });
    });
}

/**
 * 封装post请求
 * @param url
 * @param data
 * @returns {Promise}
 */

export function post(url, data) {
    return new Promise((resolve, reject) => {
        axios.post(url, data).then(
            (response) => {
                //关闭进度条
                resolve(response.data);
            }).catch((error) => {
                reject(error);
            });
    });
}

/**
 * 封装patch请求
 * @param url
 * @param data
 * @returns {Promise}
 */
export function patch(url, data = {}) {
    return new Promise((resolve, reject) => {
        axios.patch(url, data).then(
            (response) => {
                resolve(response.data);
            }).catch((error) => {
                reject(error);
            });;
    });
}

/**
 * 封装put请求
 * @param url
 * @param data
 * @returns {Promise}
 */

export function put(url, data = {}) {
    return new Promise((resolve, reject) => {
        axios.put(url, data).then(
            (response) => {
                resolve(response.data);
            }).catch((error) => {
                reject(error);
            });
    });
}

//统一接口处理,返回数据
export default function (fecth, url, param) {
    return new Promise((resolve, reject) => {
        switch (fecth) {
            case "get":
                console.log("begin a get request,and url:", url);
                get(url, param)
                    .then(function (response) {
                        resolve(response);
                    })
                    .catch(function (error) {
                        console.log("get request GET failed.", error);
                        reject(error);
                    });
                break;
            case "post":
                post(url, param)
                    .then(function (response) {
                        resolve(response);
                    })
                    .catch(function (error) {
                        console.log("get request POST failed.", error);
                        reject(error);
                    });
                break;
            default:
                break;
        }
    });
}

//失败提示(可自行配置)
function msag(err) {
    if (err && err.response) {
        switch (err.response.status) {
            case 400:
                alert(err.response.data.error.details);
                break;
            case 401:
                alert("未授权,请登录");
                break;

            case 403:
                alert("拒绝访问");
                break;

            case 404:
                alert("请求地址出错");
                break;

            case 408:
                alert("请求超时");
                break;

            case 500:
                alert("服务器内部错误");
                break;

            case 501:
                alert("服务未实现");
                break;

            case 502:
                alert("网关错误");
                break;

            case 503:
                alert("服务不可用");
                break;

            case 504:
                alert("网关超时");
                break;

            case 505:
                alert("HTTP版本不受支持");
                break;
            default:
        }
    }
}

配置api.js文件

import http from './http'

export const test = () => http("get",'接口路径')

最后在页面引入调用test即可 

八.配置webpack

在这里配置一下,打包去除console和debugger的代码

先下载需要的插件:

npm install uglifyjs-webpack-plugin --save-dev

配置config-overrides.js

const { override, fixBabelImports,addWebpackPlugin, addLessLoader, addWebpackAlias,adjustStyleLoaders } = require("customize-cra");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const  customize = require("customize-cra");
const path = require("path");


console.log(customize);
module.exports = override(
    // 针对antd 实现按需打包:根据import来打包 (使用babel-plugin-import)
    fixBabelImports("import", {
        libraryName: "antd",
        libraryDirectory: "es",
        style: true, //自动打包相关的样式 默认为 style:'css'
    }),
    // 使用less-loader对源码重的less的变量进行重新制定,设置antd自定义主题
      addLessLoader({
        lessOptions:{
            javascriptEnabled: true,
            modifyVars: { "@primary-color": "#1DA57A" },
        }
      }),
    //增加路径别名的处理
    addWebpackAlias({
        '@': path.resolve('./src')
    }),
    adjustStyleLoaders(({ use: [, , postcss] }) => {
        const postcssOptions = postcss.options;
        postcss.options = { postcssOptions };
    }),
    // 判断环境,只有在生产环境的时候才去使用这个插件
    // 如果不想这样做的话可以只修改build的命令为"build": "react-app-rewired build"
    process.env.NODE_ENV === 'production' && addWebpackPlugin(new UglifyJsPlugin({
        uglifyOptions: {
        compress: {
            drop_debugger: true,
            drop_console: true
        }
        }
    }))
);

基本配置就到这里了。

 

;