npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gantfdt/fp-umi-plugin

v0.4.2

Published

umi plugin that wires @gantfdt/fp-sdk into a umi app: entry injection, React Profiler root container, dev-server /fp-viewer/ static hosting

Readme

@gantfdt/fp-umi-plugin

把 @gantfdt/fp-sdk 性能采集接入 umi 应用的插件。宿主只需安装本包并在 umi config 注册,无需直接依赖 @gantfdt/fp-sdk。

安装与注册

pnpm add @gantfdt/fp-umi-plugin -D   # npmjs 公开包,默认 registry / npmmirror 直接可装
// framework/config/config.ts
plugins: [
  // ...已有插件
  require.resolve('@gantfdt/fp-umi-plugin'),
],
fpPerf: {
  appKey: 'bom-web',                 // 缺省取宿主 package.json name(多应用共用包名时必须显式)
  // collectUrl: '/integration/perfCollect/ingest.api', // 默认值,dev 与生产同形(网关按前缀路由)
  // configUrl: '/integration/perfConfig/findConfig.api', // 默认值,显式 '' 关闭远端采样
  // compress: true,                 // gzip 上报;后端未支持 gzip 请求解码时必须显式 false
  // panel: true,                    // 取证面板入口(默认 true);false 时完全零副作用
  // panelUrl: '/fp-viewer/panel.js',// 面板脚本地址默认值,与 /fp-viewer/ 托管同路径
  // traceRate / slowTraceMs / flushIntervalMs 均有默认值
  // profiling: true,                // 取证构建才开(默认关):react-dom 切 profiling 产物,详见下节
  // autoProfile: { include: ['src/pages/**'] }, // 组件级自动包装(默认关),依赖 profiling 开启;
  //                                            // 业务源码在宿主 cwd 之外时须设 cwd(见「组件级归因」节)
},

门禁与开关

总门禁(production-only,fail-closed):仅 production build(api.env === 'production')插件才可能 生效;umi dev / test / 环境识别不明一律按 dev 处理,无论下列开关如何配置都注册后立即返回、零副作用 (不注入 entry/runtime、不挂中间件、不动 webpack/babel 配置、不写文件——宁可不采集,也不影响同事 HMR)。

生产构建内再由开关决定是否注入:

  • FP=1 环境变量,或
  • fpPerf: { enabled: true }(构建期固化,生产接入用)

普通生产构建未显式开启同样零注入,产物与基线零增量。

开启后发生什么

  1. entry 最前面注入 init.js → initFpPerf(sdkConfig)(config 在构建期内联);
  2. 注册 runtime 插件:React Profiler 包裹根节点(生产 React 不触发回调,透明传递);
  3. 宿主若安装了 @gantfdt/fp-viewer:注册 /fp-viewer/ 静态中间件,把 viewer 的 dist 以同源 子路径托管(viewerPath 可改路径,viewerStatic: false 可关闭)。addBeforeMiddlewares 仅 dev server 生效——总门禁下 dev 恒短路,此注册在显式开启的生产构建中只是惰性 no-op、不进产物, 面板静态资源由宿主构建产物承接(见「viewer 面板」节)。

URL 分类(fpPerf 配置)

umi dev server 的 HMR 通道是 SockJS 长连接(断线自动重连),采集它会占住 trace 在途名额、 把所有 trace 强制截断——插件默认内置忽略 /dev-server/、/sockjs-node/、.hot-update.,无需配置。

  • ignoreUrls: string[]:追加不采集的 URL(子串匹配),与内置默认合并;
  • streamingUrls: string[]:SSE/流式接口(如 ['/bommgmtsse/'])——照常采集(瀑布图可见, 事件带 streaming:true 标记)但不占 trace 在途名额,长连接不再把 trace 挂到强制截断。

注意:sdkConfig 经 JSON 内联进 entry,此处只支持字符串;需要 RegExp 时请直接用 @gantfdt/fp-sdk 的 initFpPerf。

viewer 面板(仪表盘)接入

宿主安装 @gantfdt/fp-viewer 后,面板即可经 iframe 同源嵌入:

<iframe src="/fp-viewer/" />

viewer 的接口 baseURL 固定为同源 /integration(接口路径带 .api 后缀,经网关按前缀路由;perfmgmt 已并入 integration-app,2026-09-20 与后端对齐不设独立前缀),生产走聚合网关。 生产部署:把 node_modules/@gantfdt/fp-viewer/dist 拷入宿主构建产物的同名子路径(如 dist/fp-viewer/),由宿主既有静态托管(nginx/OSS/CDN)承接,无需动后端与网关路由。

取证面板(Runtime Forensics 阶段一)

sdk 内置面板入口 stub(默认开启,未激活零副作用)。三入口任一命中即激活:

  • 快捷键 option+shift+P(按 e.code === 'KeyP' 判定,绕开 macOS option 组合键的 key 变体);
  • URL 参数 ?__fp_debug=1;
  • localStorage.__fp_panel = "1"。

激活后按需注入 panelUrl 脚本——自包含 classic script(React 18 内联、Shadow DOM 自挂载、暴露 window.__fpPanel),加载失败仅 console.warn,不影响宿主页面。

