从0开始分享一个React项目:React-ant-admin

ops/2024/11/24 22:02:01/


项目源码:https://gitee.com/kong_yiji_and_lavmi/react-ant-admin

项目介绍网站:https://z3web.cn/doc-react-ant-admin/guide/start.html

建议学完React基本知识后,此项目巩固和了解基本知识在项目中如何使用,以及项目架构。

在此基础上,进行二次开发react-bpmn

在这里插入图片描述

React-ant-admin

1.代理转发(解决跨域)

在React项目中设置代理转发,通常用于解决开发环境中的跨域问题。以下是两种常用的设置代理转发的方法:

方法一:在package.json中配置

这是最简单的方法,但只能配置一个代理。

  1. 打开React项目的package.json文件。
  2. 在文件中找到或添加"proxy"字段,并设置为目标域名地址和端口号。例如:
{// ...其他配置"proxy": "http://localhost:5000"
}
  1. 保存package.json文件并重启React项目。

此时,当React项目中的请求无法找到对应的路由时,会自动转发到proxy字段指定的目标域名地址上。

方法二:使用http-proxy-middleware插件⭐⭐⭐

这种方法可以配置多个代理,更加灵活。

  1. 安装http-proxy-middleware插件:
npm install http-proxy-middleware --save
  1. 在React项目的src目录下创建一个名为setupProxy.js的文件。
  2. setupProxy.js文件中进行代理配置。例如:
