

Simon Willison 在 6 月 13 号发了一篇博客,标题平淡无奇:《Publishing WASM wheels to PyPI for use with Pyodide》。但他做的事一点不平淡——他把一个叫 Luau 的 C++ 脚本语言编译成了 WASM wheel,传到 PyPI 上,然后在浏览器里用 import luau_wasm 跑了段斐波那契。
整个流程他花了一个下午。
重点不是"Python 能在浏览器跑了"——这件事 2018 年 Pyodide 项目刚启动时就能了。重点是他怎么做到的:没有找 Pyodide 团队帮忙,没有用任何私有索引,没有绕任何弯。就是写代码、配 CI、twine upload。和发一个 Linux wheel 没区别。
这才是 Pyodide 314.0 真正改变的东西。

要理解这个变化有多大,先得理解之前有多别扭。
Python 的二进制包分发有一套成熟机制:包维护者把 C/Rust 扩展编译成 .whl 文件,文件名里嵌一个平台 tag——manylinux_2_17_x86_64 表示给 64 位 Linux 用的,win_amd64 给 Windows。PyPI 收到上传后,pip install 的时候根据你的系统选对应的 wheel。这套机制从 PEP 427(2012 年)到现在跑了 14 年,撑起了整个 Python 生态。
但在 PEP 783 之前,WASM 不属于这个体系。
Pyodide 团队手工维护了 300 多个包的独立索引,放在 anaconda.org/pyodide。每个有 C 扩展的包——numpy、scipy、pydantic-core——都要他们手动交叉编译一遍。包维护者自己不用管浏览器这个 target,也管不了——PyPI 根本不接受 WASM 平台的 wheel。上传就报错。
这就是持续了 6 年的中央化瓶颈:包的原始作者最了解自己的代码,却不能自己发布浏览器版本。Pyodide 团队成了 gatekeeper——不是因为他们想当,是因为基建没跟上。
PEP 783 在 2026 年 4 月 6 号正式被 Python 治理委员会接受,然后事情开始加速。这份 PEP 只做了一件事:定义一个新平台 tag——pyemscripten_{YEAR}_{PATCH}_wasm32。看起来就是几个词加下划线,但它是 Python 生态第 14 个被正式承认的 wheel 平台。和 manylinux、win_amd64、macosx_11_0_arm64 同级。
4 月 21 日,PyPI 合并了 warehouse PR #19804,上传通道打开。6 月 7 日,cibuildwheel v4.0 发布,一行 YAML 构建 WASM wheel。6 月 9 日,Pyodide 314.0 发布,版本号从 0.29 直接跳到 314.0——对齐的是 CPython 3.14 的版本号。一个在 0.x 阶段待了 8 年的项目,突然把自己标到了 300+。
这不是突然发生的。这是 7 年基建的收束。但在 2026 年 6 月这两周,所有拼图同时到位了。
回到 Simon 的实验。他选了一个巧妙的 demo 对象:Luau。这是 Roblox 开发的一门脚本语言,从 Lua 5.1 fork 出来,加了渐进类型系统和性能优化。用 C++ 写的。Simon 想把它打包成一个可以在浏览器里 import 的 Python 模块。

构建流程比你想象的要简单。核心就三步:
第一步:编译 Luau C++ 源码到 WASM。 用 Emscripten 编译器,target 设成 wasm32-unknown-emscripten。这和编译到 ARM 或 x86 的逻辑一样,只是目标指令集不同。
第二步:打包成 wheel。 cibuildwheel 自动检测平台 tag,生成这样的文件名:
luau_wasm-0.1a0-cp314-cp314-pyemscripten_2026_0_wasm32.whl拆开看:cp314 = CPython 3.14,pyemscripten_2026_0 = Emscripten 2026 年第 0 版 ABI,wasm32 = 32 位 WASM 架构。271.6 KB。对,一个完整的脚本语言运行时,不到 300 KB。
第三步:twine upload,完。 剩下的步骤和发任何 Python 包一样。
然后 Simon 打开 Pyodide 的在线 REPL,敲了这几行:
import micropipawait micropip.install("luau-wasm")import luau_wasmprint(luau_wasm.execute('''local animals = {"fox", "owl", "frog", "rabbit"}table.sort(animals, function(a, b) return #a < #b end)for i, name in animals do print(i .. ". " .. name .. " (" .. #name .. ")") end'''))输出:按名字长度排好序的四只动物。6 毫秒跑完。在一个浏览器 tab 里。
他还部署了一个 GitHub Pages demo,打开就能玩:左边代码编辑器,右边输出面板,Hello World、斐波那契、运行时错误测试——几个预设按钮,simonw.github.io/luau-wasm。不用装任何东西。

