ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Jupyter Notebook 贡献指南:从开发环境搭建到端到端测试的完整工程实践

2026/9/15 1:13:35 拓冰建站 浏览量
Jupyter Notebook 贡献指南:从开发环境搭建到端到端测试的完整工程实践 Jupyter Notebook 贡献指南从开发环境搭建到端到端测试的完整工程实践【免费下载链接】notebookJupyter Interactive Notebook项目地址: https://gitcode.com/GitHub_Trending/no/notebookJupyter Notebook 是一款基于 Web 的交互式计算笔记本环境本项目采用「Python 服务端 TypeScript 前端」的混合架构并以 npm workspaces monorepo 组织全部前端代码。本文以仓库根目录的 CONTRIBUTING.md 为骨架完整讲解如何搭建可编辑的开发环境、构建与热更新前端资源、用 yalc 接入未发布的本地依赖、运行 pytest 与 Playwright 双层测试体系、落实 pre-commit 代码规范以及如何在不搭建本地环境的情况下从浏览器直接参与贡献。读完本文你将具备向该仓库提交合格代码并独立完成本地验证的完整能力。贡献前须知行为准则与前置工具参与 Jupyter Notebook 开发首先需要遵守 Project Jupyter 社区的行为准则以营造友好、包容的协作环境。在动手写代码之前还需要确认本机具备以下工具Python项目在 pyproject.toml 中声明requires-python 3.10当前支持 Python 3.10 至 3.14。Node.js前端扩展包由 TypeScript 编译必须安装 NodeJS。仓库根目录的 package.json 通过packageManager: yarn3.5.0固定了 Yarn 版本。jlpmJupyter 生态对 Yarn 的固定版本别名随 Jupyter Builder 安装。你也可以用yarn或npm替代下文中的jlpm命令。mamba推荐官方建议使用mamba加速 conda 环境创建底层仍由 conda-forge 提供 Python 与 Node.js。版本边界说明以上版本约束以当前仓库实际声明为准。若你使用更新的 Python 或 Node.js 版本请以本机实际构建结果为准。搭建可编辑的开发环境开发环境搭建的目标是把 Python 包以 editable 方式安装到当前环境同时把前端jupyter-notebook扩展与 schema 链接到 Jupyter 能发现的路径从而让jupyter notebook直接加载你的本地改动。第一步创建环境并安装 Python 包# 创建新的 conda 环境内含 Python 与 Node.js mamba create -n notebook -c conda-forge python nodejs -y # 激活环境 mamba activate notebook # 以开发模式安装 Python 包同时带上 dev、docs、test 三组可选依赖 pip install -e .[dev,docs,test].[dev,docs,test]对应 pyproject.toml 中声明的三组可选依赖test组包含pytest、nbval、ipykernel、jupyter_server[test]等测试栈docs组包含 Sphinx、myst-parser、pydata-sphinx-theme 等文档栈dev组则包含pre-commit与hatch。换言之一条命令就把测试、文档、代码规范所需的依赖全部装齐。第二步安装前端依赖并构建# 安装 JavaScript 依赖并构建所有包 jlpm jlpm buildjlpm等价于仓库根目录 package.json 中由 Yarn workspace 驱动的依赖安装jlpm build则是一条串联脚本jlpm run build:utils # 编译 buildutils发布、版本工具等 - jlpm build:lib # 编译 metapackage汇总所有 jupyter-notebook 子包 - jlpm workspace jupyter-notebook/lab-extension run build # 构建 lab 扩展 - jlpm build:app # 构建应用app 包rspack 打包前端静态资源其中build:app最终进入 app/package.json由rspack负责打包产物输出到notebook/static与notebook/labextension目录供 Python 包随附分发。第三步链接扩展与 schema# 链接 notebook 扩展和 jupyter-notebook schemas jlpm developjlpm develop的执行链路定义在根 package.json实际由两部分组成jupyter-builder develop负责链接 labextension随后执行node ./buildutils/lib/develop.js --overwrite。查看 buildutils/src/develop.ts 可以看到其底层逻辑它会通过python -c import sys; print(sys.prefix)探测当前 Python 环境前缀然后把仓库内的notebook/schemas/jupyter-notebook目录符号链接到{sys.prefix}/share/jupyter/lab/schemas/jupyter-notebook--overwrite标志会先删除旧的链接目标再重建保证链接指向你当前的开发副本。第四步启用服务端扩展并验证jupyter server extension enable notebook该命令写入的正是 jupyter-config/jupyter_server_config.d/notebook.json 中的ServerApp.jpserver_extensions.notebook true配置。验证是否安装成功$ jupyter server extension list Config dir: /home/username/.jupyter Config dir: /home/username/miniforge3/envs/notebook/etc/jupyter jupyterlab enabled - Validating jupyterlab... jupyterlab 3.0.0 OK notebook enabled - Validating notebook... notebook 7.0.0a0 OK Config dir: /usr/local/etc/jupyter注意上述输出中的/home/username等路径是示例实际路径取决于你的 conda 环境位置与用户名。看到notebook enabled且Validating notebook ... OK即表示服务端扩展已正确加载。最后启动应用jupyter notebook此时浏览器打开的就是由你本地构建的前端资源驱动的 Notebook 7 界面任何对packages/*中 TypeScript 源码的修改都需要重新构建才能生效见下文 watch 模式。快速迭代watch 模式monorepo 下逐次手动构建很繁琐仓库提供了监听脚本jlpm watch从根 package.json 可以看到watch并行执行watch:lib与watch:app前者监听jupyter-notebook/metapackage后者在 app/package.json 中通过rspack --watch --config rspack.config.js监听前端源码变化并自动增量重编译。改动 TypeScript 后浏览器刷新即可看到效果。深入 monorepo包结构与构建流水线Notebook 7 的前端是典型的 npm workspaces monorepo根 package.json 声明了三个 workspace 目录Workspace内容关键产物app应用入口与打包配置前端静态资源、多个 rspack 配置buildutils构建/发布辅助脚本版本管理、依赖升级、schema 链接等工具packages/*各功能子包application、notebook-extension、tree、console-extension 等packages下的子包按职责拆分例如packages/application 提供应用外壳与主面板packages/tree 实现文件树管理界面packages/notebook-extension 承载 Notebook 核心交互packages/application-extension 负责菜单、快捷键、主题、zen 模式等应用级功能。各子包统一使用jupyter-notebook/*命名空间并在 app/package.json 的jupyterlab.plugins字段中按路由/、/tree、/notebooks、/consoles、/edit装配不同的插件集合同时通过singletonPackages约束 React、yjs、Lumino 等库只能存在单一实例。这种「按路由装配插件」的机制正是 Notebook 7 能以 JupyterLab 组件为基础、同时保持经典 Notebook 精简界面的关键。需要一次性构建全部包时在仓库根目录执行jlpm build使用 yalc 调试未发布的本地依赖默认开发安装会按照各package.json中的版本声明从 npm 拉取jupyterlab等依赖。但当你需要与尚未发布的本地 JavaScript 包联调时例如你同时在修改jupyterlab/ui-components和 Notebookyalc 可以充当本地包仓库把依赖指向本地副本。完整工作流如下全局安装 yalcnpm install -g yalc在依赖包根目录发布到本地仓库例如开发jupyterlab/ui-components时需在path_to_jupyterlab/packages/ui-components目录执行yalc publish在 Notebook 根目录把该包加入本地仓库yalc add jupyterlab/ui-components这会在根package.json中新增一条dependencies记录。关键一步Notebook 是 monorepo我们希望该依赖作为所有子包的共享解析resolution而非单个依赖出现。最直接的做法是手动把根package.json中新增的条目从dependencies挪到resolutions字段该仓库本身就用resolutions固定了react、yjs等关键库版本见根 package.json。用本地依赖重新构建jlpm install jlpm build之后对依赖包的修改需要在依赖包根目录执行jlpm build yalc push再由 Notebook 侧yarn install拉取更新。重要警告必须保证 Notebook 与本地依赖包所依赖的公共库版本一致否则 webpack/rspack 构建会因重复实例或 API 不匹配而报错。以上述为例jupyterlab/ui-components与 Notebook 都依赖jupyterlab/coreutils强烈建议两边锁定同一版本。这一约束也印证了根 package.json 使用resolutions统一版本的必要性。运行测试pytest 单元测试与 Playwright 端到端测试该仓库采用双层测试策略Python 服务端的 pytest 测试与前端浏览器级的 Playwright 端到端测试。Python 单元测试在仓库根目录运行jlpm run build:test jlpm run testbuild:test会先编译测试所需的 JavaScript 构建产物见根 package.jsontest则委托给各 workspace 的npm test。Python 侧测试位于 tests/以 tests/test_app.py 为例可以看到它通过 pytest fixture 创建临时 notebook验证JupyterNotebookApp.flags与serverapp_flags相互隔离、各路由/、/notebooks能正确返回渲染了 Jupyter Notebook 模板的 HTML。更高效的 Python 测试方式还可以借助 Hatch 环境hatch run test:test对应 pyproject.toml 中的python -m pytest -vv并继承 pyproject.toml 中[tool.pytest.ini_options]设置的 doctest、timeout300、strict-markers 等全局选项。端到端测试ui-tests覆盖更上层用户交互的端到端测试位于ui-tests目录运行步骤为cd ui-tests # 安装 jlpm 所需依赖 jlpm # 安装 playwright 浏览器内核 jlpm playwright install # 在终端 A启动 Jupyter 服务器 jlpm start # 在终端 B运行测试 jlpm test各命令的底层实现见 ui-tests/package.jsonjlpm start实际执行jupyter notebook --config test/jupyter_server_config.py其中 ui-tests/test/jupyter_server_config.py 通过configure_jupyter_server开启expose_app_in_browser允许测试直接访问应用页面jlpm test则调用 Playwright 测试运行器。ui-tests/playwright.config.ts 展示了测试基建的细节基于jupyterlab/galata的官方 Playwright 配置扩展galata 是 Jupyter 自研的 UI 测试框架内置webServer自动以jlpm start拉起服务器端口 8888超时 120 秒允许复用已存在的服务器失败时保留 tracetrace: on-first-retry与视频video: retain-on-failure便于排查CI 环境下输出 blob/json 报告。jlpm test支持追加 Playwright 参数例如带界面headed运行jlpm test --headed其余命令行选项可查阅 Playwright 官方命令行参考。测试用例本身分布在 ui-tests/test 下如menus.spec.ts、notebook.spec.ts、layout.spec.ts、mobile.spec.ts等ui-tests/test/fixtures.ts 定制了waitForApplication等待#main-panel出现ui-tests/test/utils.ts 则提供waitForNotebook、waitForKernelReady、runAndAdvanceShiftEnter 执行单元格并前进等可复用的等待与交互工具包括针对 Firefox headless 渲染问题的特殊处理。更新参考快照很多 PR 会改动用户界面导致视觉回归测试失败。如果需要更新参考快照可在你的 PR 下发布如下 GitHub 评论bot please update playwright snapshots这会触发一个 GitHub Action自动运行 UI 测试并在参考快照有变化时向你的分支推送新的提交。仓库中ui-tests/test/*.spec.ts-snapshots/目录下按浏览器chromium/firefox区分的 PNG 文件就是这套视觉回归体系的参考基线。代码风格prettier、black 与 pre-commit项目对代码风格采取「自动化接管」策略非 Python 源码统一用 prettier 格式化Python 源码统一用 black 格式化并通过 pre-commit git 钩子在提交时自动处理暂存文件。这样做的收益是PR 评审时不再争论代码风格评审速度显著提升——只要代码有效钩子会负责它应有的样子。pre-commit及其关联钩子会在执行pip install -e .[dev,test]时自动安装dev组依赖中声明了pre-commit且 pyproject.toml 中install-pre-commit-hook true。手动安装方式pip install pre-commit pre-commit install随时可手动触发pre-commit run它会对代码做自动格式化并报告无法自动修复的错误。仓库实际的钩子配置见 .pre-commit-config.yaml从中可以看出完整的质量关卡通用检查pre-commit-hooks提供的 check-json、check-yaml、check-toml、check-merge-conflict、trailing-whitespace、end-of-file-fixer 等拼写检查codespell并排除yarn.lock、pixi.lock、binder 示例等文件Python 质量ruff-check 与 ruff-format对应 pyproject.toml 中扩展的 flake8-bugbear、isort、pylint 等规则集以及 mypy仅对notebook目录、manual 阶段执行文档检查rst-backticks、rst-directive-colons 等 reStructuredText 钩子仓库卫生sp-repo-review 对仓库元数据做规范性评审本地钩子prettier通过npm run prettier:files格式化 JSON/TS/TSX/JS/CSS/Markdownintegrity通过npm run integrity --force底层是 buildutils/src/ensure-repo.ts在 pre-push 阶段校验 workspace 依赖一致性。使用要点部分钩子默认只在 CI 运行可用--hook-stage manual手动触发例如pre-commit run --all-files --hook-stage manual mypy如果设置钩子前已经提交过文件可用pre-commit run --all-files一次性修复全部历史文件修复提交需自己完成也可以用 prettier npm 脚本格式化整个代码库npm run prettier、yarn prettier或jlpm prettier对应根 package.json 的prettier --write以及配套的prettier:checkJavaScript/TypeScript 的静态检查由 ESLint 承担配置见 eslint.config.mjs它聚合了typescript-eslint、React、Jest、Prettier 推荐规则与jupyter/eslint-plugin的 Jupyter 专用规则可通过根 package.json 的jlpm eslint/jlpm eslint:check执行建议在编辑器安装 prettier 扩展并配置保存即格式化或快捷键格式化同时在编辑器集成 black 以获得 Python 侧一致的体验。构建文档文档基于 Sphinx 构建源码位于 docs/source。在完成上述开发环境搭建后# 构建文档 hatch run docs:build再开一个终端窗口启动本地服务hatch run docs:serve然后浏览器访问http://localhost:8000即可预览文档。这两个脚本定义在 pyproject.tomlbuild实际执行make -C docs html SPHINXOPTS-W-W表示将警告视为错误保证文档构建严格性serve则在docs/build/html目录启动一个 Python HTTP 服务器。不搭环境直接从浏览器贡献如果不想在本地搭建环境也有三条纯浏览器的贡献路径GitHub CodeSpaces仓库配置了基于 pixi 包管理器的开发环境pixi 配置见 pyproject.toml锁定了 Node.js 22、conda-forge 频道与 dev/docs/test 环境组。CodeSpace 启动后在终端运行pixi shell激活开发环境使用与本地相同的构建与测试命令例如jlpm build运行pixi run start启动应用浏览器会弹出按钮打开 Jupyter Notebook若弹窗未出现可到 Forwarded ports 面板找到应用 URL该任务在 pyproject.toml 中定义启动参数为jupyter notebook --no-browser --ServerApp.token --ServerApp.allow_remote_accessTrue。GitHub 内置编辑器适合提交小型修复直接在线编辑文件并提交。github.dev 高级编辑器在仓库页面按.英文句点键即可进入功能比内置编辑器更完整。小结一份贡献清单对照本文一次完整的贡献流程可以归纳为用 mamba 创建环境pip install -e .[dev,docs,test]安装全部依赖jlpm jlpm build jlpm develop完成前端构建与 schema 链接jupyter server extension enable notebook并验证jupyter server extension list输出 OK编写代码时依赖 pre-commit 钩子prettier/black/ruff/mypy自动保持风格一致必要时pre-commit run --all-files批量修复本地验证jlpm run build:test jlpm run test跑单元测试进入ui-tests目录用 Playwright 跑端到端测试涉及 UI 变化时按需更新参考快照涉及文档时用hatch run docs:build验证可构建。这条从环境、构建、测试到代码规范的完整链路既是新手快速上手的路线图也是评审者在合并代码前验证质量的检查单。【免费下载链接】notebookJupyter Interactive Notebook项目地址: https://gitcode.com/GitHub_Trending/no/notebook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考