NX Monorepo中Python虚拟环境配置及测试预启动问题
问题背景
在大型JavaScript项目中使用NX monorepo,部分模块依赖一个创建了独立Python虚拟环境的外部项目,Node.js代码需执行Python命令获取JS构建所需数据。运行NX脚本或测试时需激活该虚拟环境,但NX生成的是与系统隔离的独立进程,导致激活失败。尝试通过nx:run-script或nx:run-commands执行conda activate testenv时,出现以下错误:
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'. To initialize your shell, run $ conda init <SHELL_NAME> Currently supported shells are: - bash - fish - tcsh - xonsh - zsh - powershell
使用环境为MacOS系统下的ZSH。
问题解答
1. 在指定测试前启动Python虚拟环境
由于NX的执行进程是非交互式shell,直接调用conda activate会失败,可通过以下方式解决:
直接调用虚拟环境内的Python可执行文件
无需激活环境,直接使用虚拟环境中Python的绝对路径执行命令。例如,testenv虚拟环境的Python路径通常为~/miniconda3/envs/testenv/bin/python,在NX脚本中配置:{ "scripts": { "test-with-python": "~/miniconda3/envs/testenv/bin/python your-data-script.py && nx test your-module" } }使用
conda run命令执行conda run可直接在指定虚拟环境中执行命令,无需手动激活。在project.json的targets中配置:{ "targets": { "test-with-env": { "executor": "nx:run-commands", "options": { "commands": [ "conda run -n testenv python path/to/your-data-script.py", "nx test your-module" ], "parallel": false } } } }运行时执行
nx run your-module:test-with-env即可。通过shell脚本初始化conda并激活环境
创建shell脚本run-test-with-env.sh:#!/bin/zsh # 加载conda配置(非交互式shell不会自动加载.zshrc中的配置) source ~/miniconda3/etc/profile.d/conda.sh conda activate testenv # 执行数据脚本和测试命令 python path/to/your-data-script.py nx test your-module给脚本添加执行权限:
chmod +x run-test-with-env.sh,再在project.json中配置调用:{ "targets": { "test-with-env": { "executor": "nx:run-commands", "options": { "command": "./run-test-with-env.sh" } } } }
2. 为NX生成的进程配置自定义环境
NX进程可通过以下方式配置自定义环境变量:
在targets中直接设置
env字段
在project.json的对应target里添加环境变量配置,例如:{ "targets": { "build": { "executor": "@nx/js:tsc", "options": { "env": { "PYTHONPATH": "/path/to/your/python/project", "PATH": "/path/to/miniconda3/envs/testenv/bin:$PATH" } } } } }这样NX执行该target时,进程会带上这些环境变量。
使用环境变量文件加载
在项目根目录创建.env或.env.local文件,添加需要的环境变量:PYTHONPATH=/path/to/your/python/project PATH=/path/to/miniconda3/envs/testenv/bin:$PATHNX会自动加载这些文件中的环境变量到进程中(需确保NX版本支持,v14+版本基本都支持)。
全局NX配置中设置环境变量
修改nx.json的tasksRunnerOptions,为所有任务配置全局环境变量:{ "tasksRunnerOptions": { "default": { "runner": "@nx/workspace/tasks-runners/default", "options": { "env": { "PYTHONPATH": "/path/to/your/python/project" } } } } }
内容的提问来源于stack exchange,提问作者vlasterx

