30 lines
1.4 KiB
Markdown
30 lines
1.4 KiB
Markdown
# 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` 再提交。
|