如何将Angular Schematics集成到Nx Monorepo并自定义应用生成?
自定义Angular Schematic集成Nx工作区解决方案
一、解决ng-add时的“Angular Material只能用于默认配置”错误
这个错误的核心是你的自定义Schematic的ng-add生成器逻辑依赖了Angular CLI的默认项目结构,而Nx工作区的项目配置、目录结构和原生Angular CLI存在差异,可按以下步骤修复:
适配Nx的项目配置读取逻辑
替换Schematic中读取项目配置的Angular CLI原生方法,改用Nx提供的工具函数:// 导入Nx工具函数 import { getProjects, getProjectConfig } from '@nrwl/workspace'; export function ngAdd(options: any): Rule { return (tree: Tree, context: SchematicContext) => { // 获取Nx工作区的所有项目 const projects = getProjects(tree); // 若未指定项目,取默认项目(或让用户通过--project参数指定) const targetProject = options.project ?? Object.keys(projects)[0]; const projectConfig = getProjectConfig(tree, targetProject); // 后续逻辑基于Nx的projectConfig处理,比如获取项目根路径、构建配置等 // 替换原有的Angular CLI配置读取逻辑 }; };显式指定目标项目
执行ng-add时明确指定Nx项目名称,避免Schematic误判配置:nx add @SCHEMATICNAME:ng-add --project=your-nx-app-name检查Angular Material相关逻辑
如果你的Schematic集成了Angular Material,确保它能识别Nx项目的样式预处理器配置(比如stylePreprocessorOptions),不要硬编码.angular.json路径,而是从Nx的workspace.json(或nx.json)中读取对应项目的配置。
二、实现类似nx g app的自定义应用生成流程
要让自定义Schematic像Nx原生应用生成器一样工作,可通过两种方式实现:
方法1:封装为Nx工作区生成器
创建Nx生成器骨架
在你的Nx工作区中生成一个自定义生成器:nx g workspace-generator custom-app在生成器中调用自定义Schematic
修改生成器的index.ts,使用externalSchematic调用你的Angular Schematic,同时处理Nx的项目注册逻辑:import { Tree, SchematicContext, externalSchematic, chain } from '@angular-devkit/schematics'; import { addProjectToNxJson, updateWorkspace } from '@nrwl/workspace'; export default function (tree: Tree, context: SchematicContext) { const options = context.options as any; const projectName = options.name; const projectRoot = `apps/${projectName}`; return chain([ // 调用你的自定义Angular Schematic externalSchematic('@SCHEMATICNAME', 'app', { name: projectName, // 传递Schematic需要的其他参数,比如样式类型、路由等 style: 'scss', routing: true }), // 将新应用注册到Nx工作区配置 updateWorkspace(workspace => { workspace.projects.add({ name: projectName, root: projectRoot, projectType: 'application', sourceRoot: `${projectRoot}/src`, targets: { build: { executor: '@nrwl/angular:browser', options: { outputPath: `dist/${projectRoot}`, index: `${projectRoot}/src/index.html`, main: `${projectRoot}/src/main.ts`, polyfills: `${projectRoot}/src/polyfills.ts`, tsConfig: `${projectRoot}/tsconfig.app.json`, assets: [`${projectRoot}/src/favicon.ico`, `${projectRoot}/src/assets`], styles: [`${projectRoot}/src/styles.scss`], scripts: [] } }, test: { executor: '@nrwl/angular:karma', options: { main: `${projectRoot}/src/test.ts`, polyfills: `${projectRoot}/src/polyfills.ts`, tsConfig: `${projectRoot}/tsconfig.spec.json`, karmaConfig: `${projectRoot}/karma.conf.js`, assets: [`${projectRoot}/src/favicon.ico`, `${projectRoot}/src/assets`], styles: [`${projectRoot}/src/styles.scss`], scripts: [] } } } }); }), // 添加项目到nx.json的tags等配置 addProjectToNxJson({ projectName, tags: options.tags ?? [] }) ]); }使用自定义生成器创建应用
运行以下命令即可像nx g app一样生成应用:nx g workspace-generator custom-app your-app-name --tags=scope:your-scope,type:application
方法2:直接修改自定义Schematic适配Nx
如果要让你的原生Angular Schematic直接支持Nx,需要:
- 在Schematic的应用生成器中,读取Nx的
workspace.json而非.angular.json - 生成的项目目录遵循Nx的规范(比如默认放在
apps/或libs/下) - 自动将新项目注册到Nx的工作区配置中
完成后,即可直接使用:
nx g @SCHEMATICNAME:app your-app-name
内容的提问来源于stack exchange,提问作者baglayan
相关产品推荐
相关产品推荐