前提:宿主升级的 @gantfdt/fp-viewer 版本 dist 含 panel.js。/fp-viewer/panel.js 由宿主 静态产物承接(与 viewer dist 同包拷入、同路径,见上一节)。

  • panel: false:关闭入口 stub(三入口均不再注入脚本);
  • panelUrl: '/自定义路径/panel.js':面板脚本托管在别处时覆盖默认地址(空串视为未配置)。

组件级归因:profiling / autoProfile(默认均关)

普通生产构建的 react-dom 不触发 Profiler.onRender 回调,组件级归因(面板「组件分析」区) 需要显式开启 profiling 构建。设计规格见 docs/PROFILER_AUTOWRAP.md。

fpPerf: {
  enabled: true,
  profiling: true,                              // 显式开启(默认关)
  autoProfile: { include: ['src/pages/**'] },   // 构建期自动给业务组件 export 包 Profiler 边界
},
  • profiling: boolean(默认 false,必须显式开启):chainWebpack 注入 react-dom$ → react-dom/profiling alias(用 createRequire 从宿主 cwd 解析,指向宿主自身 node_modules,不经过插件依赖树)。React 16/17 宿主会成对注入 scheduler/tracing$ → scheduler/tracing-profiling——缺它 Profiler commit 路径抛 React 错误 #302 直接白屏(tracing 子系统 React 18 才移除,18 只需单 alias)。宿主 react 版本探测 或 profiling 产物解析失败时不注入任何 alias 并 console.warn(fail-open:半套 alias 比不注入更危险)。 注入时若检测到 umi 内置前缀 alias(react-dom → <cwd>/node_modules/react-dom,preset-built-in 默认注入),会先摘下、注完精确键再挂回末尾——webpack4 对象 alias 按键序首个匹配生效,不重排 则 react-dom$ 被前缀键遮蔽永不命中(scheduler/tracing 同理);重排中途失败会回滚为注入前 状态(原 alias 不丢)并 warn。
  • autoProfile: { cwd?: string, include?: string[], exclude?: string[] } | false(缺省关):经 modifyBabelOpts 注入 @gantfdt/fp-babel-plugin-profiler,构建期自动包装业务组件 export,并在输出目录产出 fp-components.json manifest(组件 id → 文件:行)。manifest 走 sidecar 汇合 + 跨构建快照(2026-10-25 起):各 babel 进程只落自己本次实际转换的切片(原子 rename 写 $TMPDIR/fp-profiler-manifest-<hash>/worker-<pid>.json),本插件注册时清被杀构建的 残留 worker sidecar(保留快照)。onBuildComplete 先以 deferWarnings: true 临时合并全部已就绪 切片 ∪ 跨构建快照(<cwd>/node_modules/.cache/fp-profiler/manifest-*.json, configHash(cwd/include/exclude) 匹配才承接、快照条目按 existsSync 修剪已删文件)并落盘 (组件并集、确定性排序),但此时没有 sidecar/manifest 仍属合法中间状态,不提前告警;主进程 exit 兜底在 babel sidecar 写入后做最终合并,并只在此时按三态判定覆盖告警——babel-loader 磁盘缓存命中的文件不经插件、无 sidecar,其包装记录由快照承接,暖缓存构建 manifest 不再缺席; babel 插件版本注入 options(缓存 key 含 options JSON):插件升版本即自动全量重转,杜绝宿主 静默重放旧版转换结果。 include 缺省 ['src/**'],exclude 缺省 ['**/*.test.*', '**/*.spec.*', '**/node_modules/**'] (与 babel 插件缺省对齐)。cwd 缺省宿主 umi cwd,是 include/exclude 匹配的相对路径基准: monorepo 下业务源码在宿主 cwd 之外(如 umi 跑在 framework/、页面在 ../packages/*)时必须 显式设为共同祖先目录,否则 babel 插件对 path.relative(cwd, file) 以 ../ 开头的文件直接跳过,业务页面永远包不到。cwd 支持相对路径——以 umi cwd(如 framework/)为 基准 resolve 成绝对路径再传给 babel 插件,因此 cwd: '..'(仓库根)这类写法可跨机器/CI 移植; 绝对路径原样透传。fp-components.json 的完整性不再依赖冷构建(暖缓存由快照承接), 但首次构建(或快照被清)仍需全量 transform 才有完整快照——autoProfile.cwd/include 变更本身会改变 babel options、自动触发全量重转。
  • autoProfile 依赖 profiling:包装产物在非 profiling 的 react-dom 上拿不到 Profiler 回调,注入也是白注入——autoProfile 开而 profiling 未显式开时,插件拒绝注入 babel 插件 并 console.warn,需同时设置 profiling: true。
  • 两者缺省均关:未开启时插件不注册任何 chainWebpack / modifyBabelOpts 逻辑, 普通生产构建产物与基线零增量(可 diff 证明)。SDK 未初始化时 fpProfile 运行时 fail-open 原样返回组件,已注入产物在 SDK 缺失时行为与未包装一致。

生产接入形状

enabled: true + collectUrl 指向网关承接的上报地址;/fp-viewer/ 静态资源由拷入宿主产物的静态文件承接,中间件机制不进产物。

pnpm 说明

init.js/runtime.js 对 @gantfdt/fp-sdk、@gantfdt/fp-runtime-react、react 的引用从插件自身依赖树解析 (react 为 peer,pnpm 自动链接宿主版本,保证单例)。宿主不需要直接安装 @gantfdt/* 其他包。