const { createProxyMiddleware } = require('http-proxy-middleware');module.exports = function(app) {app.use(createProxyMiddleware('/api1', {target: 'http://localhost:3001', // 目标服务器地址changeOrigin: true, // 是否改变源地址pathRewrite: { '^/api1': '' }, // 去除请求前缀}));app.use(createProxyMiddleware('/api2', {target: 'http://localhost:3002', // 另一个目标服务器地址changeOrigin: true,pathRewrite: { '^/api2': '' },}));// 可以继续添加更多的代理配置
};
  1. 保存setupProxy.js文件并重启React项目。

此时,当React项目中的请求以/api1/api2为前缀时,会分别转发到http://localhost:3001http://localhost:3002上。

注意事项

  • 在使用http-proxy-middleware插件时,确保setupProxy.js文件位于src目录下,并且文件名不能更改。
  • 在配置代理时,target字段指定的是目标服务器的地址,changeOrigin字段通常设置为true以改变源地址,pathRewrite字段用于去除请求前缀。
  • 代理配置完成后,需要重启React项目才能使配置生效。

通过以上两种方法,您可以在React项目中设置代理转发,从而解决开发环境中的跨域问题。

项目环境变量管理

env-cmd 详解

一、定义与功能

env-cmd 是一个简洁的 Node.js 程序,它允许你在执行命令时加载指定的环境文件,从而轻松管理环境变量。这个工具特别适用于开发过程中需要处理不同环境下的配置变量的场景。

二、主要特性

  1. 支持多种环境文件格式:env-cmd 支持 .env(key=value 格式)、.env.json.env.js(JavaScript 对象或 Promise)等多种环境文件格式。
  2. 灵活的环境配置:通过 .env-cmdrc.env-cmdrc.js 文件,你可以定义多个环境配置,并在运行时通过命令行参数指定要使用的环境。
  3. 与 npm 脚本集成:env-cmd 可以直接与 npm 脚本集成,只需在 package.jsonscripts 中调用即可
  4. 安全性:虽然不建议将敏感数据存储在公共仓库中,但 env-cmd 提供了方便的方式来管理和保护这些信息(例如,通过环境变量文件而非硬编码在代码中)。
  5. 扩展性:通过 --expand-envs 选项,可以将命令行参数中的环境变量进行展开,提高可编程性。
  6. 调试友好--verbose 选项可用于输出调试信息,帮助排查问题

三、使用方法

  1. 安装:通过 npm 或 yarn 安装 env-cmd。

    npm install env-cmd --save-dev
    # 或者
    yarn add env-cmd --dev
    
  2. 创建环境变量文件:在项目根目录下创建 .env 文件(或其他支持的文件格式),并在其中定义环境变量。

  3. 配置 npm 脚本:在 package.jsonscripts 部分添加使用 env-cmd 的脚本命令。

    {"scripts": {"start": "env-cmd -f .env.development node index.js","build": "env-cmd -f .env.production webpack --config webpack.config.js"}
    }
    
  4. 运行命令:通过 npm 脚本或直接运行 env-cmd 命令来加载环境变量并执行相应的操作。

四、高级用法

  1. 指定环境配置:使用 -e--env 选项指定要加载的环境配置名称(如果使用了 .env-cmdrc.env-cmdrc.js 文件)。

    env-cmd -e production node index.js
    
  2. 环境变量插值:在 .env 文件中,你可以引用其他环境变量来实现环境变量插值。

    API_URL=http://${API_HOST}:${API_PORT}
    API_HOST=localhost
    API_PORT=3000
    

.env-cmdrc.js 详解

一、定义与用途

.env-cmdrc.js 是 env-cmd 的一个配置文件,用于定义和共享多个环境配置。通过这个文件,你可以更灵活地管理和切换不同的环境变量。

/*** env-cmd  文档地址 https://github.com/toddbluhm/env-cmd#-help* 命令行使用: env-cmd --verbose -e mode_name node file.js  * mode_name: 对应 mode 里面的 属性(key) 例如 development development_color* 运行结果:* 取出 对应 mode_name 的 值(value) Object.keys方法 把 key-value 绑定到 process.env 上* 如 : development(mode_name): { test : "123" }  => process.env.test = "123"* 最终能够在整个项目中 使用 process.env.test*/

二、文件结构

.env-cmdrc.js 文件应该导出一个包含多个环境配置的对象。每个环境配置都是一个键值对对象,其中键是环境变量的名称,值是环境变量的值。

module.exports = {development: {REACT_APP_API_URL: 'http://localhost:3000/api',// 其他开发环境变量...},production: {REACT_APP_API_URL: 'https://api.example.com/api',// 其他生产环境变量...},// 可以定义更多环境配置...
};

三、使用方法

  1. 创建 .env-cmdrc.js 文件:在项目根目录下创建 .env-cmdrc.js 文件,并按照上述结构定义环境配置。

  2. 运行命令:在命令行中使用 -e--env 选项指定要加载的环境配置名称。

    env-cmd -e development node index.js
    
  3. 与 npm 脚本集成:你也可以在 package.jsonscripts 部分中集成 .env-cmdrc.js 文件的使用。

    {"scripts": {"start:dev": "env-cmd -e development node index.js","start:prod": "env-cmd -e production node index.js"}
    }
    

综上所述,env-cmd 和 .env-cmdrc.js 提供了强大的环境变量管理能力,帮助开发者在各种场景下轻松应对环境变量的管理问题。无论是个人开发者还是团队成员,都能从这些工具中受益。

此项目解读

.env-cmdrc.js:配置多种环境(开发与生产

**config**
const devConfig = {PORT: 3000, // 启动端口HOST: "0.0.0.0", // 监听地址REACT_APP_ROUTERBASE: "/react-ant-admin", // react路由基础路径REACT_APP_API_BASEURL: "http://127.0.0.1:8081/api/react-ant-admin", //请求地址PUBLIC_URL: "/react-ant-admin",// 静态文件路径
}
const proConfig = {REACT_APP_ROUTERBASE: "/react-ant-admin", // react路由基础路径REACT_APP_API_BASEURL: "/api/react-ant-admin", //请求地址PUBLIC_URL: "/react-ant-admin",// 静态文件路径BUILD_PATH: "react-ant-admin", // 打包 文件夹名称
}**mode**
// 本地mock  运行
development_mock: {...devConfig,REACT_APP_MOCK: "1", // 1 为开启mock
},// 主题色 和 本地mock  运行
development_color_mock: {...devConfig,COLOR: "true",REACT_APP_MOCK: "1",
},// 打包 :无主题 无mock
production: proConfig,

package.json中以不同形式启动项目

"scripts": {"start:mock": "node color && env-cmd --verbose -e development_mock node scripts/start.js","start:mock_color": "env-cmd --verbose -e development_color_mock node color && env-cmd --verbose -e development_color_mock node scripts/start.js","build": "node color && env-cmd --verbose -e production node scripts/build.js",
},

详细解释一下此段脚本

 "start:mock": "node color && env-cmd --verbose -e development_mock node scripts/start.js",

–verbose:选项可用于输出调试信息,帮助排查问题。

development_mock.env-cmdrc.js中配置的模式。

按需加载

在React中,loadable 是一个用于代码拆分(Code Splitting)的库,可以帮助你按需加载组件,从而提高应用的性能。代码拆分允许你将应用的代码分成小块,这样用户只有在需要的时候才会下载相应的代码,从而减少了初始加载时间。

尽管 loadable 库本身已经有一段时间没有更新,React 社区现在更推荐使用内置的 React.lazySuspense 来实现类似的功能。以下是如何使用这两种方式来实现代码拆分的示例:

使用 React.lazy 和 Suspense

  1. 安装 React 和 React-DOM(如果你还没有安装的话):

    bash复制代码npm install react react-dom
    
  2. 创建一个需要按需加载的组件(例如 OtherComponent.js):

    // OtherComponent.js
    import React from 'react';const OtherComponent = () => {return <div>This is the Other Component!</div>;
    };export default OtherComponent;
    
  3. 在你的主应用中使用 React.lazySuspense

    // App.js
    import React, { Suspense, lazy } from 'react';const OtherComponent = lazy(() => import('./OtherComponent'));const App = () => {return (<div><h1>Hello, World!</h1><Suspense fallback={<div>Loading...</div>}><OtherComponent /></Suspense></div>);
    };export default App;
    
    • lazy 函数允许你定义一个动态导入的组件。
    • Suspense 组件包裹动态加载的组件,并显示一个 fallback UI(例如一个加载指示器),直到动态加载的组件完成加载。

使用 Loadable Components 库(已过时,但了解原理)

虽然 loadable 库现在不太推荐使用,但了解它的原理仍然是有价值的。以下是如何使用 loadable-components 的示例(注意:你可能需要先安装这个库):

  1. 安装 loadable-components

    bash复制代码npm install @loadable/component
    
  2. 创建一个需要按需加载的组件(例如 OtherComponent.js,与上面的相同)。

  3. 在你的主应用中使用 Loadable

    // App.js
    import React from 'react';
    import loadable from '@loadable/component';const OtherComponent = loadable(() => import('./OtherComponent'), {fallback: <div>Loading...</div>,
    });const App = () => {return (<div><h1>Hello, World!</h1><OtherComponent /></div>);
    };export default App;
    
    • loadable 函数接受一个加载组件的函数和一个配置对象,配置对象中可以指定一个 fallback UI。

总结

虽然 loadable-components 库提供了一种实现代码拆分的方法,但 React 内置的 React.lazySuspense 提供了更简单且更直接的方式来处理动态导入和加载状态。因此,如果你正在开发一个新的React应用,建议使用 React.lazySuspense

Redux全局状态管理

https://blog.csdn.net/m0_55049655/article/details/142662383

https://blog.csdn.net/m0_55049655/article/details/143029565

index.js```jsx
import { createStore, combineReducers } from “redux”;
import MenuReducer from “./menu/reducer”;
import UserReducer from “./user/reducer”;
import LayoutReducer from “./layout/reducer”;
import VisibelReducer from “./visibel/reducer”;
const reducer = combineReducers({
menu: MenuReducer,
user: UserReducer,
layout: LayoutReducer,
componentsVisible: VisibelReducer,
});

const store = createStore(
reducer,
process.env.NODE_ENV === “development” &&
window.REDUX_DEVTOOLS_EXTENSION &&
window.REDUX_DEVTOOLS_EXTENSION()
);

export default store;


**App.js中全局状态使用**

import { Provider } from “react-redux”;
import store from “./store”;

function App() {
return (

<Suspense fallback={

Loading
}>

{process.env.showColorSet&&}



);
}

在这里插入图片描述

下图中dispatch(hooks内的js)对应于上图的action,reducer对应reducer,action.js封装内容是ruducer函数第一个参数,主要是actionType(如:加或减),所有又封装了actionTypes.js。

layout.js

import { useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { changeLayoutMode } from "../action";
import { getLayoutMode } from "../getters";export const useStateLayout = () => useSelector(getLayoutMode)export function useDispatchLayout() {const dispatch = useDispatch()const stateChangeLayout = useCallback((type, mode) => dispatch(changeLayoutMode(type, mode)), [dispatch])return {stateChangeLayout}
}

reducer(layout/reducer.js)

import * as actionTypes from "./actionTypes";
import { getLayoutMode } from "@/utils";
const localLayout = getLayoutMode()
const layout = (Array.isArray(localLayout) && localLayout) || [actionTypes.TWO_COLUMN];export default function reducer(state = layout, action) {const { type, mode } = action;switch (type) {case "push": {if (!mode) {return state}let lastMode = state[state.length - 1]console.log(mode, lastMode);if (lastMode === mode) {return state}const sliceNum = state.length > 1 ? 1 : 0return state.slice(sliceNum).concat(mode)}case "pop": {if (state.length > 1) {state = state.slice(0, 1)} else {state = layout}return state}default: {return state}}
}

action(layout/action.js)

export const changeLayoutMode = (type, mode) => ({type,mode,
});

action(layout/actionTypes.js)

const SINGLE_COLUMN = "SINGLECOLUMN";
const TWO_COLUMN = "TWO_COLUMN";
const TWO_FLANKS = "TWO_FLANKS";
const FULL_SCREEN = "FULLSCREEN"
export { SINGLE_COLUMN, TWO_COLUMN, TWO_FLANKS, FULL_SCREEN };


http://www.ppmy.cn/ops/136412.html

相关文章

在win10环境部署opengauss数据库(包含各种可能遇到的问题解决)

适用于windows环境下通过docker desktop实现opengauss部署&#xff0c;请审题。 文章目录 前言一、部署适合deskdocker的环境二、安装opengauss数据库1.配置docker镜像源2.拉取镜像源 总结 前言 注意事项&#xff1a;后面docker拉取镜像源最好电脑有科学上网工具如果没有科学上…

OAI-5G开源通信平台实践(三)

端到端验证相关问题及分析解决 PlmnTACSlice配置UE imsi配置opc/key配置问题5GC侧配置如下:错误现象解决PlmnTACSlice配置 #1. UERANSIM接5GS##AMF报错 02/21 18:05:18.949: [amf] INFO: gNB-N2 accepted[127.0.0.1] in master_sm module (../src/amf/amf-sm.c:741) 02/21 18…

2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析

一、单选题 1、下面代码运行后出现的图像是&#xff1f;&#xff08; &#xff09; import matplotlib.pyplot as plt import numpy as np x np.array([A, B, C, D]) y np.array([30, 25, 15, 35]) plt.bar(x, y) plt.show() A. B. C. D. 正确答案&#xff1a;A 答案…

Java 创建不可变集合

Java中为了安全起见&#xff0c;有时候不想让别人改集合中的数据&#xff0c;那么就可以使用不可变集合。 package listExercise;import java.util.HashMap; import java.util.Map; import java.util.Set;/*** 不可变集合* 长度不变&#xff0c;内容无法修改的集合* 当集合中的…

QSqlTableModel setModel 和 独立设置信号槽冲突

经测试&#xff0c;QSqlTableModel如果预先设置了和 sqlmodel->setTable(tableName); sqlmodel->select(); tableView->setModel(&sqlmodel);再对QSqlTableModel使用信号槽链接&#xff0c;会导致submitAll()提交成功但是数据库实际上没更新的情况。 connect(te…

vue3(十八)-基础入门之vue-nuxt自定义视图及页面组件的特殊配置

一、自定义视图 在没有指定视图的情况下&#xff0c;nuxt 使用的是默认视图 layouts/default.vue <template><nuxt /> </template>1、创建一个视图并将其保存到 layouts/blog.vue 别忘了在布局文件中添加 < nuxt /> 组件用于显示页面的主体内容。 …

输入/输出管理 III(磁盘和固态硬盘)

一、磁盘 【总结】&#xff1a; 磁盘&#xff08;Disk&#xff09;是由表面涂有磁性物质的物理盘片&#xff0c;通过一个称为磁头的导体线圈从磁盘存取数据。在读&#xff0f;写操作期间&#xff0c;磁头固定&#xff0c;磁盘在下面高速旋转。如下图所示&#xff1a; 磁盘盘面…

重生之我在学环境变量

环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#xff0c;但 是照样可以链接成功&#…