为 Jupyter Notebook 做贡献#

感谢您为 Jupyter Notebook 做出贡献!

请务必遵守 Project Jupyter 的行为准则,以营造一个友好和热情的协作环境。

搭建开发环境#

注意:您需要 NodeJS 来构建扩展包。

jlpm 命令是 JupyterLab 锁定的 yarn 版本,它随 JupyterLab 一起安装。在下文中,您可以使用 yarnnpm 来代替 jlpm

注意:我们推荐使用 mamba 来加速环境的创建。

# create a new environment
mamba create -n notebook -c conda-forge python nodejs -y

# activate the environment
mamba activate notebook

# Install package in development mode
pip install -e ".[dev,docs,test]"

# Install dependencies and build packages
jlpm
jlpm build

# Link the notebook extension and @jupyter-notebook schemas
jlpm develop

# Enable the server extension
jupyter server extension enable notebook

notebook 遵循 monorepo 结构。要一次性构建所有包:

jlpm build

还有一个 watch 脚本,用于监视文件变更并自动重新构建应用程序:

jlpm watch

为了确保 notebook 服务器扩展已安装:

$ 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

然后通过以下命令启动 Jupyter Notebook:

jupyter notebook

Notebook 依赖项的本地变更#

上述开发安装过程会根据 package.json 文件中的版本,从 npmjs 获取 JavaScript 依赖项。但是,有时我们需要在 Notebook 中测试尚未发布的依赖项(例如 @jupyterlab 包)的变更。

yalc 可以帮助您在构建 Notebook 时使用本地的 JavaScript 包,它充当一个本地包仓库。

  • 在您的环境中全局安装 yalc:npm install -g yalc

  • 发布您的依赖包
    在包的根目录下运行 yalc publish
    例如,如果您正在开发 @jupyterlab/ui-components,此命令必须在 path_to_jupyterlab/packages/ui-components 目录下执行。

  • 在 Notebook 中依赖此本地仓库

    • 在 Notebook 根目录下:
      yalc add your_package:这将在主 package.json 文件中创建一个 dependencies 条目。
      以前面的例子来说,命令应为 yalc add @jupyterlab/ui-components

    • Notebook 是一个 monorepo,所以我们希望这个依赖被‘链接’为一个 resolution(用于所有子包),而不是一个 dependency。
      最简单的方法是手动将 package.json 中的新条目从 dependencies 移动到 resolutions

    • 使用本地依赖构建 Notebook
      jlpm install && jlpm build

之后,依赖项中的变更必须通过 jlpm build && yalc push(在包的根目录下)来构建和推送,然后在 Notebook 中使用 yarn install 来获取。

警告:您需要确保 Notebook 的依赖项和本地包的依赖项正确匹配,否则在构建过程中 webpack 会报错。
在前面的例子中,@jupyterlab/ui-components 和 Notebook 都依赖于 @jupyterlab/coreutils。我们强烈建议您依赖于相同的版本。

运行测试#

要运行测试:

jlpm run build:test
jlpm run test

还有端到端测试,用于覆盖更高级别的用户交互,位于 ui-tests 文件夹中。要运行这些测试:

cd ui-tests
#install required packages for jlpm
jlpm

#install playwright
jlpm playwright install

# start a new Jupyter server in a terminal
jlpm start

# in a new terminal, run the tests
jlpm test

test 脚本会调用 Playwright 测试运行器。您可以通过在命令后附加参数来向 playwright 传递额外的参数。例如,要在有头模式下运行测试,使用 jlpm test --headed

请查阅 Playwright 命令行参考,了解更多可用的命令行选项。

在有头模式下运行端到端测试会触发类似下面的界面:

playwight-headed-demo

任务缓存#

该仓库配置为对某些开发脚本使用 Lerna 缓存系统(通过 nx)。

这有助于在多次运行 jlpm run build 时加快重建速度,避免重新构建磁盘上未发生变化的包。

您可以使用以下命令生成一个图表,以便更好地了解所有包之间的依赖关系:

npx nx graph

运行该命令默认会打开一个浏览器标签页,其中包含一个如下图所示的图表:

a screenshot showing the nx task graph

要了解更多关于 Lerna 缓存的信息:

  • https://lerna.node.org.cn/docs/features/cache-tasks

  • https://nx.dev/features/cache-task-results

更新参考快照#

通常,一个 PR(拉取请求)可能会对用户界面进行更改,这可能导致视觉回归测试失败。

如果您在处理 PR 时想要更新参考快照,可以在 GitHub 评论中发布以下句子:

bot please update playwright snapshots

这将触发一个 GitHub Action,它会自动运行 UI 测试,并在参考快照发生变化时将新的提交推送到您的分支。

代码风格#

所有非 Python 源代码都使用 prettier 进行格式化,而 Python 源代码则使用 black 进行格式化。当代码被修改并提交时,所有暂存的文件都会通过 pre-commit git 钩子(在 pre-commit 的帮助下)自动格式化。使用像 prettierblack 这样的代码格式化工具的好处是,它消除了在代码审查时关于代码风格的讨论,从而加快了审查过程。

只要您的代码有效,pre-commit 钩子就应该能处理好它的外观。pre-commit 及其相关钩子会在您运行 pip install -e ".[dev,test]" 时自动安装。

要手动安装 pre-commit,请运行以下命令:

pip install pre-commit
pre-commit install

您可以随时通过以下命令手动调用 pre-commit 钩子:

pre-commit run

这会对您的代码运行任何自动格式化,并告知您任何无法自动修复的错误。您也可以将 black 集成到您的文本编辑器中,以自动格式化代码。

如果您在设置 pre-commit install 钩子之前就已经提交了文件,可以使用 pre-commit run --all-files 来修复所有文件。之后您需要自己创建一个修复提交。

您也可以使用 prettier npm 脚本(例如 npm run prettieryarn prettierjlpm prettier)来格式化整个代码库。我们建议为您的代码编辑器安装一个 prettier 扩展,并将其配置为通过键盘快捷键或在保存时自动格式化您的代码。

默认情况下,某些钩子只在 CI(持续集成)上运行,但您可以通过使用 --hook-stage manual 参数来调用它们。

文档#

首先,请确保您已按照上述说明设置了开发环境。

然后运行以下命令来构建文档:

hatch run docs:build

在另一个终端窗口中,运行以下命令来提供文档服务:

hatch run docs:serve

现在打开一个网页浏览器并访问 https://:8000 即可查看文档。

从浏览器贡献#

另外,您也可以直接从网页浏览器为 Jupyter Notebook 做贡献,而无需设置本地环境:

  • GitHub CodeSpaces 已直接集成到 GitHub 中。此仓库使用 pixi 包管理器来设置开发环境。在 Codespace 启动后,要进行贡献:

    • 在终端中运行 pixi shell 以激活开发环境。

    • 使用上述命令来构建扩展和运行测试,例如:jlpm build

    • 要启动应用程序:pixi run start。此时应出现一个弹窗,其中有一个按钮可以在新的浏览器标签页中打开 Jupyter Notebook。如果弹窗没有出现,您可以导航到“Forwarded ports”(转发端口)面板找到应用程序的 URL。

  • Gitpod 集成已启用。Gitpod 配置会自动构建 Jupyter Notebook 应用程序和文档。

  • GitHub 的内置编辑器适用于贡献小的修复。

  • 在 Jupyter Notebook GitHub 仓库中按下点 (.) 键,可以访问更高级的 github.dev 编辑器。