Repository navigation
feat: 2026-09 全面治理与审查修复 - #9
Merged
Merged
Conversation
- LICENSE 版权行填写(2024-present Li Shuai (Jerry)),package.json 补 license/repository/bugs/homepage/keywords - README clone 地址修正为 Jerry-CodeHub(原指向过时账号),贡献者链接修复双 org 重复导致的 404 - .all-contributorsrc 项目指向统一为 Jerry-CodeHub - 工具链统一:packageManager pnpm@10.33.0、engines node>=20、.nvmrc 22.19.0,CI 同步 node22/pnpm10(消除与本地 node18/pnpm9 的漂移) - 锁文件纪律:移除 .npmrc 的 frozen-lockfile=false,CI 显式 --frozen-lockfile,Vercel installCommand 锁定 - .prettierignore 补 pnpm-lock.yaml/dist/.claude,防止 format 钩子重写锁文件
tinymce 8.5.0 存在 3 条已披露的 high 级 XSS(8.5.1 修复),升级到当前 8.x 最新。 @tinymce/tinymce-react@6 官方支持 tinymce ^8,无需配套变更。 锁文件随 pnpm 10.33.0 重新序列化(工具链统一的副产物,依赖内容无变化)。 typecheck/lint/test 全绿。
请求层(修复审计 extra-1-1 等五条同源发现): - requestConfig 按 axios 语义重写:原 errorHandler 的 instanceof Response 守卫在 @umijs/max 4.6.53 的 axios 运行时下恒为 false,400/401/403/404/500 全部分支 不可达(dec3a96 引入的回归),任何 HTTP 错误静默失败 - 状态码分流修正:400 仅提示不跳页;401 清 token 跳登录;403 提示跳 /403; 404 仅提示;网络层区分超时/断网 - 新增 BizError 业务错误类型(success:false 经 errorThrower 转型,双线分流) - 新增 antdMessage 桥:message 实例经 App 上下文注入,受 appConfig.maxCount 约束 鉴权闭环(修复 feature-1/chain-1/security-4/extra-1-5/chain-6): - mock 新增 login/logout/currentUser 三接口,token 真实参与鉴权 - initialState 真实化:token 换用户,登录名进入全局状态(顺带修正文件名拼写 initalState→initialState) - 路由守卫:layout childrenRender 内 AuthGuard(未登录重定向 /login) 注意:不用 config routes 的 wrappers 属性——实测该属性在 max 4.6.53 + layout 插件下导致生产构建整站静默白屏 - Login 增加密码字段与框架层双语文案;/login 加 layout:false 独立全屏(feature-17) - RightContent 登出走接口并重置 initialState,顶栏昵称消费真实数据(feature-6 部分) - en-US 修复 HaiAirPosture 菜单键错挂与拼写(feature-16) 依赖:axios override 0.31.1→1.20.0(消解其 5 条 high 公告,errorHandler 为 版本无关的对象形状判断) 验收:typecheck/lint/test/build 全绿;生产构建浏览器实测:守卫重定向、登录、 昵称、菜单权限收敛(dontHaveAccess)、403 拦截、登出、登出后再拦截全部通过
大删除窗口(审计 code-3/feature-2/chain-5/feature-11/feature-14/chain-12/feature-10/deps-3/4/5/7/8/11 等): 删除死代码(162 文件 / -167,846 行,src 活代码 18k→9.7k 行): - Formily/Designable 低代码设计器(零路由零引用,依赖锁死 3.5 年未发版的 beta fork;README 首位卖点同步移除,恢复路由的替代方案见 remediation plan D1) - D3 半成品:DataDemo(Frequency 的陈旧整份拷贝)、BarChartRace、components/data.json - MapCompute 死数据:thermalData.json(9.8MB,运行时实际走 public/data)、 result.json、ngeohash(538 行,仅注释引用) - 占位页/死文件:Feature/Map/Cesium/AudioFeature 的 index.tsx、Cesium.ts、 Footer、Guide、format.ts;_defaultProps 只保留在用的 appList - ArtPlayer 演示页与路由(视频统一 xgplayer,决策 D5) 删除死依赖(16 项,lockfile 686KB→608KB): - 设计器栈 ×8:@formily/antd-v5/core/react、@designable/formily-antd、 @pind/designable-* ×4(幽灵依赖 transformer 随目录消失) - 零引用 ×8:@ant-design/charts(保留在用的 plots)、artplayer、ahooks(连带 消除 js-cookie high 公告)、rbush、@types/rbush、cesium-heatmap/cesiumjs-heat/ heatmap.js/simpleheat(热力图页实为 Cesium 原生实现) - @types/d3 移入 devDependencies;splitChunks 移除 designable 死分组并清理 media/turf 分组正则 清理:GeoHash/Trajectory 死注释、locales 注释键与 ArtPlayer 键、 CLAUDE.md 技术栈与项目概述同步 验收:typecheck/lint/test/build 全绿;浏览器实测 home/D3/Cesium/xgplayer 页面正常渲染,Formily 与 ArtPlayer 菜单消失
…verhaul 首屏体积治理(审计 perf-1/4/11,验收目标 191→≤25 脚本 / gzip ≤1MB): - splitChunks 重构:vendors 兜底组限定 chunks:'initial'(根因修复:原配置 继承 chunks:'all' + maxSize 碎片化,把 Cesium/turf 异步引擎卷入首屏同步加载); 全部 maxSize 碎片化移除(55KB 级碎片破坏缓存);d3 独立分组与图表库解包 - 实测:同步脚本 192→4(umi/framework/vendors/vendor-antd), 首屏 gzip 2.40MB→728KB(-70%) - Frequency.tsx 移除零使用的 d3 命名空间导入(barrel 整包引入) 样式基础层(审计 extra-3-1/2/3/5、ui-12,级联基线): - 移除 tailwind important:true(全部 utilities 带 !important 与 AntD5 token 确定性冲突面),按需覆盖改用组件 props(Avatar size、Button 原生 padding) - 关闭 preflight,基础 reset 交还 antd reset 独占;裸 border 分隔线 替换为 AntD Divider - content globs 放宽到全部 src 并负向排除 .umi 生成物,消除静默 purge 盲区 体积度量门禁(审计 perf-11): - 新增 scripts/check-bundle-size.mjs + size-budget.json:同步脚本数/首屏 gzip/dist/public 四项预算,超限 exit 1,可直接接入 CI;基线数据留档 - 新增 pnpm analyze / pnpm size 脚本 验收:typecheck/lint/test/build 全绿;体积预算 4 项中 2 项达标、dist/public 待演示数据瘦身收紧(预算暂设现实值并注明);浏览器冒烟 login/home(图表)/ table/Cesium 热力图全通过
…ragma 依赖批量升级(审计 deps-6/deps-12,官方源 audit 实测 130 条→32 条,high 49→5): - @umijs/max ^4.6.53→^4.7.19:从上游消解 vite 4.5.2(14 条,含 launch-editor 命令注入 high)与 hono 4.12.18(19 条)整条构建链公告 - overrides 补齐 22 条同 major 无损 pin(react-router 6.30.4、@remix-run/router 1.23.3、brace-expansion、js-yaml、postcss、ws、dompurify(消 @cesium/engine 10 条)、qs、protobufjs 等) - @types/react 18.3.31 / @types/react-dom 18.3(与运行时 react 18.3.1 对齐)、 TypeScript ^5.9.3、@ant-design/icons ^5.6.1(修复 icons 类型与 @types/react 18.3 的 Pick 冲突) - Frequency.tsx 恢复 d3 命名空间导入(TS5.9 暴露的跨行成员链使用,行式 grep 误判为死代码;d3 已独立分包不进首屏) Cesium strip-pragma 两条产线统一(审计 perf-8): - 提取 config/chainWebpack.ts 供 config.ts 与 config.github.ts 共用, 均以 NODE_ENV=production 门控,消除 Docker/Vercel 与 GitHub Pages 产物不一致 验收:typecheck/lint/test/build 全绿;体积预算 4/4 达标(首屏 gzip 721KB); 浏览器冒烟 home(图表)/table/Cesium 热力图全通过;axios 1.20.0 override 复核仍生效
…rectness - mergePolygons 此前误用 turf.combine(仅几何打包不合并),多边形合并功能实际 未生效(审计 code-1);改用 turf.union(featureCollection) 真求并集: 相交多边形合并为单环,不相交返回 MultiPolygon 多环,返回类型改为外环数组 Point[][],调用方 Trajectory.tsx 按环逐个渲染,不相交并集如实呈现 - handlerComputePoint(审计 code-8):起点先入列;每段终点无条件入列 (原实现短线段终点丢失,补点结果与用户绘制轨迹不一致) 验证:turf.union 语义断言(相交→Polygon 9 顶点 / 相离→MultiPolygon 2 环)、 typecheck/lint/test/build 全绿
Table 专项(审计 extra-1-2/chain-3/chain-10/chain-11/feature-7/8/9/13/code-4/17): - 新增 userService 三层数据适配:dev 走 mock / 配 UMI_APP_API_BASE 走真实后端 / 其余静态托管拉取 public/data/users.json + localStorage 持久化——演示站 /table 生产环境 CRUD 真实可用(审计 P0-4 闭环,生产构建实测:编辑→持久化→刷新存活) - UpdateForm 从模板遗留三步「规则配置」收敛为单步「编辑用户」表单 - handleUpdate 去掉 || '' 兜底(表单外字段不再被空串清空),mock PUT 过滤 undefined 双保险 - valueEnum 数字键改 MALE/FEMALE 与数据/类型对齐;名称列接通详情抽屉(getUserDetail 成对生效,404 回落行数据);移除「订阅警报」「批量审批」无行为按钮 - ProTable request 包 try/catch 消除 unhandled rejection;mock 全部 handler 去 any (@types/express)并补 gender 过滤与 GET /api/v1/user/:userId PDF 专项(审计 code-2/chain-2/feature-4): - 默认文档 URL 与 cmaps/standard_fonts 改经 PUBLIC_PATH 拼接(config define 注入, 主产线 '/' / gh-pages '/umi-react-admin/' 三环境统一);copy 补 pdfjs 静态资源 - 加载失败由静默改为 Alert 可见提示(含原因);修复 onError→onLoadError 属性误用 - 已知项:pdfjs worker 握手(onPull undefined)导致文档不渲染——该页此前从未 可用过(旧 URL 直接 404),真实 Chrome 复核与处置留阶段 5 验收 TinyMCE 注入链(审计 feature-5):TINYMCE_API_KEY 经 define 注入(umi 仅自动 注入 UMI_APP_* 前缀),页面改用全局常量,.env.example 补占位 Clarity 默认移除(审计 opensource-4/ops-6):删除硬编码作者私有项目 ID 的 public/js/clarity.js,headScripts 改 CLARITY_ID 环境变量条件注入,CI secret 可选 其他:strip-pragma 死规则回滚(核实 loader 从未安装,审计 ops-8 判断正确); requestConfig 接 UMI_APP_API_BASE;空目录 services/api 清理;.env.example 补全 验收:typecheck/lint/test/build/体积预算全绿;浏览器实测 Table 静态层 CRUD 全链路、详情抽屉、Excel 页、PDF 失败提示全部通过
…hygiene 暗色模式真实现(审计 ui-2/feature-6,浏览器实测): - antd 运行时启用 cssVar(--ant-* 变量以 .css-var-rN 作用域注入)+ 启动算法读 localStorage 与 layout navTheme 同源,无首帧闪烁 - config.ts 启用 antd.configProvider——useAntdConfigSetter 热切换的前提 (此前为 console.error 空操作);RightContent 主题 Popover 从假按钮变为 真切换:算法热切换 + initialState 同步 + localStorage 持久化 - tailwind 颜色 token 桥接(var(--ant-color-*)),布局层 hover:bg-zinc-200 等硬编码色板换 token 类,暗色下自动跟随 - 实测:点击深色后按钮容器 rgb(20,20,20)(antd 暗色精确值)、刷新保持、切回正常 框架层 i18n(审计 ui-4,方案 B:框架层双语 + 演示页中文声明): - 403/404 页接入 useIntl(中英键配齐),Pdf 页示例标题/加载文件标签双语 - requestConfig 九处提示文案经 getIntl 接入(非组件环境,键缺失回退中文) a11y 最小集(审计 ui-9): - 顶栏三个图标按钮补 Tooltip + aria-label(中英);eslint 接入 jsx-a11y 最小规则(alt-text/aria-props/role-supports-aria-props error、anchor-is-valid warn) 管线卫生与交互修复(审计 ui-5/10/17、extra-3-4 等): - AudioPlayer 歌词外移 lyrics.json(根除 dist 垃圾 CSS 规则源)+ 画布改容器宽 自适应 + resize 监听清理(审计竞态项) - xgplayer width 100vh→100%;InfoMap 高度 calc(100vh-220px) 消双滚动、按钮中文化 - GeoHash 三处 text-success 死类删除;config.ts 删 antd4 时代的 lessLoader 死配置 - tailwind blocklist 拦截 D3 字符串字面量误产出的死类 - Table/AutonaviMap 静态 message 统一经 antdMessage 桥(受 App 上下文约束) 验收:typecheck/lint/test/build/体积预算全绿;暗色切换/持久化/切回实测通过; Table/Excel/PDF 回归无损
测试体系落地(审计 test-1/7/8、feature-18,从零到 34 例): - vitest + @vitest/coverage-v8 + jsdom;起步集覆盖率 95.9% 语句 / 86.8% 分支 - requestConfig 行为契约测试 11 例:拦截器 token 注入、400/401/403/404/500 全分支、BizError 分流、超时/网络——dec3a96 式守卫回归从此有测试网 - geoHash 性质测试:编码可逆边界包含、精度单调收缩、实测已知值固化 (wx4g0bm6,与 JSDoc 示例不符——实测为准) - UserInfo 默认值;mock 抽取 filterAndPaginate 纯函数并测试;仓库卫生测试 迁移 vitest(node --test 退役) 质量门禁严格化(审计 convention-2/3、test-3/4/5): - lint 拆分:eslint . --max-warnings=0(零警告通过)+ stylelint;check 获得严格 lint - lint-staged 单一配置(.lintstagedrc,package.json 字段删除) - 各 ignore 补 coverage/dist 等生成物;pre-commit 增加 typecheck - Table 三处 anchor a11y 修复清零 jsx-a11y 警告 CI 改版(审计 test-2、ops-3/11、security-3/6、deps-6): - 新增 ci.yml:PR 触发 pnpm check + 构建冒烟 + 产物 JWT 泄露扫描(补 security-6 盲区)+ 非阻断 audit 观察期(官方源,两段式) - deploy.yml:并发去重、actions 升至现行版本、actions-gh-pages v3→v4(弃用运行时) - 样式文件命名统一 Xxx.style.ts;CLAUDE.md 补命令与命名说明
…ance 开源合规(审计 opensource-2/3/7/8、docs 全组): - turf 整包改按需子包(@turf/union + @turf/helpers):AGPL(marchingsquares) 与 EPL(jsts)传递组件从依赖树根除(pnpm why 双零验证) - Cesium Apache-2.0 许可副本随产物分发(copy dist/Cesium/LICENSE.md) - 新增 THIRD-PARTY-NOTICES.md:依赖许可汇总 + TinyMCE 双许可例外 + 演示资源清单 + 已知接受风险(image-size 无补丁公告登记) - 演示媒体治理(决策 D9/D25 路线 A):react-dev.pdf(疑似 Meta 版权)→ 脚本自制 demo.pdf(1.2KB);来源不明音频 → 正弦合成 WAV(版权自有); 零引用的 video.mp4/poster.jpg 删除——public 15.5MB → 3.2MB - 热力图演示数据降采样 21,025 → 5,385 点(5.3MB → 1.1MB,图面密度仍足演示) 文档与社区(审计 docs-8、opensource-6): - README 重构:在线演示链接、环境变量表、目录结构、部署、功能说明(鉴权/ 暗色/双语/a11y 范围)、第三方许可说明、统计与隐私、License 章节 - 新增 SECURITY.md(私有漏洞报告+已知限制)、CONTRIBUTING.md、CHANGELOG.md (治理批次全记录)、CODE_OF_CONDUCT.md、PR/feature_request 模板 - all-contributors 配置修正(双 org 拼接根因)并重生成,三个贡献者链接 200 - package.json 补 description;LsDocs 空目录删除;仓库卫生测试更名 repo-hygiene.test.ts(名实相符) 验收:typecheck/lint/test/build/体积预算全绿;浏览器实测热力图(降采样数据) 与音频可视化(合成 WAV)页面正常,四项新资源全部 200
- Dockerfile 重建为多阶段:node:22-alpine 构建(层缓存友好的依赖前置 + corepack pnpm --frozen-lockfile + CESIUM_ION_TOKEN build-arg)→ nginxinc/nginx-unprivileged:1.27-alpine 运行(全程非 root,审计 ops-1/7) - 新增 nginx.conf:SPA history 回退(修深链 404 类问题)、哈希资源一年长缓存、 入口 no-cache、gzip - 新增 .dockerignore(本地 .env* 秘书绝不进镜像,token 只走 build-arg) - deploy.yml 开启 force_orphan:gh-pages 孤儿化部署,历史不累积(审计 extra2:71 提交/33MiB + 旧产物含已泄露 token 的克隆暴露面) 验收:docker build 一次通过;docker run 实测 GET / 与深链 /table 均 200 (SPA 回退生效),/Cesium/LICENSE.md 200(Apache-2.0 随分发)
Cesium 六页健壮性(审计 ui-8/code-5/10/11/12): - Viewer 初始化全部包 try/catch,WebGL 不可用时渲染 Result 可见兜底 (此前 GeoHash 的 Spin 永转、其余页整块空白) - Trajectory:初始化定时器清理 + 绘制事件处理器随卸载销毁 + 回调卸载守卫 - GeoHash:GeoHash 绘制 setTimeout 补 isDestroyed 卸载守卫 - ThermalMap:img.onload 卸载守卫 + Blob URL 用后 revoke(此前从不释放) 热力图渲染重构(审计 perf-2,方案 Step4): - Entity API 逐点渲染改 PointPrimitiveCollection 批量路径(可支撑 10 万级点), id 直接挂原始数据点,hover 经 picked.id 读取;删除对 entities.cluster 的 21k 次无效属性写入(EntityCollection 无该属性,聚合从未生效) - 数据按需加载:挂载即 fetch 改为首次使用时拉取 + Promise 缓存,viewer 初始化 与数据加载解耦;视野按数据包围盒 flyTo 杂项(审计 code-6/7/15/16、ui-6、feature-12/15、chain-7/8、extra-2-10): - Frequency tooltip 恢复真实数据渲染(复用带转义的 renderMatchDetail, 替换 '已经获取到数据: matches;' 占位字面量) - Signature 画布 aspect-ratio 自适应(补漏);html2canvas 补 catch; useWavesurfer 经 ref 取最新配置消除陈旧闭包 - 六个父级菜单路径补 redirect(直接访问不再空白);menu.feature.D3 键补齐; 删除死模型 useUser 与 valtio 配置(全仓零消费);git gc 清理 tmp_pack 验收:全门禁绿;浏览器实测 ThermalMap/GeoHash/Trajectory 渲染正常、 点云按钮(Primitive 路径+按需数据)可用、零控制台错误
…ging 首页图表(审计 ui-7):远程 JSON(render.alipay.com)本地化到 public/data/charts,useChartData 三态 hook(Spin/Result 可重试/渲染), 五张卡片补标题——数据源不可达不再静默空白 FullCalendar(审计 ui-3/13、extra-3-6):侧栏 AntD 化(Typography/List/ Checkbox,demo-app* 裸样式类随之消失)、window.prompt/confirm 换受控 Modal 与 Modal.confirm、日历 locale 跟随全局语言切换 RichText(审计 ui-16):console.warn 输出改为页面可见内容回显 PDF(审计 perf-9):15 页全量渲染改分组懒渲染(每组 2 页 + 翻页) 门禁与配置: - 体积门禁并入样式管线覆盖检查(审计 extra-3-9):源码使用的工具类必须 存在于产物 umi.css,min-w-96 式静默失效从此被抓住(工具类前缀表判定, 自定义类不误报) - .vscode 瘦身(决策 D34):删除个人 todo-tree 主题与 wrapTabs,保留 tailwind 关联/cSpell 词库(对协作者有正收益的共享配置) 验收:全门禁绿;浏览器实测 Home 五图表本地数据渲染、日历侧栏与弹窗、 三组父级菜单 redirect(子路由模式修正后生效)、零页面错误
绿色范围标记块缺少注释中声称的'仅第一个类型组'判断,data.forEach 每个 类型组重复绘制一遍(N 层 0.1 透明度叠加变深、标记线与频率标签重绘)。 补 typeIndex === 0 守卫(审计 code-7)——至此 166 条确认发现中的代码项全部闭环
mock/userAPI.test.ts 落在 umi 的 mock 扫描范围(mock 目录下全部 .ts/.js)内, 被当作 mock 文件 require 时 vitest 拒绝 CJS 加载,整批 mock 加载失败: dev 下 createMockMiddleware 对 null 调 Object.keys,所有请求 HTTP 500; max preview 启动即 fatal(93bf356 引入,长驻的旧 preview 进程掩盖了问题)。 - 查询逻辑抽到 src/services/demo/userQuery.ts,mock 与静态演示层共用, 测试随之移出 mock 目录 - 顺带修复 Table 名称/昵称搜索无效:查询表单按 dataIndex 传 name/nickName, 此前 mock 与静态实现只认 keyword/gender - config 增加 mock.exclude 兜底(config/mock.ts) - 新增 scripts/mock-loadable.test.ts:用 umi 的 getMockData 按项目配置加载 mock,纳入 pnpm check 验收:pnpm check 全绿(36 例);dev 实测 GET / 与 login/currentUser/ queryUserList 均 200,name/nickName 过滤生效;max preview 正常启动
umi request 运行时同步调用 handler(error, opts) 并丢弃返回值,随后自行 reject 给调用方。 原 errorHandler 为 async 且各分支 return Promise.reject(error),每个失败请求都多出一个 无人处理的 rejection(浏览器实测 Uncaught (in promise) AxiosError);也不接收 opts, logout 的 skipErrorHandler 形同虚设。 - errorHandler 改为同步:只负责提示/跳转;skipErrorHandler 时原样抛出交给调用方 - 主动取消的请求(ERR_CANCELED)不再提示"网络异常" - token 只注入同源或配置的 baseURL 请求,第三方绝对地址不带凭证 - 测试改写:断言不产生 rejected promise;新增复刻 umi 运行时 catch 分支的契约测试 (用旧实现回放:6 例失败并报 Unhandled Rejection,证明测试能拦住该回归) 验收:pnpm check 全绿(42 例);dev 实测伪造 token → 401 提示、清 token、回登录页, 控制台无 Uncaught (in promise)
纯静态托管(GitHub Pages / Vercel / Docker nginx)没有登录后端,auth.ts 又没有静态兜底, 登录请求 405/404、currentUser 404 → 整站被路由守卫锁在 /login(875efa5 引入; max preview 自带 mock 掩盖了这一点)。 - 抽出 services/demo/mode.ts:USE_BACKEND 判定供鉴权与表格数据层共用 - auth.ts 静态模式:login 本地签发演示 token、fetchCurrentUser 本地解析 token (保留 dontHaveAccess 权限演示)、logout 不发请求;后端模式行为不变 - getInitialState 统一经 fetchCurrentUser;启动换取用户改 skipErrorHandler, 失效 token 静默回落登录页(不再在启动期弹静态 message 警告) - 子路由直链/刷新:GitHub Pages 部署复制 404.html,Vercel 增加 SPA rewrite - 新增 auth.test.ts:两种模式契约 5 例 验收:pnpm check 全绿(47 例);生产构建 + 纯静态服务器(非 GET 返回 405、SPA 回退)实测: 未登录停留 /login、登录态进入 /home 与 /table 深链、名称搜索、dontHaveAccess 403、 登出回 /login 清 token,全程零 /api 请求、控制台无新增错误
…ing natives PDF 页 onPull 报错的真正根因(此前归因于 splitChunks,b7b6399 的去 enforce 并未生效): umi 默认 `import 'core-js'` 注入 216 个模块,其中 176 个是 esnext 提案 polyfill;umi 锁定的 core-js 3.34 里约 95 个提案实现带 forced:true,会强制覆盖浏览器原生实现。Promise.try 被换成 不透传参数的旧提案版(toString 仍伪装 native,应用内 Promise.try((a,b)=>[a,b],1,2) 得 [null,null]),pdfjs 5 按 URL 加载时 GetReader 流的 sink 为 undefined。本地文件加载不走该路径, 原版 pdfjs 单独运行正常——对照实验定位。 - config polyfill.imports: ['core-js/stable']:polyfill 216→40 个,esnext 176→0 - PDF 页:换文件/加载成功时重置分组,分组按步长对齐(不再 3-4→4-5 回退重叠), label 与 input 关联,限定选择 PDF 验收:pnpm check 全绿;生产构建 + 纯静态服务器实测:demo.pdf 经 URL 渲染 2 页、 Promise.try 透传参数;24 个路由逐一冒烟(含 6 个 Cesium 页 WebGL 渲染),polyfill 变更 无新增控制台错误(D3 NaN 与 AudioPlayer 崩溃为既有问题,后续提交修复)
…-load "首屏 728KB"只统计 index.html 同步脚本;登录后落地页 /home 实测 12 个 JS、1275KB gzip, 其中 vendor-media(xgplayer/wavesurfer,经 @antv/g→html2canvas 被整组拖入)与 vendor-d3 (图表库用到的 d3-* 与 D3 页全部 d3 同组)都是命名 + enforce 分组造成的误合并。 - splitChunks:删除 media、d3 强制命名组(跨域共享库交给 webpack 按引用拆分); cesium 组补 @cesium/*(cesium 包仅 re-export,此前 4.95MB 引擎落在数字 chunk 里) - config/chunkGraph.ts:构建时记录各 chunk group 实际加载的文件(写入 node_modules/.cache,不进 dist),两条产线同源 - check-bundle-size.mjs:新增路由真实首屏指标(入口 + 布局 + 路由及其异步依赖); 修复样式覆盖检查正则(变体前缀此前为必选,普通工具类一律漏检,包括它要抓的 min-w-96);fileURLToPath + readdirSync 跨平台;按 index.html 解析样式表(兼容哈希文件名) - size-budget.json:阈值收紧为实测 + 约 10%(入口 780KB、/home 1250KB、/login 780KB、 dist 30MB、public 4MB) 实测:/home 1275→1153KB gzip(10 个 JS,与浏览器实际加载清单一致);入口 736→710KB; vendor-cesium 83KB→4.3MB(引擎归组,6 个 Cesium 页共享缓存);门禁全绿
…aders b72a86a 的 nginx 对全部 js/css 设 1 年 immutable,注释称"带内容哈希",但 umi 默认不加哈希 (umi.js、1527.async.js 等固定文件名):发版后老用户长期命中旧脚本,新旧数字 chunk 混用可致白屏。 另 nginx 自带 mime.types 没有 .mjs,pdf.js 的 module worker 会以 octet-stream 下发被浏览器拒绝。 - config hash: true:产物文件名带 8 位内容哈希 - nginx/default.conf:仅哈希文件 immutable;Cesium 资产/演示数据等无哈希文件 no-cache 协商; .mjs 单独 location 设 application/javascript(server 级 types 块会整体替换映射表,不能那样写); server_tokens off;缺失的哈希文件返回 404 而非回退 HTML - nginx/security-headers.conf:nosniff / Referrer-Policy / X-Frame-Options 经 include 注入每个 location(location 级 add_header 不继承 server 级);CSP 留模板,按实际来源收敛后启用 - 运行镜像升级到 nginx-unprivileged 1.30(当前稳定线)并按多架构摘要钉住 - .dockerignore 排除 src/.umi*、.mfsu、.swc(含宿主机绝对路径的本地生成物) 验收:docker build + run 实测:/ 与 /table 深链 200 no-cache;哈希 js immutable; pdf worker .mjs 为 application/javascript;Cesium worker 与 data json no-cache;安全头齐全、 Server 无版本号;POST 405;缺失哈希文件 404;浏览器经容器渲染 PDF 2 页与首页图表,控制台无错误
富文本此前经 @tinymce/tinymce-react 从 Tiny Cloud 加载(npm 的 tinymce 只用于类型), 2fe9e00 升级 8.9.1"修 XSS"对运行时无效;没有登记域名的有效 key 时 TinyMCE 8 Cloud 编辑器 只读(浏览器实测 "All created TinyMCE editors are configured to be read-only"), 部署流水线也未注入 key,演示站同样只读。 - tinymceBundle.ts:按官方 bundling 方式导入核心/模型/主题/图标/皮肤(oxide 与 oxide-dark) /内容样式与所用插件(含 help 插件 keynav 文案);编辑器 licenseKey="gpl" - 皮肤随全局暗色主题切换(按 key 重建编辑器,草稿经 ref 保留) - 移除 TINYMCE_API_KEY 的 define 与类型声明;README / THIRD-PARTY 许可说明改为与实际一致 (自托管即随产物分发 GPL 组件,闭源商用需商业许可或替换) 验收:pnpm check 全绿;构建后 TinyMCE 仅在富文本路由异步 chunk(约 500KB gzip),/home 与入口体积 不变;浏览器实测 8.9.1 可编辑、输入与内容回显正常、零外部请求零失败请求、暗色为 oxide-dark
- ESLint 覆盖 .mjs/.cjs(ESLint 8 的 `eslint .` 默认只查 .js,scripts/*.mjs 此前完全逃逸: 单独 lint 体积脚本即有 8 个警告);scripts 目录允许 console(CLI 本职) - lint-staged 与 CI 同引擎同规则:eslint --fix --max-warnings=0,并纳入 mjs/cjs - CI:push 与 PR 按分支合并并发组,同仓库分支开 PR 不再双跑;拆出 build 矩阵同时冒烟 build 与 build:github;主产线构建后执行体积预算与样式覆盖门禁 - 依赖 override:hono 4.12.34、brace-expansion 1.1.21(新公告,均构建链)、tmp 0.2.7 (all-contributors-cli 链路的 high 路径穿越,API 兼容已验证);audit 33→16 条,high 5→2 (仅剩无补丁的 image-size,已登记为接受风险) - .npmrc 去掉仓库级 npmmirror(README 的既定意图;CI/Docker/海外贡献者走官方源, 国内开发者在 ~/.npmrc 配置镜像) - .gitignore 覆盖 .env 与 .env.*(保留 .env.example) - DndKit Item 导出顺序为 organize-imports 格式化产物 验收:pnpm check 全绿(lint 含 mjs);frozen-lockfile 校验通过;all-contributors CLI 可用
…ader menus - tailwind.css 补回 preflight 中的边框基线(*::before/after 的 border-width:0 与 border-style:solid,及 hr 顶边):关闭 preflight 后 .border 只有宽度没有样式, RichText 回显框边框此前不显示,任何 border* 工具类都会静默失效 - 更正 app.tsx 与 tailwind.config.js 注释:antd cssVar 变量挂在组件根 .css-var-* 作用域, 不在 :root(浏览器实测 :root 上为空),token 类只在 antd 组件树内生效 - 登录页改用 bg-bg-layout / text-text-tertiary token 类,暗色模式不再是浅底深卡 - a11y:<html lang> 随语言设置(runtime render);覆盖 umi 默认 viewport,允许缩放 (WCAG 1.4.4);顶栏账户/主题/语言由 hover Popover + div onClick 改为 antd Dropdown (button 可聚焦、hover/click 双触发、role=menu 并标记当前选中项);GitHub 链接 noopener - 富文本:主题切换重建编辑器前从旧实例取内容作为新编辑器初始值(不依赖 change 事件) 验收:pnpm check 全绿;构建产物含边框基线;浏览器实测回显框 1px solid、登录页暗/亮背景 随算法切换、html lang=zh-CN、viewport 可缩放、主题菜单切换暗色且富文本草稿保留; Table/日历/签名/Cesium/拖拽等页面视觉无回归
…uards - components/CesiumViewer:createDemoViewer(通用控件配置 + 初始化失败返回 null)与 CesiumInitError 兜底;6 个 Cesium 页各约 40 行重复的 Viewer 配置/try-catch/Result 收敛 - 恢复署名区:此前 6 页都把 cesiumWidget.creditContainer 设为 display:none, Cesium ion 与影像数据提供方的条款要求显示署名 - GeoHash:初始化失败时不再一边显示兜底一边 Spin 永转 - ThermalMap:按钮回调经 loadDataFor 统一处理——数据加载失败不再产生 unhandled rejection,等待数据期间组件卸载则放弃绘制(此前 await 后直接写已销毁的 viewer) 验收:typecheck/lint 全绿;浏览器实测 6 页渲染(canvas 像素采样确认影像已绘制, Bing 影像瓦片 200)、左下角 Cesium ion 署名可见、点云按钮按需加载数据,控制台无错误
…ale, local chart data - Excel 导入改取 cell.text:邮箱被 Excel 自动转超链接、富文本或公式单元格的 value 是对象, String(value) 得到 "[object Object]";行 key 独立于名称(重名不再冲突);导出链接挂到 文档后点击、下一轮再 revoke;提示改用 App 上下文 message - GitHub Pages 子路径:布局 logo 与 AudioVisible 音频改经 PUBLIC_PATH 拼接 - FullCalendar:确认框改用 App 上下文 modal;英文用内置 en(美式、周日起始),侧栏日期 随语言格式化(此前固定英文) - D3 频率图:首段刻度为 0 Hz,log10(0) = -Infinity 使 3 个频段 x/width 为 NaN(控制台持续 报错),首段改线性插值;d3 导入统一为具名导入 - 首页图表数据全部本地化且项目自制:柱状图/旭日图此前仍拉 AntV 远程示例数据; 1deb343 本地化的折线/散点实为 AAPL 股价与气温距平第三方数据,却在 THIRD-PARTY 中 登记为"项目自制"。新增 scripts/generate-chart-data.mjs 确定性生成四份数据 (固定种子,重复生成逐字节一致),数据体积 128KB → 58KB - Table 编辑态更名 editingUser;access.ts 参数类型改为 AppInitialState 验收:pnpm check 全绿;浏览器实测 Excel 导入超链接/富文本/重名三类用例正确、导出生成 users.xlsx;日历英文周日起始、侧栏 "Sep 21, 2026";D3 46 个 rect 零 NaN;首页 5 图渲染、 零外部请求;音频经 PUBLIC_PATH 200;控制台无错误
…layer - 页面崩溃:2ac4c80 把歌词外移到 lyrics.json 时写成了转义后的字面量 \n(真实换行为 0), xgplayer-music 解析为空后抛 "Reduce of empty array",整页落入 ErrorBoundary - 版权:此前热链第三方 CDN 上的商业歌曲与专辑封面,并随仓库分发该歌曲完整歌词。按演示媒体 自制替换的约定(D9/D25 路线 A)改用项目自制的 public/audio/stereo.wav 与自写示例 LRC (lyrics.ts,以真实换行拼接);唱片与背景改为纯 CSS 绘制;页面信息改为自制素材说明 - 频谱画布:此前误取 id="canvas" 的外层 div 设置尺寸(从未生效),且频谱挂在全页第一个 canvas 上;改为组件内查询 canvas 并随容器宽度同步 验收:浏览器实测页面正常渲染、自制音频经 PUBLIC_PATH 加载 200 并播放、5 行歌词解析与滚动、 频谱绘制、画布随容器 688×160;无外部请求
- geohashBounds 的 latitude/longitude 此前返回最后一轮二分点(恰好落在格子边上), 改为格子中心;页面只用 min/max,无行为回归 - JSDoc 示例值此前是错的(wx4g0s8q),实现本身与标准 geohash 算法一致: (39.9042, 116.4074) 精度 8 → wx4g0bm6、精度 12 → wx4g0bm6c408(独立参考实现核对) - 测试不再称"实测为准",新增 12 位已知值与中心点断言 验收:geoHash 测试 14 例全绿
- README:静态部署下的本地演示鉴权、部署细节(404.html、SPA rewrite、nginx 缓存与安全头、 CSP 模板)、PDF 浏览器要求、无障碍范围、演示媒体来源(含图表数据生成脚本与 xgplayer 演示 CDN); 目录树去掉已删除的 models - CLAUDE.md:状态管理不再写 Valtio(配置已删);新增易踩坑清单(mock 目录、polyfill、 演示数据层模式与 preview 自带 mock、PUBLIC_PATH、图表数据来源) - SECURITY.md:私有漏洞报告入口对报告者是仓库 Security 标签;门禁清单与已知限制更新 (本地演示 token 无安全性、localStorage token、CSP 未默认开启) - THIRD-PARTY-NOTICES:图表数据、音频页歌词与唱片的来源登记;更正"字跳动"笔误; 移除已删除的 artplayer;登记本轮替换的第三方内容 - CHANGELOG:新增审查修复小节,并更正"首屏 728KB"只统计入口同步脚本的口径
|
Important Review skippedToo many files! This PR contains 277 files, which is 177 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: ⛔ Files ignored due to path filters (8)
📒 Files selected for processing (277)
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying umi-react-admin with
|
| Latest commit: |
c5c390c
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://20857bae.umi-react-admin.pages.dev |
| Branch Preview URL: | https://feat-next-umi.umi-react-admin.pages.dev |
- 误报根因:@cesium/engine 的 Source/Core/Ion.js 自带公开的默认 ion token(HS256 JWT), 打包后必然进入产物,原先的固定 grep 每次都会命中;PR #9 两条构建都挂在这一步,并无秘钥泄露 - 改为 scripts/check-dist-secrets.mjs:扫描产物里所有 JWT 形态字符串(不再只认 HS256 头部), 只放行从已安装 Ion.js 动态读取的 Cesium 默认 token,读取失败直接判失败; 输出只含文件路径与 sha256 指纹,不打印 token 值 - CI 只在 pull_request 与 workflow_dispatch 时触发:分支 push 与 PR 双触发时, 被并发取消的那次会以 cancelled 留在 PR 检查列表里 - README 徽章改为指向 master 的 deploy.yml:ci.yml 不在 master 上运行,原徽章只反映最近一次分支运行 - 同步 SECURITY 与 CHANGELOG 验收:新增 4 例测试(伪造 JWT 被拦截且输出不含 token 值、Cesium 默认 token 放行、白名单来源可读、 产物目录缺失判失败),pnpm check 全绿(52 例);无 secret 的干净 worktree 构建(等价 CI)只含 Cesium 默认 token,扫描通过;含本地 .env.local 注入 token 的产物被判失败,只显示指纹
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
feat/next-umi的全部改动,共 29 个提交,一次合入 master:740461f..d3e9ed0。依据 2026-09-20 的全量审计,做选择性重构。70730b6..77a0054。2026-09-21 审查上面 15 个提交,发现 3 个阻断、4 个高危和若干改进项,全部修复。改动共 283 个文件(+8,680 / −299,228)。删除行里约 28 万是两份热力图数据;排除数据、锁文件和二进制后,代码 diff 为 +3,239 / −10,045,其中约 8k 行是删掉的 Designable 死代码。
建议用 Create a merge commit 合并:保留逐条提交说明,以及"审查 → 修复"的对应关系;master 主线用
git log --first-parent看仍然干净。审查修复要点
mock/下的测试文件被 umi 当成 mock 加载,dev 全站 500,preview 启动即退出Uncaught (in promise),skipErrorHandler不生效Promise.try执行中新发现并修复:
其余改进见各提交说明,以及 CHANGELOG 的"审查修复"小节。
建议阅读顺序(按主题,数据文件与锁文件可跳过)
有已知问题的中间状态(bisect 时请跳过,或用
git bisect --first-parent)区间都是含左不含右。
875efa5..2e5737893bf356..70730b61b23518..0f515ee2ac4c80..e360a03b72a86a..290af0f验证
pnpm check全绿(typecheck、lint 含 .mjs、48 个测试);frozen-lockfile 校验一致;pnpm audit从 33 条降到 16 条,high 从 5 降到 2,剩下的两条都是 image-size,暂无补丁,已登记为接受风险。/umi-react-admin/.mjs类型、深链、PDF / 富文本 / 音频)体积前后对比(gzip):
合并前清单(完成后执行
gh pr ready)CESIUM_ION_TOKEN.env.example中两行 TinyMCE 配置(TinyMCE 已改为自托管,这两行不再需要)check、build (build)、build (build:github)合并后清单
feat/next-umi分支nginx/目录