You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 23:36:07