一.项目创建
打开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')
})
);
如果不是版本问题,就是要更改配置,报错如下:
主要是配置问题,少了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')
})
);
然后继续报错了:
这次是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
}
}
}))
);
基本配置就到这里了。