# assets/js ## cheerio.min.js 打包好的 [cheerio](https://github.com/cheeriojs/cheerio)(含 parse5 解析器),注入到 fjs(QuickJS)脚本组件运行环境,作为 `Widget.html.load` / `Widget.dom.*` 的实现。 上游 ForwardWidgets 宿主的约定就是 "Widget has built-in cheerio",脚本以同步 cheerio API 消费 DOM——fjs 的 Dart 桥(`fjs.bridge_call`)只有异步 Promise 形态, 因此 DOM 解析必须完整运行在 JS 侧,不能走宿主桥。 全局导出名:`__fjsCheerio`(`__fjsCheerio.load(html)`)。bundle 头部带一个 `atob` polyfill(`entities` 包解码实体表需要,QuickJS 没有内置 atob/Buffer)。 ### 重新构建 ```bash mkdir /tmp/cheerio-bundle && cd /tmp/cheerio-bundle npm install cheerio@1.1.2 esbuild echo "export { load } from 'cheerio';" > entry.js npx esbuild entry.js --bundle --format=iife --global-name=__fjsCheerio \ --platform=browser --minify --banner:js="$(cat banner.js)" \ --outfile=cheerio.min.js ``` `banner.js` 为 atob polyfill,内容见当前 bundle 文件头部(第 1 段 `if (typeof globalThis.atob === 'undefined')`)。`--platform=browser` 会选择 cheerio 的 browser 入口(只含 load/parse,不含依赖 Buffer/undici 的 loadBuffer/fromURL)。构建后用一个无 Node 全局的裸 `vm` 沙箱冒烟验证 `load/text/attr/closest/Array.from` 再提交。