# 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` 再提交。
