ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

4 步跑通 PyScript 配置与部署:从 make setup 到静态托管的实战清单

4 步跑通 PyScript 配置与部署:从 make setup 到静态托管的实战清单

4 步跑通 PyScript 配置与部署:从 make setup 到静态托管的实战清单

【免费下载链接】pyscriptAn open source platform for Python in the browser. https://pyscript.net Docs: https://docs.pyscript.net/ Try it: https://pyscript.com/ Community: https://discord.gg/HxvBtukrg2项目地址: https://gitcode.com/gh_mirrors/py/pyscript

这一篇是维护 PyScript 期间积累的配置部署笔记:覆盖本地构建、<py-config>三种写法的冲突规则、用事件链定位加载卡点、Worker 配置三要素、静态托管上线时的响应头要求,以及上线前该查什么。假设你会 git 和 npm,不需要先读懂 polyscript 的启动逻辑。

1 环境准备:先构建出 core/dist 运行时

这一节帮你解决「本地没有可测试的 PyScript 构建产物」的问题。

  • node >= 20、npm >= 6、Python >= 3.8;版本不达标make setup会直接报红拒绝安装
  • 仓库根目录执行make setup:检查版本后执行cd core && npm ci,并在已激活的 venv/conda 环境里装 requirements.txt(black、pre-commit 等工具链)
  • make build在 core 下跑 playwright chromium 安装加完整构建,产物落在core/dist/

PyScript 页面只依赖两份产物:core.css和core.js,<head>里引用完,正文用<script type="py">(Pyodide)或<script type="mpy">(MicroPython)就能跑 Python。

这里有个坑:构建会重新生成src/stdlib/pyscript.js(把src/stdlib/pyscript/里全部 Python 内嵌成一个 JS 对象)和插件入口文件,带// ⚠️ This file is an artifact: DO NOT MODIFY头的文件改了一定被覆盖,机制见 core/README.md。日常调试别跑完整 build,用npm run dev:chokidar 监听core/src/,只重建 stdlib、plugins 和 core 且不压缩,改完几秒内生效;npm run server则起一个带正确响应头的静态服务器,测试页在http://localhost:8080/tests/。

2 配置体系:一个页面只允许一份全局配置

这一节帮你解决「配了 packages 却没生效」这类问题——多半是配置本身被判定为冲突,根本没被解析。

解析入口在 core/src/config.js,规则可以背下来:

  1. 全局配置二选一:<py-config>标签,或给<script type="py" config="...">加config属性;两者同时出现,抛CONFLICTING_CODE(Ambiguous py-config VS config attribute)
  2. 标签只能有一个,多个同样抛错(Too many py-config)
  3. 多个脚本带config属性时必须指向同一个文件,否则报 Unable to use different configs on main

配置内容支持内联或文件 URL,格式按扩展名判断(.json走 JSON、.toml走 TOML),也可用type属性强制。常见键:

  • packages = ["numpy"]:装哪些包,远程自定义包需另开experimental_remote_packages = true
  • files:路径映射,把本地文件拷进虚拟文件系统(VFS),如"./src" -> "./runtime",见 config.json 示例
  • plugins = ["!error"]:!前缀关闭内置插件,错误页示例 就是用它放行 stderr
  • experimental_ffi_timeout = 100:调整 Python 调 JS 的超时,单位毫秒

写自己的 config.toml 时建议照抄仓库测试目录里的最小写法,先跑通再改,别一上来堆键。

3 调试方法:事件链定位加载卡点

这一节帮你解决「页面白屏,不知道卡在哪一步」。

PyScript 把生命周期暴露成 DOM 事件:py:progress(detail 是Loading xxx/Loaded xxx,加载阶段可配合console.time计时)、每个脚本的py:done、以及 all-done.js 在所有脚本就绪后派发的py:all-done。测试页里的监听代码可以直接抄:

<script> addEventListener("py:progress", ({ detail }) => console.log(detail)); addEventListener("py:all-done", () => console.log("all scripts ready")); </script>

