feat(node): use helper to determine project name and root directory in project generators (#18620)

Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com>
This commit is contained in:
Leosvel Pérez Espinosa 2023-08-21 20:47:18 +01:00 committed by GitHub
parent 7900d56ff2
commit d56605522b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 200 additions and 100 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "application", "name": "application",
"factory": "./src/generators/application/application", "factory": "./src/generators/application/application#applicationGeneratorInternal",
"schema": { "schema": {
"$schema": "http://json-schema.org/schema", "$schema": "http://json-schema.org/schema",
"cli": "nx", "cli": "nx",
@ -14,13 +14,19 @@
"type": "string", "type": "string",
"$default": { "$source": "argv", "index": 0 }, "$default": { "$source": "argv", "index": 0 },
"x-prompt": "What name would you like to use for the node application?", "x-prompt": "What name would you like to use for the node application?",
"x-priority": "important" "x-priority": "important",
"pattern": "^[a-zA-Z][^:]*$"
}, },
"directory": { "directory": {
"description": "The directory of the new application.", "description": "The directory of the new application.",
"type": "string", "type": "string",
"x-priority": "important" "x-priority": "important"
}, },
"projectNameAndRootFormat": {
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
"type": "string",
"enum": ["as-provided", "derived"]
},
"skipFormat": { "skipFormat": {
"description": "Skip formatting files", "description": "Skip formatting files",
"type": "boolean", "type": "boolean",
@ -131,7 +137,7 @@
"aliases": ["app"], "aliases": ["app"],
"x-type": "application", "x-type": "application",
"description": "Create a node application.", "description": "Create a node application.",
"implementation": "/packages/node/src/generators/application/application.ts", "implementation": "/packages/node/src/generators/application/application#applicationGeneratorInternal.ts",
"hidden": false, "hidden": false,
"path": "/packages/node/src/generators/application/schema.json", "path": "/packages/node/src/generators/application/schema.json",
"type": "generator" "type": "generator"

View File

@ -1,6 +1,6 @@
{ {
"name": "library", "name": "library",
"factory": "./src/generators/library/library", "factory": "./src/generators/library/library#libraryGeneratorInternal",
"schema": { "schema": {
"$schema": "http://json-schema.org/schema", "$schema": "http://json-schema.org/schema",
"cli": "nx", "cli": "nx",
@ -19,13 +19,19 @@
"type": "string", "type": "string",
"description": "Library name", "description": "Library name",
"$default": { "$source": "argv", "index": 0 }, "$default": { "$source": "argv", "index": 0 },
"x-prompt": "What name would you like to use for the library?" "x-prompt": "What name would you like to use for the library?",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$"
}, },
"directory": { "directory": {
"type": "string", "type": "string",
"description": "A directory where the lib is placed", "description": "A directory where the lib is placed",
"alias": "dir" "alias": "dir"
}, },
"projectNameAndRootFormat": {
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
"type": "string",
"enum": ["as-provided", "derived"]
},
"simpleModuleName": { "simpleModuleName": {
"description": "Keep the module name simple (when using `--directory`).", "description": "Keep the module name simple (when using `--directory`).",
"type": "boolean", "type": "boolean",
@ -131,7 +137,7 @@
"aliases": ["lib"], "aliases": ["lib"],
"x-type": "library", "x-type": "library",
"description": "Create a node library.", "description": "Create a node library.",
"implementation": "/packages/node/src/generators/library/library.ts", "implementation": "/packages/node/src/generators/library/library#libraryGeneratorInternal.ts",
"hidden": false, "hidden": false,
"path": "/packages/node/src/generators/library/schema.json", "path": "/packages/node/src/generators/library/schema.json",
"type": "generator" "type": "generator"

View File

@ -438,6 +438,52 @@ ${jslib}();
checkFilesExist(`dist/apps/_should_keep.txt`); checkFilesExist(`dist/apps/_should_keep.txt`);
}, 120000); }, 120000);
it('should support generating projects with the new name and root format', () => {
const appName = uniq('app1');
const libName = uniq('@my-org/lib1');
runCLI(
`generate @nx/node:app ${appName} --project-name-and-root-format=as-provided --no-interactive`
);
// check files are generated without the layout directory ("apps/") and
// using the project name as the directory when no directory is provided
checkFilesExist(`${appName}/src/main.ts`);
// check build works
expect(runCLI(`build ${appName}`)).toContain(
`Successfully ran target build for project ${appName}`
);
// check tests pass
const appTestResult = runCLI(`test ${appName}`);
expect(appTestResult).toContain(
`Successfully ran target test for project ${appName}`
);
// assert scoped project names are not supported when --project-name-and-root-format=derived
expect(() =>
runCLI(
`generate @nx/node:lib ${libName} --buildable --project-name-and-root-format=derived --no-interactive`
)
).toThrow();
runCLI(
`generate @nx/node:lib ${libName} --buildable --project-name-and-root-format=as-provided --no-interactive`
);
// check files are generated without the layout directory ("libs/") and
// using the project name as the directory when no directory is provided
checkFilesExist(`${libName}/src/index.ts`);
// check build works
expect(runCLI(`build ${libName}`)).toContain(
`Successfully ran target build for project ${libName}`
);
// check tests pass
const libTestResult = runCLI(`test ${libName}`);
expect(libTestResult).toContain(
`Successfully ran target test for project ${libName}`
);
}, 500_000);
describe('NestJS', () => { describe('NestJS', () => {
it('should have plugin output if specified in `tsPlugins`', async () => { it('should have plugin output if specified in `tsPlugins`', async () => {
newProject(); newProject();

View File

@ -11,14 +11,14 @@
"hidden": true "hidden": true
}, },
"application": { "application": {
"factory": "./src/generators/application/application", "factory": "./src/generators/application/application#applicationGeneratorInternal",
"schema": "./src/generators/application/schema.json", "schema": "./src/generators/application/schema.json",
"aliases": ["app"], "aliases": ["app"],
"x-type": "application", "x-type": "application",
"description": "Create a node application." "description": "Create a node application."
}, },
"library": { "library": {
"factory": "./src/generators/library/library", "factory": "./src/generators/library/library#libraryGeneratorInternal",
"schema": "./src/generators/library/schema.json", "schema": "./src/generators/library/schema.json",
"aliases": ["lib"], "aliases": ["lib"],
"x-type": "library", "x-type": "library",

View File

@ -197,7 +197,7 @@ describe('app', () => {
expect(() => expect(() =>
readProjectConfiguration(tree, 'my-dir-my-node-app-e2e') readProjectConfiguration(tree, 'my-dir-my-node-app-e2e')
).toThrow(/Cannot find/); ).not.toThrow();
}); });
it('should update tags', async () => { it('should update tags', async () => {

View File

@ -3,11 +3,9 @@ import {
addProjectConfiguration, addProjectConfiguration,
convertNxGenerator, convertNxGenerator,
ensurePackage, ensurePackage,
extractLayoutDirectory,
formatFiles, formatFiles,
generateFiles, generateFiles,
GeneratorCallback, GeneratorCallback,
getWorkspaceLayout,
joinPathFragments, joinPathFragments,
logger, logger,
names, names,
@ -22,13 +20,13 @@ import {
updateProjectConfiguration, updateProjectConfiguration,
updateTsConfigsToJs, updateTsConfigsToJs,
} from '@nx/devkit'; } from '@nx/devkit';
import { Linter, lintProjectGenerator } from '@nx/linter'; import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
import { configurationGenerator } from '@nx/jest'; import { configurationGenerator } from '@nx/jest';
import { getRelativePathToRootTsConfig, tsConfigBaseOptions } from '@nx/js'; import { getRelativePathToRootTsConfig, tsConfigBaseOptions } from '@nx/js';
import { esbuildVersion } from '@nx/js/src/utils/versions';
import { Linter, lintProjectGenerator } from '@nx/linter';
import { mapLintPattern } from '@nx/linter/src/generators/lint-project/lint-project';
import { join } from 'path'; import { join } from 'path';
import { initGenerator } from '../init/init';
import { import {
expressTypingsVersion, expressTypingsVersion,
expressVersion, expressVersion,
@ -41,11 +39,9 @@ import {
nxVersion, nxVersion,
} from '../../utils/versions'; } from '../../utils/versions';
import { e2eProjectGenerator } from '../e2e-project/e2e-project'; import { e2eProjectGenerator } from '../e2e-project/e2e-project';
import { initGenerator } from '../init/init';
import { setupDockerGenerator } from '../setup-docker/setup-docker'; import { setupDockerGenerator } from '../setup-docker/setup-docker';
import { Schema } from './schema'; import { Schema } from './schema';
import { mapLintPattern } from '@nx/linter/src/generators/lint-project/lint-project';
import { esbuildVersion } from '@nx/js/src/utils/versions';
export interface NormalizedSchema extends Schema { export interface NormalizedSchema extends Schema {
appProjectRoot: string; appProjectRoot: string;
@ -364,7 +360,14 @@ function updateTsConfigOptions(tree: Tree, options: NormalizedSchema) {
} }
export async function applicationGenerator(tree: Tree, schema: Schema) { export async function applicationGenerator(tree: Tree, schema: Schema) {
const options = normalizeOptions(tree, schema); return await applicationGeneratorInternal(tree, {
projectNameAndRootFormat: 'derived',
...schema,
});
}
export async function applicationGeneratorInternal(tree: Tree, schema: Schema) {
const options = await normalizeOptions(tree, schema);
const tasks: GeneratorCallback[] = []; const tasks: GeneratorCallback[] = [];
if (options.framework === 'nest') { if (options.framework === 'nest') {
@ -414,6 +417,8 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
...options, ...options,
projectType: options.framework === 'none' ? 'cli' : 'server', projectType: options.framework === 'none' ? 'cli' : 'server',
name: options.rootProject ? 'e2e' : `${options.name}-e2e`, name: options.rootProject ? 'e2e' : `${options.name}-e2e`,
directory: options.rootProject ? 'e2e' : `${options.appProjectRoot}-e2e`,
projectNameAndRootFormat: 'as-provided',
project: options.name, project: options.name,
port: options.port, port: options.port,
isNest: options.isNest, isNest: options.isNest,
@ -447,21 +452,24 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
return runTasksInSerial(...tasks); return runTasksInSerial(...tasks);
} }
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema { async function normalizeOptions(
const { layoutDirectory, projectDirectory } = extractLayoutDirectory( host: Tree,
options.directory options: Schema
); ): Promise<NormalizedSchema> {
const appsDir = layoutDirectory ?? getWorkspaceLayout(host).appsDir; const {
projectName: appProjectName,
const appDirectory = projectDirectory projectRoot: appProjectRoot,
? `${names(projectDirectory).fileName}/${names(options.name).fileName}` projectNameAndRootFormat,
: names(options.name).fileName; } = await determineProjectNameAndRootOptions(host, {
name: options.name,
const appProjectName = appDirectory.replace(new RegExp('/', 'g'), '-'); projectType: 'application',
directory: options.directory,
const appProjectRoot = options.rootProject projectNameAndRootFormat: options.projectNameAndRootFormat,
? '.' rootProject: options.rootProject,
: joinPathFragments(appsDir, appDirectory); callingGenerator: '@nx/node:application',
});
options.rootProject = appProjectRoot === '.';
options.projectNameAndRootFormat = projectNameAndRootFormat;
options.bundler = options.bundler ?? 'esbuild'; options.bundler = options.bundler ?? 'esbuild';
options.e2eTestRunner = options.e2eTestRunner ?? 'jest'; options.e2eTestRunner = options.e2eTestRunner ?? 'jest';
@ -472,7 +480,7 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
return { return {
...options, ...options,
name: names(appProjectName).fileName, name: appProjectName,
frontendProject: options.frontendProject frontendProject: options.frontendProject
? names(options.frontendProject).fileName ? names(options.frontendProject).fileName
: undefined, : undefined,

View File

@ -1,10 +1,12 @@
import { Linter } from '@nx/linter'; import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/linter';
export interface Schema { export interface Schema {
name: string; name: string;
skipFormat?: boolean; skipFormat?: boolean;
skipPackageJson?: boolean; skipPackageJson?: boolean;
directory?: string; directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
unitTestRunner?: 'jest' | 'none'; unitTestRunner?: 'jest' | 'none';
e2eTestRunner?: 'jest' | 'none'; e2eTestRunner?: 'jest' | 'none';
linter?: Linter; linter?: Linter;

View File

@ -14,13 +14,19 @@
"index": 0 "index": 0
}, },
"x-prompt": "What name would you like to use for the node application?", "x-prompt": "What name would you like to use for the node application?",
"x-priority": "important" "x-priority": "important",
"pattern": "^[a-zA-Z][^:]*$"
}, },
"directory": { "directory": {
"description": "The directory of the new application.", "description": "The directory of the new application.",
"type": "string", "type": "string",
"x-priority": "important" "x-priority": "important"
}, },
"projectNameAndRootFormat": {
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
"type": "string",
"enum": ["as-provided", "derived"]
},
"skipFormat": { "skipFormat": {
"description": "Skip formatting files", "description": "Skip formatting files",
"type": "boolean", "type": "boolean",

View File

@ -1,13 +1,10 @@
import * as path from 'path';
import { import {
addDependenciesToPackageJson, addDependenciesToPackageJson,
addProjectConfiguration, addProjectConfiguration,
convertNxGenerator, convertNxGenerator,
extractLayoutDirectory,
formatFiles, formatFiles,
generateFiles, generateFiles,
GeneratorCallback, GeneratorCallback,
getWorkspaceLayout,
joinPathFragments, joinPathFragments,
names, names,
offsetFromRoot, offsetFromRoot,
@ -16,19 +13,30 @@ import {
Tree, Tree,
updateJson, updateJson,
} from '@nx/devkit'; } from '@nx/devkit';
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
import { Linter, lintProjectGenerator } from '@nx/linter'; import { Linter, lintProjectGenerator } from '@nx/linter';
import { Schema } from './schema';
import { axiosVersion } from '../../utils/versions';
import { join } from 'path';
import { import {
globalJavaScriptOverrides, globalJavaScriptOverrides,
globalTypeScriptOverrides, globalTypeScriptOverrides,
} from '@nx/linter/src/generators/init/global-eslint-config'; } from '@nx/linter/src/generators/init/global-eslint-config';
import * as path from 'path';
import { join } from 'path';
import { axiosVersion } from '../../utils/versions';
import { Schema } from './schema';
export async function e2eProjectGenerator(host: Tree, _options: Schema) { export async function e2eProjectGenerator(host: Tree, options: Schema) {
return await e2eProjectGeneratorInternal(host, {
projectNameAndRootFormat: 'derived',
...options,
});
}
export async function e2eProjectGeneratorInternal(
host: Tree,
_options: Schema
) {
const tasks: GeneratorCallback[] = []; const tasks: GeneratorCallback[] = [];
const options = normalizeOptions(host, _options); const options = await normalizeOptions(host, _options);
const appProject = readProjectConfiguration(host, options.project); const appProject = readProjectConfiguration(host, options.project);
addProjectConfiguration(host, options.e2eProjectName, { addProjectConfiguration(host, options.e2eProjectName, {
@ -146,25 +154,23 @@ export async function e2eProjectGenerator(host: Tree, _options: Schema) {
return runTasksInSerial(...tasks); return runTasksInSerial(...tasks);
} }
function normalizeOptions( async function normalizeOptions(
tree: Tree, tree: Tree,
options: Schema options: Schema
): Omit<Schema, 'name'> & { e2eProjectRoot: string; e2eProjectName: string } { ): Promise<
const { layoutDirectory, projectDirectory } = extractLayoutDirectory( Omit<Schema, 'name'> & { e2eProjectRoot: string; e2eProjectName: string }
options.directory > {
); const { projectName: e2eProjectName, projectRoot: e2eProjectRoot } =
const appsDir = layoutDirectory ?? getWorkspaceLayout(tree).appsDir; await determineProjectNameAndRootOptions(tree, {
const name = options.name ?? `${options.project}-e2e`; name: options.name ?? `${options.project}-e2e`,
projectType: 'library',
const appDirectory = projectDirectory directory: options.rootProject ? 'e2e' : options.directory,
? `${names(projectDirectory).fileName}/${names(name).fileName}` projectNameAndRootFormat: options.rootProject
: names(name).fileName; ? 'as-provided'
: options.projectNameAndRootFormat,
const e2eProjectName = appDirectory.replace(new RegExp('/', 'g'), '-'); // this is an internal generator, don't save defaults
callingGenerator: null,
const e2eProjectRoot = options.rootProject });
? 'e2e'
: joinPathFragments(appsDir, appDirectory);
return { return {
...options, ...options,

View File

@ -1,7 +1,10 @@
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
export interface Schema { export interface Schema {
project: string; project: string;
projectType: 'server' | 'cli'; projectType: 'server' | 'cli';
directory?: string; directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
name?: string; name?: string;
port?: number; port?: number;
linter?: 'eslint' | 'none'; linter?: 'eslint' | 'none';

View File

@ -18,6 +18,11 @@
"type": "string", "type": "string",
"x-priority": "important" "x-priority": "important"
}, },
"projectNameAndRootFormat": {
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
"type": "string",
"enum": ["as-provided", "derived"]
},
"name": { "name": {
"description": "The name of the e2e project. Defaults to the project name with '-e2e' suffix.", "description": "The name of the e2e project. Defaults to the project name with '-e2e' suffix.",
"type": "string" "type": "string"

View File

@ -1,10 +1,8 @@
import { import {
convertNxGenerator, convertNxGenerator,
extractLayoutDirectory,
formatFiles, formatFiles,
generateFiles, generateFiles,
GeneratorCallback, GeneratorCallback,
getWorkspaceLayout,
joinPathFragments, joinPathFragments,
names, names,
offsetFromRoot, offsetFromRoot,
@ -15,26 +13,31 @@ import {
updateProjectConfiguration, updateProjectConfiguration,
updateTsConfigsToJs, updateTsConfigsToJs,
} from '@nx/devkit'; } from '@nx/devkit';
import { Schema } from './schema'; import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
import { libraryGenerator as jsLibraryGenerator } from '@nx/js'; import { libraryGenerator as jsLibraryGenerator } from '@nx/js';
import { join } from 'path';
import { addSwcDependencies } from '@nx/js/src/utils/swc/add-swc-dependencies';
import { addSwcConfig } from '@nx/js/src/utils/swc/add-swc-config'; import { addSwcConfig } from '@nx/js/src/utils/swc/add-swc-config';
import { addSwcDependencies } from '@nx/js/src/utils/swc/add-swc-dependencies';
import { join } from 'path';
import { initGenerator } from '../init/init'; import { initGenerator } from '../init/init';
import { getImportPath } from '@nx/js/src/utils/get-import-path'; import { Schema } from './schema';
export interface NormalizedSchema extends Schema { export interface NormalizedSchema extends Schema {
name: string;
fileName: string; fileName: string;
projectName: string;
projectRoot: string; projectRoot: string;
projectDirectory: string;
parsedTags: string[]; parsedTags: string[];
compiler: 'swc' | 'tsc'; compiler: 'swc' | 'tsc';
} }
export async function libraryGenerator(tree: Tree, schema: Schema) { export async function libraryGenerator(tree: Tree, schema: Schema) {
const options = normalizeOptions(tree, schema); return await libraryGeneratorInternal(tree, {
projectNameAndRootFormat: 'derived',
...schema,
});
}
export async function libraryGeneratorInternal(tree: Tree, schema: Schema) {
const options = await normalizeOptions(tree, schema);
const tasks: GeneratorCallback[] = [ const tasks: GeneratorCallback[] = [
await initGenerator(tree, { await initGenerator(tree, {
...options, ...options,
@ -75,37 +78,42 @@ export async function libraryGenerator(tree: Tree, schema: Schema) {
export default libraryGenerator; export default libraryGenerator;
export const librarySchematic = convertNxGenerator(libraryGenerator); export const librarySchematic = convertNxGenerator(libraryGenerator);
function normalizeOptions(tree: Tree, options: Schema): NormalizedSchema { async function normalizeOptions(
const { layoutDirectory, projectDirectory } = extractLayoutDirectory( tree: Tree,
options.directory options: Schema
); ): Promise<NormalizedSchema> {
const { npmScope, libsDir: defaultLibsDir } = getWorkspaceLayout(tree); const {
const libsDir = layoutDirectory ?? defaultLibsDir; projectName,
const name = names(options.name).fileName; names: projectNames,
const fullProjectDirectory = projectDirectory projectRoot,
? `${names(projectDirectory).fileName}/${name}` importPath,
: name; projectNameAndRootFormat,
} = await determineProjectNameAndRootOptions(tree, {
name: options.name,
projectType: 'library',
directory: options.directory,
importPath: options.importPath,
projectNameAndRootFormat: options.projectNameAndRootFormat,
callingGenerator: '@nx/node:library',
});
options.projectNameAndRootFormat = projectNameAndRootFormat;
const projectName = fullProjectDirectory.replace(new RegExp('/', 'g'), '-');
const fileName = getCaseAwareFileName({ const fileName = getCaseAwareFileName({
fileName: options.simpleModuleName ? name : projectName, fileName: options.simpleModuleName
? projectNames.projectSimpleName
: projectNames.projectFileName,
pascalCaseFiles: options.pascalCaseFiles, pascalCaseFiles: options.pascalCaseFiles,
}); });
const projectRoot = joinPathFragments(libsDir, fullProjectDirectory);
const parsedTags = options.tags const parsedTags = options.tags
? options.tags.split(',').map((s) => s.trim()) ? options.tags.split(',').map((s) => s.trim())
: []; : [];
const importPath =
options.importPath || getImportPath(tree, fullProjectDirectory);
return { return {
...options, ...options,
fileName, fileName,
name: projectName, projectName,
projectRoot, projectRoot,
projectDirectory: fullProjectDirectory,
parsedTags, parsedTags,
importPath, importPath,
}; };
@ -150,9 +158,7 @@ function updateProject(tree: Tree, options: NormalizedSchema) {
return; return;
} }
const project = readProjectConfiguration(tree, options.name); const project = readProjectConfiguration(tree, options.projectName);
const { libsDir } = getWorkspaceLayout(tree);
const rootProject = options.projectRoot === '.' || options.projectRoot === ''; const rootProject = options.projectRoot === '.' || options.projectRoot === '';
project.targets = project.targets || {}; project.targets = project.targets || {};
@ -162,9 +168,7 @@ function updateProject(tree: Tree, options: NormalizedSchema) {
options: { options: {
outputPath: joinPathFragments( outputPath: joinPathFragments(
'dist', 'dist',
rootProject rootProject ? options.projectName : options.projectRoot
? options.projectDirectory
: `${libsDir}/${options.projectDirectory}`
), ),
tsConfig: `${options.projectRoot}/tsconfig.lib.json`, tsConfig: `${options.projectRoot}/tsconfig.lib.json`,
packageJson: `${options.projectRoot}/package.json`, packageJson: `${options.projectRoot}/package.json`,
@ -182,5 +186,5 @@ function updateProject(tree: Tree, options: NormalizedSchema) {
project.targets.build.options.srcRootForCompilationRoot = options.rootDir; project.targets.build.options.srcRootForCompilationRoot = options.rootDir;
} }
updateProjectConfiguration(tree, options.name, project); updateProjectConfiguration(tree, options.projectName, project);
} }

View File

@ -1,8 +1,10 @@
import { Linter } from '@nx/linter'; import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
import type { Linter } from '@nx/linter';
export interface Schema { export interface Schema {
name: string; name: string;
directory?: string; directory?: string;
projectNameAndRootFormat?: ProjectNameAndRootFormat;
simpleModuleName?: boolean; simpleModuleName?: boolean;
skipTsConfig?: boolean; skipTsConfig?: boolean;
skipFormat?: boolean; skipFormat?: boolean;

View File

@ -19,13 +19,19 @@
"$source": "argv", "$source": "argv",
"index": 0 "index": 0
}, },
"x-prompt": "What name would you like to use for the library?" "x-prompt": "What name would you like to use for the library?",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$"
}, },
"directory": { "directory": {
"type": "string", "type": "string",
"description": "A directory where the lib is placed", "description": "A directory where the lib is placed",
"alias": "dir" "alias": "dir"
}, },
"projectNameAndRootFormat": {
"description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).",
"type": "string",
"enum": ["as-provided", "derived"]
},
"simpleModuleName": { "simpleModuleName": {
"description": "Keep the module name simple (when using `--directory`).", "description": "Keep the module name simple (when using `--directory`).",
"type": "boolean", "type": "boolean",