这就是效果先行。不是 PPT 上的架构图,是一个能点能跑的东西。
L3 Expert Zone(可跳过):如果你维护的是 Rust 扩展

Pydantic 团队发了一篇详细的构建指南。核心配置:
- uses: pypa/cibuildwheel@v4env:CIBW_BUILD: "cp314-pyodide_wasm32"如果是 Rust 写的扩展(通过 PyO3/maturin),需要额外设一个环境变量:
export MATURIN_PYEMSCRIPTEN_PLATFORM_VERSION=2026_0然后 maturin 会自动选 wasm32-unknown-emscripten target。Rust 1.93.0 以上不需要 nightly——这是另一个"不是玩具"的信号。一个需要 nightly Rust 的平台是实验性的;一个 stable Rust 能直接编译的平台是生产级的。
Pydantic 的 pydantic_core(Rust 写的校验核心)v2.47.0 已经作为 pyemscripten wheel 在 PyPI 上了。你可以自己去验证:打开 pypi.org/project/pydantic_core/#files,翻到最下面,能看到 cp314-cp314-pyemscripten_2026_0_wasm32.whl。和它的 118 个兄弟 wheel 排在一起——Linux 的、macOS 的、Windows 的,现在加了一个浏览器的。

Simon 用 BigQuery 扫了 PyPI 的公开数据集。截止 6 月中旬,已经发布 pyemscripten_202*_wasm32 wheel 的包有这些:
pydantic_core、onnx、imgui-bundle、typst、uuid7-rs、yaml-rs、toml-rs、cmm-16bit、cadquery-ocp、arro3-* 系列……

不是几百个,但种类很有意思。有数据校验核心(pydantic_core),有 ONNX 运行时,有 GUI 框架(imgui-bundle),有排版引擎(typst),有各种 Rust 写的序列化库。这些不是"尝鲜"型的玩具包——每一个都有人在生产环境中依赖它们。
包维护者的决策逻辑其实很简单:成本 vs 覆盖。加一个 WASM target 的成本是多少?一行 CIBW_BUILD。CI 多跑 2-3 分钟。多了几百 KB 的 wheel 文件。覆盖的是什么?一个全新的平台——所有能用浏览器的设备。
这个成本/收益比,随着 cibuildwheel v4.0 的发布,已经偏到了让大多数维护者选择"加"的那一边。
但不是所有包都适合。
Pyodide 不是服务器 Python 的替代品。把它当替代品用,你会失望。把它当浏览器里的 Python用,它很强。

它擅长三件事:
它做不了三件事:
threading 或 multiprocessing——WASM wheel 不是你的战场。requests.get("https://任意网址") 在浏览器里撞上 CORS 墙。Pyodide 提供 pyodide.http 包装了浏览器的 fetch() API,但它不是 requests 的直接替换。服务器端得配 CORS header 才行。Node.js 下有实验性 socket 支持(pyodide.useNodeSockFS()),但浏览器端无解。一句话:把它想象成露营炉,别想象成中央厨房。野外能炒一桌菜,但不是把家里六眼灶搬过去。
2018 年,Pyodide 项目刚启动时的叙事是:"你看,CPython 能在浏览器里跑!"这个叙事在 2026 年 6 月已经过时了。现在的叙事是:"pip install 的第四个平台,叫浏览器。"
判断一个基础设施变化是不是"范式级别",我有三个简单信号:
pypa/packaging,就是 Python 语言基础设施的一部分。三个信号同时亮绿灯。这不是巧合——cibuildwheel 在 6 月 7 日发布、Pyodide 314.0 在 6 月 9 日发布、Simon 在 6 月 13 日发博客,不是因为他们约好了。是因为 PEP 783 在 4 月 6 日通过后,每个团队都在等对方先动,然后一瞬间全动了。
2009 年,Node.js 让 JavaScript 从浏览器扩展到了服务器。当时也有人说"JS 在服务器端跑?玩具吧。"15 年后,没有人质疑 JS 是服务器端一等语言。
Pyodide 314.0 是同一个硬币的另一面。Python 从服务器扩展到浏览器。同样的怀疑——"Python 在浏览器里跑?玩具吧。"同样的答案——不是玩具,是 infrastructure。