再开 DevTools 的 Console 和 Network,Python 报错、fetch 失败基本无所遁形。想关掉页面上的红色错误卡片(比如演示环境不想暴露堆栈),就用第 2 节说的plugins = ["!error"],而不是删控制台输出。

4 Worker 配置三要素:type、config、files

这一节帮你解决「主线程被算爆、页面掉帧」的问题。先说结论:主线程单次阻塞超过 200ms 掉帧,CPU 密集活必须挪进 Web Worker。

写法上给<script type="py" worker>加worker属性,或在主线程脚本里用PyWorker显式建一个(注意:PyWorker 只能在主线程创建,worker 内部会抛NotSupported):

from pyscript import PyWorker worker = PyWorker("./worker.py", type="pyodide", config="./config.json") await worker.ready

这就是三要素:type定解释器(pyodide全量 CPython、micropython轻量版),config复用第 2 节那套体系给 worker 单独配packages,files把 worker 要用的.py映射进它的 VFS,参考 worker 测试。

这里有个坑:worker 里代理window/document依赖 SharedArrayBuffer,它要求响应带 COOP/COEP 头。头缺失时 worker 内pyscript.window是NotSupported占位;如果本就不需要碰 DOM,配sync_main_only = true可消掉那条警告,no_sab 示例 演示了这条路径。

5 生产部署:静态托管 + 两个响应头

这一节帮你解决「本地能跑,上线后 worker 全挂」的问题。

PyScript 应用是纯静态站点,Nginx、Netlify、Vercel 都行,托管core/dist加你的页面即可。但有两个响应头必须在服务器上配好,本地npm run server(static-handler --coi)和make serve(mini-coi)替你做了这件事,仓库里 mini-coi.js 能看到具体值:

  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp

缺了这俩,第 4 节的 worker DOM 代理就不可用;用了 COEP 后,页面里所有跨域资源都得带 CORP 标记,第三方资源没配会整页加载失败,这是最常见的上线事故。

上线前检查清单:

  • make build全绿:它会先跑 pre-commit 和 oxlint,收尾自动执行 playwright 集成测试(JS 测试加 Python 测试在 mpy/py 双解释器、主线程/worker 四种组合下各跑一遍)
  • dist/core.js、dist/core.css的相对路径引用无误
  • 页面监听py:all-done做加载完成的最终确认,别只信py:ready
  • 想压体积用npm run size看 dist 各文件的 brotli 大小,再精简packages

6 踩坑回查表与扩展方向

这一节帮你解决「上线一周后偶发报错」的反查效率问题。

  • 控制台出现CONFLICTING_CODE/BAD_CONFIG:回第 2 节对照标签与config属性是否混用
  • 包装不上:先核对packages拼写和可达性;装远程自定义包确认experimental_remote_packages已开,远程包示例 给了完整形态
  • worker 里pyscript.window抛NotSupported:SharedArrayBuffer 不可用,检查响应头,或改走sync通道、配sync_main_only = true
  • Python 调 JS 卡死:给experimental_ffi_timeout设一个明确的毫秒上限,让它可预期地抛错而不是无限挂起

扩展方向是插件:内置插件在 core/src/plugins/,新建插件只要加一个入口文件,构建器会按名字在 dist 里产出独立 chunk,不增大core.js体积;第三方插件不用进仓库,页面里import @pyscript/core后动态加载即可,py-editor、py-terminal、py-game都是现成参照。

收尾给你下一步:把第 2 节的 TOML 写进自己的项目,make build全绿后用第 3 节的事件监听确认一次完整加载链路,再对照第 5 节清单把响应头加到服务器上。

【免费下载链接】pyscriptAn open source platform for Python in the browser. https://pyscript.net Docs: https://docs.pyscript.net/ Try it: https://pyscript.com/ Community: https://discord.gg/HxvBtukrg2项目地址: https://gitcode.com/gh_mirrors/py/pyscript

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表