关于 wasm-compatibility
用于评估 marimo Notebook 在 WebAssembly 环境中能否运行的检查技能,面向维护浏览器端 Notebook 的开发者。它结合 marimo 的 lint 规则与手动检查,并生成含问题和建议的报告。
主要功能
- 01运行 WASM lint 规则
- 02检查依赖与运行时模式
- 03评估并发行为限制
- 04生成兼容性报告与建议
适用场景
- 01检查 Notebook 的浏览器运行兼容性
- 02定位不兼容的导入和系统调用
- 03评估依赖包及并发代码风险
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ marimo-team/ skills --skill wasm-compatibility安装后在 Claude Code 中输入/wasm-compatibility确认已加载。
附带文件references/pyodide-packages.md
详细介绍
marimo 笔记本的 WASM 兼容性检查器
检查 marimo 笔记本能否在 WebAssembly(WASM)环境中运行,例如 marimo playground、社区云或导出的 WASM HTML。
说明
1. 读取笔记本
读取目标笔记本文件。如果用户未指定,请询问要检查哪个笔记本。
2. 运行 marimo 的 WASM lint 规则
marimo 自带三条 lint 规则,可自动捕获大多数 WASM 不兼容问题。请先运行这些规则,并根据其输出生成报告,而不是手动重新检查这些问题:
marimo check <notebook> --select MW --format json
- MW001
incompatible-import— Pyodide 中缺失或无法正常运行的标准库模块(subprocess、pdb、dbm、resource、fcntl、termios、readline、curses、tkinter、pydecimal、test),以及需要原生同步、共享内存、管道或进程派生的 multiprocessing 导出项和子模块(Lock、Condition、Semaphore、Barrier、Manager、Pipe、RLock、shared_memory、ForkContext/ForkProcess、ThreadPool等)。Process、Queue、SimpleQueue、Pool和ProcessPoolExecutor仍被允许——它们通过与 WASM 兼容的协作式适配器运行(见第 3 步)。 - MW002
unsafe-system-call—os.system()、os.fork()、signal.signal()、breakpoint()等调用,即使导入本身成功,也会在 Pyodide 中失败。 - MW003
incompatible-package— 解析笔记本的 PEP 723 依赖树(跳过所有标记为sys_platform != 'emscripten'的依赖),并在 PyPI 上检查是否有兼容 WASM 的 wheel,从而捕获通过传递依赖引入jaxlib等情况。
注意: MW001 会标记导入语句(from multiprocessing import Lock、import multiprocessing.synchronize),但不会标记后续的属性访问。仅有 import multiprocessing,之后在代码深处调用 multiprocessing.Lock(),可能会漏检。对于包含并发代码的笔记本,也请手动检查这一点。
注意: MW003 结果干净,并不意味着某个包在浏览器中就一定可以安全使用。如果笔记本将某个包标记为 sys_platform != 'emscripten',MW003 会完全跳过该包——这只能说明该包不会在 WASM 中安装,并不表示笔记本不会使用它。请检查笔记本是否也设置了 cache_cells = true,以及导出时是否使用了 --execute(见第 4 步)。如果是,则仍可通过缓存使用被排除的包。如果不是,任何导入或访问被排除包的代码路径都会在浏览器中失败,而 MW003 不会对此发出警告。
3. 检查检查器未覆盖的内容
以下检查仍需手动进行,由 Agent 驱动:
- PEP 723 元数据。 如果笔记本没有
# /// script块,或导入了未列在dependencies中的包,请发出 WARN。缺少此元数据时,笔记本在 WASM 中启动时不会自动安装包。固定版本和最低版本限制都可以——marimo 在 WASM 中运行时会去除版本约束。 - 仅在运行时出现的模式。 静态检查无法捕获以下情况:读取环境变量(
os.environ、os.getenv)、硬编码绝对文件路径,或使用Path.home()/Path.cwd()并假设存在真实文件系统,以及大型内存数据集(WASM 笔记本的内存上限为 2GB)。发现这些情况时请标出。 - 并发语义。 WASM 笔记本会为
threading.Thread、Event、local、ThreadPoolExecutor、wait、as_completed,以及进程形式的multiprocessing.Process、Queue、SimpleQueue、Pool、ProcessPoolExecutor运行协作式适配器。API 形式真实可用,但没有 OS 线程、没有共享内存,也没有真正的并行。所有任务都在单个 Pyodide 解释器中一次运行一个。如果笔记本依赖实际并发来提升速度,而不只是依赖 API 形式,请警告用户:它可以正确运行,但会按顺序执行。 - 已启用缓存执行。 检查笔记本的
pyproject.toml(或内联的# /// script块)中是否包含[tool.marimo.runtime] cache_cells = true。如果已设置,标记为sys_platform != 'emscripten'的不兼容包不会自动判定为 FAIL——请参阅第 4 步中的规避方案。
4. 生成报告
输出清晰、可执行的报告:
兼容性:PASS / FAIL / WARN
- PASS — 检查器和第 3 步都未发现问题。
- WARN — 未发现失败项,但第 3 步发现了值得进一步检查的情况(缺少 PEP 723 元数据、仅在运行时出现的模式,或只能顺序运行的并发代码)。
- FAIL — 检查器报告了诊断信息,或第 3 步发现了完全无法运行的内容。
检查发现 — 逐字粘贴第 2 步的诊断信息(文件、行、代码、消息)。
手动检查发现 — 列出第 3 步发现的所有问题,注明单元格或行号,并给出建议的修复方法。
建议 — 对于 FAIL/WARN 笔记本,提出具体的修复方案:
- 将不兼容的包替换为适用于 WASM 的替代方案
- 重写不兼容的代码模式
对于没有 WASM 构建版本的包,没有可直接替换的方案。有两种规避方案,它们解决的是不同问题——请检查笔记本实际需要哪一种:
-
预先计算所有可达结果并缓存。 使用
sys_platform != 'emscripten'标记从 WASM 中排除该包。这样,marimo 会在服务端运行一次实际计算,并将结果打包到导出文件中:# /// script # dependencies = [ # "marimo", # "torch; sys_platform != 'emscripten'", # ] # # [tool.marimo.runtime] # cache_cells = true # ///marimo export html-wasm notebook.py -o output_dir --execute这种方式可直接覆盖单个静态结果(例如绘图或一次性计算)。对于数量较少且可枚举的结果集合(例如从固定选项列表中选择的下拉菜单或滑块),则改用
@mo.persistent_cache(method="lazy")装饰计算过程。导出前添加一个单元格,为每个选项调用一次该计算。请参阅缓存预先计算的值。无论采用哪种方式,被排除的包都不会在浏览器中运行——笔记本只会读取其缓存结果。 -
使用能在浏览器中运行实际计算的兼容层。 对于无法提前枚举的输入空间,预先计算并不适用——例如滑块在连续范围内驱动实时推理。此时,笔记本需要使用真正适用于 WASM 的计算实现。
moutils.onnx.OnnxRuntime就是这种模式的一个例子:它会将 PyTorch 或 JAX 模型转换为 ONNX,并让返回的对象在浏览器中使用onnxruntime-web运行推理,而不是使用原始框架。
补充说明
- WASM 笔记本通过浏览器中的 Pyodide 运行
- 内存上限为 2GB
- 网络请求可以正常使用,但可能需要兼容 CORS 的端点
- Chrome 的 WASM 性能最佳;也支持 Firefox、Edge 和 Safari
micropip可以在运行时从 PyPI 安装任何纯 Python wheel- 如需查看 marimo 的 WASM lint 规则完整列表,请参阅 lint 规则参考
- 如需查看人工维护的 Pyodide 内置软件包快照,请参阅 pyodide-packages.md。这是一份便于阅读的快速参考,但
marimo check --select MW003会直接查询 PyPI,因此始终保持最新