antd pro request(Module not found: Error: Can’t resolve ’react’ in)

本文目录
- Module not found: Error: Can’t resolve ’react’ in
- 移除antd pro中的 路由的国际化
- 使用 MockJs — 实现真正的前后端分离
- 关闭 Umi UI
- antd pro 动态菜单与动态路由
- antd pro 实现文件下载
- CKEditor5的入门使用(react)
Module not found: Error: Can’t resolve ’react’ in
使用 react + webpack 启动一个简单的 react 例子时, 报错 :
一. 项目结构:
二. 一些文件内容:
app.jsx:
package.json:
webpack.config.js:
出现错误的原因: resolve.modules 这个方法使用错了, resolve.modules 告诉 webpack 寻找模块时应该从哪些路径查找, resolve.modules 的默认值就是 就不去 "node_modules" 查找了.
resolve.modules 里的路径可以是相对路径, 也可以是绝对路径. 如果是相对路径, 查找模块时会像 node 查找模块一样, 先从离的最近的 node_modules 目录里查找, 如果没找到, 层层向上继续找, 直到到最外层的根目录的 node_modules. 如果是绝对路径, 就简单多了, 只在指定的路径里查找.
移除antd pro中的 路由的国际化
对于大部分不需要国际化的ant pro来说。
移除locale会减轻很多开发工作。
import { formatMessage } from ’umi/locale’;
替换
为
const pageName = currRouterData.cnname;
import { formatMessage } from ’umi/locale’;
替换formatter
为
使用 MockJs — 实现真正的前后端分离
前言: 刚刚看了下的后台,发现我技术文章中,阅读留言最多的是关于移动端的文章,甚至还有人付费赞赏或咨询。关于 PC 端的技术文章就显得比较冷清了,唉,废了好大劲写的,没人看。 和我想的一样,移动端才是王道,下次找工作我也搞移动端 。
背景: 去年我写了一篇 学习使用 json-server 和 mockjs 的文章,当时没有仔细研究,文章只提到了 MockJs 其中一个 Random 的用法,关于 MockJs 拦截器和另一个很常用的 Mock.mock 函数都没有提及。这次来搞一下。
唉!以前我也是经常会听到 前后端分离 这个名词,只模糊的知道它最重要的一个作用就是,大大的提升了 前端的地位。 但是平时在开发的时候,我也会想奶奶的,没有接口这前端不就写了一个破页面,后期还的和后端对接口,对接口的时候花费的时间,肯定是不比前端开发的时候短,工期上最起码一半一半吧, 这也就前后端分离 ,我这个小脑袋就不是太明白了。
不过我现在是终于搞明白这个问题了, 对于前端来讲,真正的前后端分离,标志是不依赖后端的前端工作开发完成,项目基本宣告结束。 后端开发完接口,只需要提换一个 URL 就行了,这也意味着前端需要去写一些接口。
除了带来开发任务稍微重点外,我至少看到了两个最大的优点:
我体会最深就是这两点。
插曲 :对了,今天中午我捡到一个手机,我必须要用一张动图来描述下:
这个经典的 GIF ,来自郑伊健的恐怖电影「第一诫」,清凉一冬,绝对值得一看,虽然剧情有很大的 bug ,但是港片就这点好,它有很抓人的地方,让你觉得特别好看。
正文由此开始:
待续~~~
上面三种方案都可以,但你要知道接口很多,需要支持批量引入,所以 使用 Axios 响应拦截器 就不太可取,只能在这简单的造些假数据。
著名开源项目 vue-element-admin 开发环境下模拟假接口使用的是 在 webpack-dev-server 的 before 处拦截。生产环境下是在项目入口文件( index,js )使用 Mock.mock 模拟的。
拦截请求的步骤如下,根据 devserverbefore 配置的栗子:
可知道 before 接收一个函数,函数的第一个参数一般叫 app ,因为它的作用和 express 的 app 是等效的。也就是说这个 app 自带路由, 正好解决接口批量引入的问题。
在项目中,一般都是这么写,把逻辑提出去:
./mock/mock-server.js 文件的内容为:
./mock/index.js 文件的内容为:
mockXHR 不用看,因为这是给线上环境用的,所以可以简单的改写为:
随便找一个,例如 user 看下接口怎么写的:
完美,到此结束。
我想你一定对更改文件的时候,为什么要 清路由和清缓存感兴趣。
如果熟悉 express 框架,看到 app._router.stack 你就知道了。不知道也没关,我演示给你看,新建一个JS 文件,文件内容为:
执行结束,看在 test.js 文件的内容:
发现没,重复被添加的路由,不是覆盖而是扩展。
这个涉及到 CJS 模块的运行机制, 记住 require 的文件会被加到 require.cache 里面,当文件改变读的是缓存,而不是最新更改的文件。
项目结构过大,如果只在 mock 文件夹里面管理有点麻烦,我就想在页面所在目录直接写接口,怎么办?没错使用 require.context 来批量引入。但是 NodeJs 是没有批量引入的 API 的。找遍了 npm 也没发现一个 package 和 require.context 长得像的。
难道没办法了吗?当然不是,自己动手丰衣足食。 依照 vue-cli 插件的命名规范,我给写的 package 取名 node-plugin-require-context ,简单讲下实现原理:
其实还有一个缺点,如果你看过 Antd-Pro 项目,你就会发现它模拟数据,模块化采用的是 ESModule ,而不是 CJS。保持编码模块化风格一致确实也是需要优化的一个地方,不管了,反正我不干。
官网本来就是中文的,我在使用中发现写的贼好,我就不用画蛇添足了。建议每次使用前:
关闭 Umi UI
antd pro 项目 默认启动umi ui ,会出现一个mini图标气泡浮在右下角,
关闭有两种方式,一种是直接用样式 display none
另一种通过配置环境变量
package.json 中的start 命令,本来是 "start": "umi dev",现在变成 "start": "UMI_UI=none umi dev",
或者是 "cross-env UMI_UI=none umi dev"
通过加上UMI_UI=none 来关闭 umi ui
更新一波
pro的最新版也有了
antd pro 动态菜单与动态路由
项目中使用了动态菜单,其中含有固定和非固定的菜单,但是我们的后端同事只在登陆时返回含有动态菜单 name 的数组。
阅读源码我们可以发现,在 layouts/BasicLayout 中可以看到 menuData 是从 menu.js 中获取的
routes 就是运行生成的 .umi/router.js 的内容,将其输出我们可以直观的看见它的具体结构
在 router.config.js 中使用 dynamic 去标志该目录(路由)是动态的
大体思路就是对 routes 进行数据处理,将登录获取到的特定路由(这里用 name 属性标识)在 routes 中过滤出来
此时的 menuData 就是我们想要的实际菜单了
旧版本(2.x)回到 layouts/BasicLayout 中,从props中取出 routerMap
权限组件 Authorized ,使用这个组件就能实现不跳转的 404、403页面了
但是3.x的写法会导致出现404或者403时会全屏,所以如果是局部应用的话,可以将登录校验、404/403校验分离,将 Routes 分别挂在对应的路由层级上
antd pro 实现文件下载
这是POST 请求的:
export async function downloadDiagnosticLog(params) {
return request(`/api/v1/diagnosisLogController/download?${stringify(params, { arrayFormat: ’repeat’ })}`);
}
* sendDownloadDiagnosticLog({ payload }, { call, put }) {
console.log(’payload: ’, payload);
const response= yield call(downloadDiagnosticLog, payload);
console.log(’payload: ’, response);
yield put({
type: ’respDownloadDiagnosticLog’,
payload: response,
});
},
respDownloadDiagnosticLog(state, { payload }) {
return {
...state,
downloadDiagnosticLogState: payload,
};
},
async sendDownloadDiagnosticLog(id) {
const fileName= ’rowData.activeDepotName’;//说白了就是给文件个名字
console.log(this);
await this.props.dispatch({//发送请求
type: ’DiagnosticLog/sendDownloadDiagnosticLog’,
payload: { id: id ? : this.state.selectedRowKeys},//参数
});
const { DiagnosticLog: { downloadDiagnosticLogState} } = this.props;
console.log(downloadDiagnosticLogState);
let response= downloadDiagnosticLogState;
const blob= new Blob();//创建blob对象
const aLink= document.createElement(’a’);//创建a链接
aLink.style.display= ’none’;
aLink.href= blob;
aLink.download= fileName;
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
};
《a href={`/api/v1/diagnosisLogController/download?id=${record.id}`}
CKEditor5的入门使用(react)
没有前言,开始讲解。
使用环境: 基于react的antd-pro框架,这部分受antd的影响较小(仅部分表标签)。 CKEditor5 的document 12.1.0版本.
cnpm install @ckeditor/ckeditor5-build-decoupled-document
可根据需求安装对应的主题插件:
index.js
以上按照官方文档也能写个差不多,主要是图片上传部分
uploadType.js
uploadType写完之后,按照"初始化"部分引入即可。

更多文章:
js代码炫酷特效模板(鼠标悬停特效代码怎么写,鼠标放在小图片上旁边显示一张大图片)
2026年5月14日 04:00
strutsprepareandexecutefilter(struts2原理)
2026年4月13日 00:30
物流管理系统数据库设计文档(求基于C#的库存管理系统的设计与实现毕业设计论文)
2025年12月2日 13:30
executed alternatively(各位帅哥 靓妹 英文好的 江湖救急了 谢谢!!)
2026年4月4日 05:15
arraylist和array区别(ArraryList,Array string[]的差别是什么)
2026年1月4日 01:00
reset sw不分方向(微星H55M-P32主板开启,重启,指示灯接口,应该如何插)
2026年1月27日 04:45
黑莓开发者模式(黑莓KEY2 Lite 开发者选项怎么打开)
2025年6月23日 08:15
in length的用法(新概念英语第2册Lesson90~92重点句型及语法)
2026年4月9日 10:45
webpack缺点(如何理解webpack文档中对AMD缺点的描述)
2026年9月10日 12:30
corresponding author和第一作者(corresponding author必须是第一作者吗)
2026年5月12日 05:30













