NX workspace-generator使用directory属性时抛出异常排查
问题背景
- 自定义NX
workspace-generator用于生成带自定义配置的Angular库,不传--directory参数时,调用libraryGenerator()可正常完成库生成 - 传入
--directory参数后触发报错,错误信息如下:
Cannot find configuration for 'myLib' in /workspace.json. The terminal process "/bin/zsh '-c', 'npx nx workspace-generator ng-library myLib --teamName=myTeam --directory=parentDir --dry-run'" terminated with exit code: 1.
- 当前使用
@nrwl/angular版本为13.1.5,暂无法升级,需要直接通过传参指定生成目录,不想生成后手动移动文件 - 现有核心代码如下:
- 生成器入口
index.ts关键逻辑:
- 生成器入口
import { Tree, formatFiles, installPackagesTask, readProjectConfiguration, generateFiles, joinPathFragments, updateProjectConfiguration, getProjects, ProjectConfiguration } from '@nrwl/devkit'; import { libraryGenerator } from '@nrwl/angular/generators'; import { LibSchemaModel } from './lib-schema.model'; export default async function (tree: Tree, schema: LibSchemaModel) { const libraryName = schema.name; await libraryGenerator(tree, { name: libraryName, importPath: `@${schema.importPathPrefix}/${libraryName}`, publishable: schema.libraryType === 'publishable', buildable: schema.libraryType === 'buildable', directory: schema.directory // 注释该行则所有功能运行正常 }); // ... 后续自定义配置逻辑 }
- 生成器
schema.json配置:
{ "$schema": "http://json-schema.org/schema", "cli": "nx", "$id": "ng-library", "type": "object", "properties": { "name": { "type": "string", "description": "The name of the library.", "x-prompt": "Which name do you want to use for the library?", "$default": { "$source": "argv", "index": 0 } }, "teamName": { "type": "string", "description": "The team name.", "x-prompt": "Which is the library's team name?" }, "importPathPrefix": { "type": "string", "description": "The prefix used for the library importPath." }, "directory": { "type": "string", "description": "The directory that will contain the new library." }, "libraryType": { "description": "Library type: `Publishable` to publish it outside the workspace or `Buildable` to use it internally in the workspace.", "type": "string", "default": "publishable", "enum": [ "publishable", "buildable" ], "x-prompt": { "message": "Which library type do you want to generate?", "type": "list", "items": [ { "value": "publishable", "label": "Publishable" }, { "value": "buildable", "label": "Buildable" } ] } }, "installDeps": { "type": "boolean", "description": "Install dependencies", "default": true } }, "required": ["name", "teamName", "teamEmail"] }
报错原因
13.1.x版本的@nrwl/angular库生成器有固定命名逻辑:传入directory参数时,最终写入workspace.json的项目名不是传入的原始name值,会自动把目录名按kebab-case规则转换后,拼接在原始库名前作为最终的项目唯一key。
比如传入name=myLib、directory=parentDir,最终注册的项目名是parent-dir-myLib,后续自定义逻辑里如果直接用原始的libraryName(即myLib)调用readProjectConfiguration读取项目配置,自然找不到对应配置抛出错误。
修复方案
调用libraryGenerator前先按NX内部规则计算出最终的项目名,后续所有读取、修改项目配置的操作都使用这个计算后的项目名即可,不需要手动移动生成的文件。
直接用@nrwl/devkit导出的names工具方法处理命名拼接即可,修正后的核心代码如下:
import { Tree, formatFiles, installPackagesTask, readProjectConfiguration, generateFiles, joinPathFragments, updateProjectConfiguration, getProjects, ProjectConfiguration, names // 引入官方命名处理工具 } from '@nrwl/devkit'; import { libraryGenerator } from '@nrwl/angular/generators'; import { LibSchemaModel } from './lib-schema.model'; export default async function (tree: Tree, schema: LibSchemaModel) { const libraryName = schema.name; // 按NX规则计算最终项目名:有directory时拼接{kebab-case格式的directory}-{name},无directory则直接用原始name const projectName = schema.directory ? `${names(schema.directory).fileName}-${libraryName}` : libraryName; await libraryGenerator(tree, { name: libraryName, importPath: `@${schema.importPathPrefix}/${libraryName}`, publishable: schema.libraryType === 'publishable', buildable: schema.libraryType === 'buildable', directory: schema.directory }); // 后续所有项目配置操作,都用projectName代替原来的libraryName // 示例:const projectConfig = readProjectConfiguration(tree, projectName); // ... 其余原有逻辑保持不变 }
如果是多级目录场景,把每一级目录都按kebab-case转换后用-拼接,再加上原始库名即可,和NX内部生成器的命名规则完全一致。
内容的提问来源于stack exchange,提问作者Francesco
相关产品推荐
相关产品推荐