在 .github/workflows 里找到 cibuildwheel 的 job,加一行:
CIBW_BUILD: "cp314-pyodide_wasm32"推上去,看 CI 能不能绿。如果绿了——你的包就有了第四个平台。
import micropipawait micropip.install("你常用的包名")看它能不能装上。能装上 = 包的维护者已经替你做了第 1 步。
下次有人告诉你"X 语言能进 Y 平台了",不要问"能跑吗"(答案永远是能)。问这三个问题:协议标准化了吗?工具链降到零门槛了吗?有不可能回头的关键包入局了吗?三个全是 yes,才是范式转移。缺一个,只是 demo。
生成时间:2026-06-14 · 由 Hook Master + Title Judge 提供
pip install 的第四个平台,叫浏览器
作者:一个把 Python 从服务器扩展到浏览器的神器 -- Pyodide
pyemscripten 的 wheel tag——Python 包的浏览器目标平台,和 Linux wheel 同级。import 直接跑。Python 分发的边界不再是 CPU 架构——Pyodide 314.0 将 WASM 变成了 PyPI 上的一等 wheel 目标平台。这不是"Python 能在浏览器跑"的老故事,而是 pip install 机制本身的一次静默升级:PEP 783 标准化平台 tag,cibuildwheel v4.0 把门槛降到一行 YAML,Pydantic 等关键包已入局。本文从 Simon Willison 的可复现实操切入,给出一个三信号判断框架供读者迁移复用。
家人们,Python 生态发生了一件大事但没人咋呼 📢
pip install 现在有第四个平台了——叫浏览器。不是以前那种"Python 转 JS"的老方案,是正儿八经的 CPython 3.14 编译成 WebAssembly,wheel 直接传 PyPI,浏览器里 import micropip; await micropip.install("包名") 就能用。
Simon Willison(那个 Django 创始人)花一个下午就把他写的 C++ 项目打包成 WASM wheel 传上去了。271 KB。6 毫秒跑完斐波那契。
Pydantic 已经在发了。这意味着什么?以后你在浏览器里跑 Python 不会再有"对不起,这个库不支持"——只要维护者加一行 CI 配置。
我写了篇 3000 字把这事掰开讲清楚了 👆 从 PEP 783 到 cibuildwheel 到 Pyodide 314.0,到谁已经在船上、谁不该上船。诚实画了边界——三件事能做,三件事做不了。
标签:#Python #Pyodide #WebAssembly #pip #开源 #技术趋势 #浏览器编程
Python 生态一个被低估的大变化:Pyodide 314.0。
不是"Python 能在浏览器跑了"(那个 2018 年就能了),是 PyPI 现在接受 WASM 平台的 wheel 了。和 Linux/macOS/Windows wheel 同级——同一个 twine upload。
Simon Willison 前天写博客验证了全流程:C++ → Emscripten → WASM wheel → PyPI → 浏览器 import,一个下午跑通。Pydantic 已经在生产级发 emscripten wheel 了。
这不是玩具信号。cibuildwheel v4.0 把门槛压到了一行 YAML。
我写了个判断框架:协议标准化 × 工具零门槛 × 关键包入局 = 范式转移。缺一个就是 demo。
articles/pending/visuals/2026-06-14-pyodide-3140-wasm/fig1-timeline.md(Pyodide 7 年基建收束,5 个关键拐点)articles/pending/visuals/2026-06-14-pyodide-3140-wasm/fig2-flowchart.md(WASM wheel 完整构建管线)articles/pending/visuals/2026-06-14-pyodide-3140-wasm/fig3-quadrant.md(浏览器 Python 方案竞争定位)articles/pending/visuals/2026-06-14-pyodide-3140-wasm/配图说明.md(5 张手动截图优先级清单)