feat(js): refactor usages of npmScope (#16947)

This commit is contained in:
Jason Jean 2023-05-15 16:06:24 -04:00 committed by GitHub
parent 9b4ba3af4d
commit 6b928bc250
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 222 additions and 349 deletions

View File

@ -104,13 +104,11 @@ It only uses language primitives and immutable objects
- [createProjectGraphAsync](../../devkit/documents/nx_devkit#createprojectgraphasync)
- [defaultTasksRunner](../../devkit/documents/nx_devkit#defaulttasksrunner)
- [detectPackageManager](../../devkit/documents/nx_devkit#detectpackagemanager)
- [detectWorkspaceScope](../../devkit/documents/nx_devkit#detectworkspacescope)
- [ensurePackage](../../devkit/documents/nx_devkit#ensurepackage)
- [extractLayoutDirectory](../../devkit/documents/nx_devkit#extractlayoutdirectory)
- [formatFiles](../../devkit/documents/nx_devkit#formatfiles)
- [generateFiles](../../devkit/documents/nx_devkit#generatefiles)
- [getDependentPackagesForProject](../../devkit/documents/nx_devkit#getdependentpackagesforproject)
- [getImportPath](../../devkit/documents/nx_devkit#getimportpath)
- [getNpmPackageSharedConfig](../../devkit/documents/nx_devkit#getnpmpackagesharedconfig)
- [getOutputsForTargetAndConfiguration](../../devkit/documents/nx_devkit#getoutputsfortargetandconfiguration)
- [getPackageManagerCommand](../../devkit/documents/nx_devkit#getpackagemanagercommand)
@ -1139,24 +1137,6 @@ Detects which package manager is used in the workspace based on the lock file.
---
### detectWorkspaceScope
**detectWorkspaceScope**(`packageName`): `string`
Detect workspace scope from the package.json name
#### Parameters
| Name | Type |
| :------------ | :------- |
| `packageName` | `string` |
#### Returns
`string`
---
### ensurePackage
**ensurePackage**(`tree`, `pkg`, `requiredVersion`, `options?`): `void`
@ -1324,25 +1304,6 @@ doesn't get confused about incorrect TypeScript files.
---
### getImportPath
**getImportPath**(`npmScope`, `projectDirectory`): `string`
Prefixes project name with npm scope
#### Parameters
| Name | Type |
| :----------------- | :------- |
| `npmScope` | `string` |
| `projectDirectory` | `string` |
#### Returns
`string`
---
### getNpmPackageSharedConfig
**getNpmPackageSharedConfig**(`pkgName`, `version`): [`SharedLibraryConfig`](../../devkit/documents/nx_devkit#sharedlibraryconfig) \| `undefined`
@ -1471,12 +1432,12 @@ Example:
`Object`
| Name | Type |
| :-------------------- | :-------- |
| `appsDir` | `string` |
| `libsDir` | `string` |
| `npmScope` | `string` |
| `standaloneAsDefault` | `boolean` |
| Name | Type | Description |
| :-------------------- | :-------- | :----------------------------------------------------------------------- |
| `appsDir` | `string` | - |
| `libsDir` | `string` | - |
| `npmScope` | `string` | **`Deprecated`** This will be removed in Nx 17. Use getNpmScope instead. |
| `standaloneAsDefault` | `boolean` | - |
---

View File

@ -12,7 +12,7 @@
"npmScope": {
"type": "string",
"description": "Npm scope for importing libs. NOTE: only used if running the generator in an Angular CLI workspace.",
"x-priority": "important"
"x-deprecated": "This will be inferred from your root package.json"
},
"defaultBase": {
"type": "string",

View File

@ -104,13 +104,11 @@ It only uses language primitives and immutable objects
- [createProjectGraphAsync](../../devkit/documents/nx_devkit#createprojectgraphasync)
- [defaultTasksRunner](../../devkit/documents/nx_devkit#defaulttasksrunner)
- [detectPackageManager](../../devkit/documents/nx_devkit#detectpackagemanager)
- [detectWorkspaceScope](../../devkit/documents/nx_devkit#detectworkspacescope)
- [ensurePackage](../../devkit/documents/nx_devkit#ensurepackage)
- [extractLayoutDirectory](../../devkit/documents/nx_devkit#extractlayoutdirectory)
- [formatFiles](../../devkit/documents/nx_devkit#formatfiles)
- [generateFiles](../../devkit/documents/nx_devkit#generatefiles)
- [getDependentPackagesForProject](../../devkit/documents/nx_devkit#getdependentpackagesforproject)
- [getImportPath](../../devkit/documents/nx_devkit#getimportpath)
- [getNpmPackageSharedConfig](../../devkit/documents/nx_devkit#getnpmpackagesharedconfig)
- [getOutputsForTargetAndConfiguration](../../devkit/documents/nx_devkit#getoutputsfortargetandconfiguration)
- [getPackageManagerCommand](../../devkit/documents/nx_devkit#getpackagemanagercommand)
@ -1139,24 +1137,6 @@ Detects which package manager is used in the workspace based on the lock file.
---
### detectWorkspaceScope
**detectWorkspaceScope**(`packageName`): `string`
Detect workspace scope from the package.json name
#### Parameters
| Name | Type |
| :------------ | :------- |
| `packageName` | `string` |
#### Returns
`string`
---
### ensurePackage
**ensurePackage**(`tree`, `pkg`, `requiredVersion`, `options?`): `void`
@ -1324,25 +1304,6 @@ doesn't get confused about incorrect TypeScript files.
---
### getImportPath
**getImportPath**(`npmScope`, `projectDirectory`): `string`
Prefixes project name with npm scope
#### Parameters
| Name | Type |
| :----------------- | :------- |
| `npmScope` | `string` |
| `projectDirectory` | `string` |
#### Returns
`string`
---
### getNpmPackageSharedConfig
**getNpmPackageSharedConfig**(`pkgName`, `version`): [`SharedLibraryConfig`](../../devkit/documents/nx_devkit#sharedlibraryconfig) \| `undefined`
@ -1471,12 +1432,12 @@ Example:
`Object`
| Name | Type |
| :-------------------- | :-------- |
| `appsDir` | `string` |
| `libsDir` | `string` |
| `npmScope` | `string` |
| `standaloneAsDefault` | `boolean` |
| Name | Type | Description |
| :-------------------- | :-------- | :----------------------------------------------------------------------- |
| `appsDir` | `string` | - |
| `libsDir` | `string` | - |
| `npmScope` | `string` | **`Deprecated`** This will be removed in Nx 17. Use getNpmScope instead. |
| `standaloneAsDefault` | `boolean` | - |
---

View File

@ -25,10 +25,6 @@
"type": "boolean",
"default": true
},
"npmScope": {
"type": "string",
"description": "Npm scope for importing libs."
},
"standaloneApi": {
"description": "Use Standalone Components if generating an Angular application.",
"type": "boolean",

View File

@ -14,10 +14,6 @@
"description": "The name of the application.",
"type": "string"
},
"npmScope": {
"description": "Npm scope for importing libs.",
"type": "string"
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",

View File

@ -142,7 +142,6 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
affected: {
defaultBase: 'main',
},
npmScope: 'projscope',
tasksRunnerOptions: {
default: {
options: {

View File

@ -582,9 +582,9 @@ describe('Workspace Tests', () => {
});
it('should work for libraries when scope is unset', async () => {
const json = readJson('nx.json');
delete json.npmScope;
updateFile('nx.json', JSON.stringify(json));
const json = readJson('package.json');
json.name = proj;
updateFile('package.json', JSON.stringify(json));
const lib1 = uniq('mylib');
const lib2 = uniq('mylib');

View File

@ -5,6 +5,9 @@ import {
names,
Tree,
} from '@nx/devkit';
import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope';
import type { Schema } from '../schema';
import type { NormalizedSchema } from './normalized-schema';
import { E2eTestRunner, UnitTestRunner } from '../../../utils/test-runners';
@ -28,11 +31,8 @@ export function normalizeOptions(
? 'e2e'
: `${names(options.name).fileName}-e2e`;
const {
appsDir: defaultAppsDir,
npmScope,
standaloneAsDefault,
} = getWorkspaceLayout(host);
const { appsDir: defaultAppsDir, standaloneAsDefault } =
getWorkspaceLayout(host);
const appsDir = layoutDirectory ?? defaultAppsDir;
const appProjectRoot = options.rootProject
? '.'
@ -45,7 +45,11 @@ export function normalizeOptions(
? options.tags.split(',').map((s) => s.trim())
: [];
const prefix = normalizeNewProjectPrefix(options.prefix, npmScope, 'app');
const prefix = normalizeNewProjectPrefix(
options.prefix,
getNpmScope(host),
'app'
);
options.standaloneConfig = options.standaloneConfig ?? standaloneAsDefault;

View File

@ -1,5 +1,5 @@
{
"name": "<% if(npmScope) { %><%= npmScope %>/<% } %><%= libFileName %>",
"name": "<%= importPath %>",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "<%= angularPeerDepVersion %>",

View File

@ -1,7 +1,6 @@
import type { Tree } from '@nx/devkit';
import {
generateFiles,
getWorkspaceLayout,
joinPathFragments,
names,
offsetFromRoot,
@ -18,7 +17,6 @@ export function createFiles(
options: NormalizedSchema,
project: AngularProjectConfiguration
) {
const { npmScope } = getWorkspaceLayout(tree);
const rootOffset = offsetFromRoot(options.libraryOptions.projectRoot);
const libNames = names(options.libraryOptions.fileName);
const pathToComponent = options.componentOptions.flat
@ -42,7 +40,7 @@ export function createFiles(
projectRoot: options.libraryOptions.projectRoot,
routing: options.libraryOptions.routing,
pathToComponent,
npmScope,
importPath: options.libraryOptions.importPath,
rootOffset,
angularPeerDepVersion: `^${major}.${minor}.0`,
tpl: '',

View File

@ -5,10 +5,14 @@ import {
names,
Tree,
} from '@nx/devkit';
import { getImportPath } from 'nx/src/utils/path';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope';
import { Linter } from '@nx/linter';
import { Schema } from '../schema';
import { NormalizedSchema } from './normalized-schema';
import { Linter } from '@nx/linter';
import { UnitTestRunner } from '../../../utils/test-runners';
import { normalizeNewProjectPrefix } from '../../utils/project';
@ -37,11 +41,9 @@ export function normalizeOptions(host: Tree, schema: Schema): NormalizedSchema {
? `${names(projectDirectory).fileName}/${name}`.replace(/\/+/g, '/')
: name;
const {
libsDir: defaultLibsDirectory,
npmScope,
standaloneAsDefault,
} = getWorkspaceLayout(host);
const { libsDir: defaultLibsDirectory, standaloneAsDefault } =
getWorkspaceLayout(host);
const npmScope = getNpmScope(host);
const libsDir = layoutDirectory ?? defaultLibsDirectory;
const projectName = fullProjectDirectory
@ -60,7 +62,7 @@ export function normalizeOptions(host: Tree, schema: Schema): NormalizedSchema {
options.standaloneConfig = options.standaloneConfig ?? standaloneAsDefault;
const importPath =
options.importPath || getImportPath(npmScope, fullProjectDirectory);
options.importPath || getImportPath(host, fullProjectDirectory);
const ngCliSchematicLibRoot = projectName;
const allNormalizedOptions = {

View File

@ -98,7 +98,6 @@ exports[`workspace move to nx layout should create nx.json 1`] = `
],
"sharedGlobals": [],
},
"npmScope": "my-org",
"targetDefaults": {
"build": {
"dependsOn": [

View File

@ -14,7 +14,6 @@ import {
formatFilesTask,
getAllProjects,
getWorkspaceRootFileTypesInfo,
normalizeOptions,
updatePackageJson,
updateRootEsLintConfig,
updateRootTsConfig,
@ -24,11 +23,10 @@ import {
export async function migrateFromAngularCli(
tree: Tree,
rawOptions: GeneratorOptions
options: GeneratorOptions
): Promise<GeneratorCallback> {
validateWorkspace(tree);
const projects = getAllProjects(tree);
const options = normalizeOptions(tree, rawOptions, projects);
const angularJson = readJson(tree, 'angular.json') as any;
ensureAngularDevKitPeerDependenciesAreInstalled(tree);

View File

@ -3,7 +3,9 @@ import { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
import type { Styles } from '../utils/types';
export interface GeneratorOptions {
skipInstall?: boolean;
/**
* @deprecated This should be inferred with {@link getNpmScope}
*/
npmScope?: string;
defaultBase?: string;

View File

@ -9,7 +9,7 @@
"npmScope": {
"type": "string",
"description": "Npm scope for importing libs. NOTE: only used if running the generator in an Angular CLI workspace.",
"x-priority": "important"
"x-deprecated": "This will be inferred from your root package.json"
},
"defaultBase": {
"type": "string",

View File

@ -1,7 +1,6 @@
export * from './dependencies';
export * from './format-files-task';
export * from './logger';
export * from './normalize-options';
export * from './projects';
export * from './types';
export * from './validation-logging';

View File

@ -1,46 +0,0 @@
import type { Tree } from '@nx/devkit';
import {
detectWorkspaceScope,
joinPathFragments,
names,
readJson,
} from '@nx/devkit';
import type { GeneratorOptions } from '../schema';
import type { WorkspaceProjects } from './types';
export function normalizeOptions(
tree: Tree,
options: GeneratorOptions,
projects: WorkspaceProjects
): GeneratorOptions {
let npmScope = options.npmScope;
if (npmScope) {
npmScope = names(npmScope).fileName;
} else if (projects.libs.length > 0) {
// try get the scope from any library that have one
for (const lib of projects.libs) {
const packageJsonPath = joinPathFragments(
lib.config.root,
'package.json'
);
if (!tree.exists(packageJsonPath)) {
continue;
}
const { name } = readJson(
tree,
joinPathFragments(lib.config.root, 'package.json')
);
npmScope = detectWorkspaceScope(name);
if (npmScope) {
break;
}
}
}
// use the name (scope if exists) in the root package.json
npmScope =
npmScope || detectWorkspaceScope(readJson(tree, 'package.json').name);
return { ...options, npmScope };
}

View File

@ -45,12 +45,9 @@ export function createNxJson(
options: GeneratorOptions,
defaultProject: string | undefined
): void {
const { npmScope } = options;
const targets = getWorkspaceCommonTargets(tree);
writeJson<NxJsonConfiguration>(tree, 'nx.json', {
...(npmScope ? { npmScope } : {}),
affected: {
defaultBase: options.defaultBase ?? deduceDefaultBase(),
},

View File

@ -1,6 +1,7 @@
import type { Tree } from '@nx/devkit';
import { names, readNxJson, readProjectConfiguration } from '@nx/devkit';
import type { AngularProjectConfiguration } from '../../utils/types';
import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope';
export function normalizeDirectory(
appName: string,
@ -60,6 +61,6 @@ export function getProjectPrefix(
): string | undefined {
return (
(readProjectConfiguration(tree, project) as AngularProjectConfiguration)
.prefix ?? readNxJson(tree).npmScope
.prefix ?? getNpmScope(tree)
);
}

View File

@ -1,5 +1,7 @@
import type { Tree } from '@nx/devkit';
import { names, readNxJson } from '@nx/devkit';
import { names } from '@nx/devkit';
import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope';
export function buildSelector(
tree: Tree,
@ -9,7 +11,7 @@ export function buildSelector(
casing: keyof Pick<ReturnType<typeof names>, 'fileName' | 'propertyName'>
): string {
let selector = name;
prefix ??= projectPrefix ?? readNxJson(tree)?.npmScope;
prefix ??= projectPrefix ?? getNpmScope(tree);
if (prefix) {
selector = `${prefix}-${selector}`;
}

View File

@ -182,12 +182,7 @@ export { stripIndents } from 'nx/src/utils/strip-indents';
/**
* @category Utils
*/
export {
joinPathFragments,
normalizePath,
getImportPath,
detectWorkspaceScope,
} from 'nx/src/utils/path';
export { joinPathFragments, normalizePath } from 'nx/src/utils/path';
// TODO(v16): Change this to export from 'nx/src/utils/workspace-root'
/**

View File

@ -18,6 +18,9 @@ export function getWorkspaceLayout(tree: Tree): {
appsDir: string;
libsDir: string;
standaloneAsDefault: boolean;
/**
* @deprecated This will be removed in Nx 17. Use {@link getNpmScope} instead.
*/
npmScope: string;
} {
const nxJson = readNxJson(tree);

View File

@ -2,14 +2,14 @@ import type { Tree } from '@nx/devkit';
import {
convertNxGenerator,
formatFiles,
getImportPath,
getWorkspaceLayout,
joinPathFragments,
readProjectConfiguration,
updateProjectConfiguration,
writeJson,
} from '@nx/devkit';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { esbuildInitGenerator } from '../init/init';
import { EsBuildExecutorOptions } from '../../executors/esbuild/schema';
import { EsBuildProjectSchema } from './schema';
@ -43,9 +43,8 @@ function addBuildTarget(tree: Tree, options: EsBuildProjectSchema) {
const packageJsonPath = joinPathFragments(project.root, 'package.json');
if (!tree.exists(packageJsonPath)) {
const { npmScope } = getWorkspaceLayout(tree);
const importPath =
options.importPath || getImportPath(npmScope, options.project);
options.importPath || getImportPath(tree, options.project);
writeJson(tree, packageJsonPath, {
name: importPath,
version: '0.0.1',

View File

@ -1,10 +1,5 @@
import {
getImportPath,
getWorkspaceLayout,
joinPathFragments,
names,
Tree,
} from '@nx/devkit';
import { getWorkspaceLayout, joinPathFragments, names, Tree } from '@nx/devkit';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { Schema } from '../schema';
export interface NormalizedSchema extends Schema {
@ -28,7 +23,7 @@ export function normalizeOptions(
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
const fileName = projectName;
const { libsDir, npmScope } = getWorkspaceLayout(host);
const { libsDir } = getWorkspaceLayout(host);
const projectRoot = joinPathFragments(libsDir, projectDirectory);
const parsedTags = options.tags
@ -36,7 +31,7 @@ export function normalizeOptions(
: [];
const importPath =
options.importPath || getImportPath(npmScope, projectDirectory);
options.importPath || getImportPath(host, projectDirectory);
const appMain = options.js ? 'src/index.js' : 'src/index.ts';

View File

@ -18,7 +18,6 @@ import {
updateJson,
writeJson,
} from '@nx/devkit';
import { getImportPath } from 'nx/src/utils/path';
import {
addTsConfigPath,
@ -29,6 +28,7 @@ import { addMinimalPublishScript } from '../../utils/minimal-publish-script';
import { Bundler, LibraryGeneratorSchema } from '../../utils/schema';
import { addSwcConfig } from '../../utils/swc/add-swc-config';
import { addSwcDependencies } from '../../utils/swc/add-swc-dependencies';
import { getImportPath } from '../../utils/get-import-path';
import {
esbuildVersion,
nxVersion,
@ -491,8 +491,6 @@ function normalizeOptions(
pascalCaseFiles: options.pascalCaseFiles,
});
const { npmScope } = getWorkspaceLayout(tree);
const projectRoot = joinPathFragments(destinationDir, projectDirectory);
const parsedTags = options.tags
@ -500,7 +498,7 @@ function normalizeOptions(
: [];
const importPath =
options.importPath || getImportPath(npmScope, projectDirectory);
options.importPath || getImportPath(tree, projectDirectory);
options.minimal ??= false;

View File

@ -0,0 +1,25 @@
import { getImportPath } from './get-import-path';
import { Tree, writeJson } from '@nx/devkit';
import { createTree } from '@nx/devkit/testing-pre16';
describe('getImportPath', () => {
let tree: Tree;
beforeEach(() => {
tree = createTree();
});
it('should use the npmScope if it is set to anything other than @', () => {
writeJson(tree, 'package.json', {
name: '@myorg/source',
});
expect(getImportPath(tree, 'my-package')).toEqual('@myorg/my-package');
});
it('should just use the package name if npmScope is empty', () => {
writeJson(tree, 'package.json', {
name: 'source',
});
expect(getImportPath(tree, 'my-package')).toEqual('my-package');
});
});

View File

@ -0,0 +1,12 @@
import { Tree } from '@nx/devkit';
import { getNpmScope } from './package-json/get-npm-scope';
/**
* Prefixes project name with npm scope
*/
export function getImportPath(tree: Tree, projectDirectory: string): string {
const npmScope = getNpmScope(tree);
return npmScope
? `${npmScope === '@' ? '' : '@'}${npmScope}/${projectDirectory}`
: projectDirectory;
}

View File

@ -0,0 +1,19 @@
import { Tree, readNxJson, readJson } from '@nx/devkit';
/**
* Read the npm scope that a workspace should use by default
*/
export function getNpmScope(tree: Tree): string | undefined {
const nxJson = readNxJson(tree);
// TODO(v17): Remove reading this from nx.json
if (nxJson?.npmScope) {
return nxJson.npmScope;
}
const { name } = readJson<{ name?: string }>(tree, 'package.json');
if (name?.startsWith('@')) {
return name.split('/')[0].substring(1);
}
}

View File

@ -8,6 +8,7 @@ import {
Tree,
} from '@nx/devkit';
import type { LibraryGeneratorOptions, NormalizedOptions } from '../schema';
import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope';
export function normalizeOptions(
tree: Tree,
@ -16,7 +17,7 @@ export function normalizeOptions(
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
options.directory
);
const { libsDir: defaultLibsDir, npmScope } = getWorkspaceLayout(tree);
const { libsDir: defaultLibsDir } = getWorkspaceLayout(tree);
const libsDir = layoutDirectory ?? defaultLibsDir;
const name = names(options.name).fileName;
const fullProjectDirectory = projectDirectory
@ -39,7 +40,7 @@ export function normalizeOptions(
global: options.global ?? false,
linter: options.linter ?? Linter.EsLint,
parsedTags,
prefix: npmScope, // we could also allow customizing this
prefix: getNpmScope(tree), // we could also allow customizing this
projectDirectory: fullProjectDirectory,
projectName,
projectRoot,

View File

@ -1,10 +1,5 @@
import {
getImportPath,
getWorkspaceLayout,
joinPathFragments,
names,
Tree,
} from '@nx/devkit';
import { getWorkspaceLayout, joinPathFragments, names, Tree } from '@nx/devkit';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { Schema } from '../schema';
export interface NormalizedSchema extends Schema {
@ -23,10 +18,9 @@ export function normalizeOptions(
const { libsDir } = getWorkspaceLayout(host);
const projectRoot = joinPathFragments(libsDir, projectDirectory);
const { npmScope } = getWorkspaceLayout(host);
return {
...options,
importPath: options.importPath ?? getImportPath(npmScope, projectDirectory),
importPath: options.importPath ?? getImportPath(host, projectDirectory),
projectRoot,
};
}

View File

@ -15,7 +15,6 @@ import {
updateProjectConfiguration,
updateTsConfigsToJs,
} from '@nx/devkit';
import { getImportPath } from 'nx/src/utils/path';
import { Schema } from './schema';
import { libraryGenerator as jsLibraryGenerator } from '@nx/js';
@ -23,10 +22,10 @@ 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 { initGenerator } from '../init/init';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
export interface NormalizedSchema extends Schema {
name: string;
prefix: string;
fileName: string;
projectRoot: string;
projectDirectory: string;
@ -99,11 +98,10 @@ function normalizeOptions(tree: Tree, options: Schema): NormalizedSchema {
: [];
const importPath =
options.importPath || getImportPath(npmScope, fullProjectDirectory);
options.importPath || getImportPath(tree, fullProjectDirectory);
return {
...options,
prefix: npmScope, // we could also allow customizing this
fileName,
name: projectName,
projectRoot,

View File

@ -21,7 +21,8 @@
},
"npmScope": {
"type": "string",
"description": "NPM Scope that the workspace uses."
"description": "NPM Scope that the workspace uses.",
"x-deprecated": "This is inferred from the package.json in the workspace root instead."
},
"tasksRunnerOptions": {
"type": "object",

View File

@ -423,6 +423,7 @@ export async function workspaceGenerators(args: Arguments) {
});
const nxJson: NxJsonConfiguration = readNxJson();
const collection = nxJson.npmScope
? `@${nxJson.npmScope}/workspace-plugin`
: 'workspace-plugin';

View File

@ -68,6 +68,7 @@ export interface NxJsonConfiguration<T = '*' | string[]> {
*/
targetDefaults?: TargetDefaults;
/**
* @deprecated This is inferred from the package.json in the workspace root. Please use {@link getNpmScope} instead.
* NPM Scope that the workspace uses
*/
npmScope?: string;

View File

@ -177,12 +177,7 @@ export { stripIndents } from './utils/strip-indents';
/**
* @category Utils
*/
export {
joinPathFragments,
normalizePath,
getImportPath,
detectWorkspaceScope,
} from './utils/path';
export { joinPathFragments, normalizePath } from './utils/path';
// TODO(v16): Change this to export from './utils/workspace-root'
/**

View File

@ -11,6 +11,7 @@ import { NxJsonConfiguration } from '../config/nx-json';
import { Task } from '../config/task-graph';
import { InputDefinition } from '../config/workspace-json-project-json';
import { hashTsConfig } from '../plugins/js/hasher/hasher';
import { createProjectRootMappings } from '../project-graph/utils/find-project-for-path';
type ExpandedSelfInput =
| { fileset: string }
@ -181,6 +182,9 @@ class TaskHasher {
[runtime: string]: Promise<PartialHash>;
} = {};
private externalDepsHashCache: { [packageName: string]: PartialHash } = {};
private projectRootMappings = createProjectRootMappings(
this.projectGraph.nodes
);
constructor(
private readonly nxJson: NxJsonConfiguration,
@ -584,7 +588,7 @@ class TaskHasher {
...fileNames,
...values,
JSON.stringify({ ...p.data, files: undefined }),
hashTsConfig(p, this.nxJson, this.options),
hashTsConfig(p, this.projectRootMappings, this.options),
]);
res({
value,

View File

@ -1,8 +1,10 @@
import { getImportPath } from '../../../utils/path';
import { ProjectGraphProjectNode } from '../../../config/project-graph';
import { readJsonFile } from '../../../utils/fileutils';
import { getRootTsConfigFileName } from '../utils/typescript';
import { NxJsonConfiguration } from '../../../config/nx-json';
import {
findProjectForPath,
ProjectRootMappings,
} from '../../../project-graph/utils/find-project-for-path';
interface CompilerOptions {
paths: Record<string, string[]>;
@ -28,14 +30,14 @@ let tsConfigJson: TsconfigJsonConfiguration;
export function hashTsConfig(
p: ProjectGraphProjectNode,
nxJson: NxJsonConfiguration,
projectRootMappings: ProjectRootMappings,
{ selectivelyHashTsConfig }: { selectivelyHashTsConfig: boolean }
) {
if (!tsConfigJson) {
tsConfigJson = readTsConfigJson();
}
if (selectivelyHashTsConfig) {
return removeOtherProjectsPathRecords(p, tsConfigJson, nxJson);
return removeOtherProjectsPathRecords(p, tsConfigJson, projectRootMappings);
} else {
return JSON.stringify(tsConfigJson);
}
@ -44,19 +46,28 @@ export function hashTsConfig(
function removeOtherProjectsPathRecords(
p: ProjectGraphProjectNode,
tsConfigJson: TsconfigJsonConfiguration,
nxJson: NxJsonConfiguration
projectRootMapping: ProjectRootMappings
) {
const { paths, ...compilerOptions } = tsConfigJson.compilerOptions;
const rootPath = p.data.root.split('/');
rootPath.shift();
const pathAlias = getImportPath(nxJson?.npmScope, rootPath.join('/'));
const filteredPaths: Record<string, string[]> = {};
if (!paths) {
return '';
}
for (const [key, files] of Object.entries(paths)) {
for (const filePath of files) {
if (p.name === findProjectForPath(filePath, projectRootMapping)) {
filteredPaths[key] = files;
break;
}
}
}
return JSON.stringify({
compilerOptions: {
...compilerOptions,
paths: {
[pathAlias]: paths[pathAlias] ?? [],
},
paths: filteredPaths,
},
});
}

View File

@ -6,7 +6,7 @@ import {
ProjectGraph,
} from '../../../../config/project-graph';
import { parseJson } from '../../../../utils/json';
import { getImportPath, joinPathFragments } from '../../../../utils/path';
import { joinPathFragments } from '../../../../utils/path';
import { ProjectsConfigurations } from '../../../../config/workspace-json-project-json';
import { NxJsonConfiguration } from '../../../../config/nx-json';
import { ExplicitDependency } from './explicit-project-dependencies';
@ -56,9 +56,13 @@ function createPackageNameMap(
)
)
);
// TODO(v17): Stop reading nx.json for the npmScope
const npmScope = nxJsonConfiguration.npmScope;
res[
packageJson.name ??
getImportPath(nxJsonConfiguration.npmScope, projectName)
(npmScope
? `${npmScope === '@' ? '' : '@'}${npmScope}/${projectName}`
: projectName)
] = projectName;
} catch (e) {}
}

View File

@ -1,4 +1,4 @@
import { getImportPath, joinPathFragments, normalizePath } from './path';
import { joinPathFragments, normalizePath } from './path';
describe('normalizePath', () => {
it('should remove drive letters', () => {
@ -21,17 +21,3 @@ describe('joinPathFragments', () => {
);
});
});
describe('getImportPath', () => {
it('should use the npmScope if it is set to anything other than @', () => {
expect(getImportPath('myorg', 'my-package')).toEqual('@myorg/my-package');
});
it('should allow for a single @ to be used as the npmScope', () => {
expect(getImportPath('@', 'my-package')).toEqual('@/my-package');
});
it('should just use the package name if npmScope is empty', () => {
expect(getImportPath('', 'my-package')).toEqual('my-package');
});
});

View File

@ -17,26 +17,3 @@ export function normalizePath(osSpecificPath: string): string {
export function joinPathFragments(...fragments: string[]): string {
return normalizePath(path.join(...fragments));
}
/**
* Detect workspace scope from the package.json name
* @param packageName
* @returns
*/
export function detectWorkspaceScope(packageName: string): string {
return packageName?.startsWith('@')
? packageName.substring(1).split('/')[0]
: '';
}
/**
* Prefixes project name with npm scope
*/
export function getImportPath(
npmScope: string,
projectDirectory: string
): string {
return npmScope
? `${npmScope === '@' ? '' : '@'}${npmScope}/${projectDirectory}`
: projectDirectory;
}

View File

@ -1,12 +1,12 @@
import {
extractLayoutDirectory,
getImportPath,
getWorkspaceLayout,
joinPathFragments,
names,
Tree,
} from '@nx/devkit';
import { Schema } from '../schema';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
export interface NormalizedSchema extends Schema {
name: string;
@ -15,7 +15,6 @@ export interface NormalizedSchema extends Schema {
projectRoot: string;
projectDirectory: string;
parsedTags: string[];
npmScope: string;
npmPackageName: string;
bundler: 'swc' | 'tsc';
publishable: boolean;
@ -27,7 +26,7 @@ export function normalizeOptions(
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
options.directory
);
const { npmScope, libsDir: defaultLibsDir } = getWorkspaceLayout(host);
const { libsDir: defaultLibsDir } = getWorkspaceLayout(host);
const libsDir = layoutDirectory ?? defaultLibsDir;
const name = names(options.name).fileName;
const fullProjectDirectory = projectDirectory
@ -48,13 +47,12 @@ export function normalizeOptions(
? options.tags.split(',').map((s) => s.trim())
: [];
const npmPackageName = options.importPath || getImportPath(npmScope, name);
const npmPackageName = options.importPath || getImportPath(host, name);
return {
...options,
bundler: options.compiler ?? 'tsc',
fileName,
npmScope,
libsDir,
name: projectName,
projectRoot,

View File

@ -1,10 +1,5 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import {
Tree,
readProjectConfiguration,
readJson,
readNxJson,
} from '@nx/devkit';
import { Tree, readProjectConfiguration, readJson } from '@nx/devkit';
import generator from './generator';
import { PackageJson } from 'nx/src/utils/package-json';
@ -24,6 +19,6 @@ describe('preset generator', () => {
expect(config).toBeDefined();
const packageJson = readJson<PackageJson>(tree, 'package.json');
expect(packageJson.dependencies).toHaveProperty('@nx/devkit');
expect(readNxJson(tree).npmScope).not.toBeDefined();
expect(readJson(tree, 'nx.json').npmScope).not.toBeDefined();
});
});

View File

@ -1,5 +1,5 @@
import { getWorkspaceLayout, joinPathFragments, names, Tree } from '@nx/devkit';
import { getImportPath } from 'nx/src/utils/path';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { Schema } from '../schema';
export interface NormalizedSchema extends Schema {
@ -24,7 +24,7 @@ export function normalizeOptions(
const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
const fileName = projectName;
const { libsDir, npmScope } = getWorkspaceLayout(host);
const { libsDir } = getWorkspaceLayout(host);
const projectRoot = joinPathFragments(libsDir, projectDirectory);
const parsedTags = options.tags
@ -32,7 +32,7 @@ export function normalizeOptions(
: [];
const importPath =
options.importPath || getImportPath(npmScope, projectDirectory);
options.importPath || getImportPath(host, projectDirectory);
const normalized: NormalizedSchema = {
...options,

View File

@ -1,6 +1,5 @@
import {
extractLayoutDirectory,
getImportPath,
getProjects,
getWorkspaceLayout,
joinPathFragments,
@ -9,6 +8,8 @@ import {
normalizePath,
Tree,
} from '@nx/devkit';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { assertValidStyle } from '../../../utils/assertion';
import { NormalizedSchema, Schema } from '../schema';
@ -26,7 +27,7 @@ export function normalizeOptions(
const projectName = fullProjectDirectory.replace(new RegExp('/', 'g'), '-');
const fileName = projectName;
const { libsDir: defaultLibsDir, npmScope } = getWorkspaceLayout(host);
const { libsDir: defaultLibsDir } = getWorkspaceLayout(host);
const libsDir = layoutDirectory ?? defaultLibsDir;
const projectRoot = joinPathFragments(libsDir, fullProjectDirectory);
@ -35,7 +36,7 @@ export function normalizeOptions(
: [];
const importPath =
options.importPath || getImportPath(npmScope, fullProjectDirectory);
options.importPath || getImportPath(host, fullProjectDirectory);
let bundler = options.bundler ?? 'none';

View File

@ -1,11 +1,10 @@
import {
addDependenciesToPackageJson,
applyChangesToString,
getWorkspaceLayout,
joinPathFragments,
names,
Tree,
} from '@nx/devkit';
import { Tree } from 'nx/src/generators/tree';
import { getImportPath, joinPathFragments } from 'nx/src/utils/path';
import type * as ts from 'typescript';
import { NormalizedSchema } from '../schema';
@ -21,6 +20,7 @@ import {
typesReactRouterDomVersion,
} from '../../../utils/versions';
import { ensureTypescript } from '@nx/js/src/utils/typescript/ensure-typescript';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
let tsModule: typeof import('typescript');
@ -78,13 +78,12 @@ export function updateAppRoutes(host: Tree, options: NormalizedSchema) {
{
const { content: componentContent, source: componentSource } =
readComponent(host, appComponentPath);
const { npmScope } = getWorkspaceLayout(host);
const changes = applyChangesToString(
componentContent,
addRoute(appComponentPath, componentSource, {
routePath: options.routePath,
componentName: names(options.name).className,
moduleName: getImportPath(npmScope, options.projectDirectory),
moduleName: getImportPath(host, options.projectDirectory),
})
);
host.write(appComponentPath, changes);

View File

@ -2,13 +2,12 @@ import type { Tree } from '@nx/devkit';
import {
convertNxGenerator,
formatFiles,
getImportPath,
getWorkspaceLayout,
joinPathFragments,
readProjectConfiguration,
updateProjectConfiguration,
writeJson,
} from '@nx/devkit';
import { getImportPath } from '@nx/js/src/utils/get-import-path';
import { rollupInitGenerator } from '../init/init';
import { RollupExecutorOptions } from '../../executors/rollup/schema';
@ -43,9 +42,8 @@ function addBuildTarget(tree: Tree, options: RollupProjectSchema) {
const packageJsonPath = joinPathFragments(project.root, 'package.json');
if (!tree.exists(packageJsonPath)) {
const { npmScope } = getWorkspaceLayout(tree);
const importPath =
options.importPath || getImportPath(npmScope, options.project);
options.importPath || getImportPath(tree, options.project);
writeJson(tree, packageJsonPath, {
name: importPath,
version: '0.0.1',

View File

@ -1,7 +1,7 @@
import { getWorkspaceLayout, ProjectConfiguration, Tree } from '@nx/devkit';
import { getImportPath } from 'nx/src/utils/path';
import { ProjectConfiguration, Tree } from '@nx/devkit';
import type { NormalizedSchema, Schema } from '../schema';
import { getDestination, getNewProjectName, normalizeSlashes } from './utils';
import { getImportPath } from '../../../utilities/get-import-path';
export function normalizeSchema(
tree: Tree,
@ -13,14 +13,12 @@ export function normalizeSchema(
: schema.destination;
const newProjectName =
schema.newProjectName ?? getNewProjectName(destination);
const { npmScope } = getWorkspaceLayout(tree);
return {
...schema,
destination,
importPath:
schema.importPath ??
normalizeSlashes(getImportPath(npmScope, destination)),
schema.importPath ?? normalizeSlashes(getImportPath(tree, destination)),
newProjectName,
relativeToRootDestination: getDestination(
tree,

View File

@ -10,7 +10,6 @@ import {
visitNotIgnoredFiles,
writeJson,
readJson,
getImportPath,
} from '@nx/devkit';
import type * as ts from 'typescript';
import {
@ -21,6 +20,7 @@ import { NormalizedSchema } from '../schema';
import { normalizeSlashes } from './utils';
import { relative } from 'path';
import { ensureTypescript } from '../../../utilities/typescript';
import { getImportPath } from '../../../utilities/get-import-path';
let tsModule: typeof import('typescript');
@ -62,7 +62,7 @@ export function updateImports(
fromPath ||
normalizeSlashes(
getImportPath(
npmScope,
tree,
project.root.slice(libsDir.length).replace(/^\/|\\/, '')
)
),

View File

@ -8,7 +8,7 @@ exports[`new --preset should generate necessary npm dependencies for empty prese
"nx": "0.0.1",
},
"license": "MIT",
"name": "my-workspace",
"name": "@my-workspace/source",
"private": true,
"scripts": {},
"version": "0.0.0",
@ -28,7 +28,6 @@ exports[`new should generate an empty nx.json 1`] = `
],
"sharedGlobals": [],
},
"npmScope": "npmScope",
"targetDefaults": {
"build": {
"dependsOn": [

View File

@ -1,5 +1,5 @@
{
"name": "<%= formattedNames.fileName %>",
"name": "@<%= formattedNames.fileName %>/source",
"version": "0.0.0",
"license": "MIT",
"scripts": {

View File

@ -1,5 +1,5 @@
{
"name": "<%= formattedNames.fileName %>",
"name": "@<%= formattedNames.fileName %>/source",
"version": "0.0.0",
"license": "MIT",
"scripts": {

View File

@ -72,7 +72,6 @@ export function generatePreset(host: Tree, opts: NormalizedSchema) {
`--name=${opts.appName}`,
opts.style ? `--style=${opts.style}` : null,
opts.linter ? `--linter=${opts.linter}` : null,
opts.npmScope ? `--npmScope=${opts.npmScope}` : `--npmScope=${opts.name}`,
opts.preset ? `--preset=${opts.preset}` : null,
opts.bundler ? `--bundler=${opts.bundler}` : null,
opts.framework ? `--framework=${opts.framework}` : null,

View File

@ -85,7 +85,6 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
expect(nxJson).toMatchInlineSnapshot(`
{
"$schema": "./node_modules/nx/schemas/nx-schema.json",
"npmScope": "proj",
"targetDefaults": {
"build": {
"dependsOn": [
@ -134,7 +133,6 @@ describe('@nx/workspace:generateWorkspaceFiles', () => {
],
"sharedGlobals": [],
},
"npmScope": "proj",
"targetDefaults": {
"build": {
"dependsOn": [

View File

@ -50,7 +50,6 @@ function setPresetProperty(tree: Tree, options: NormalizedSchema) {
delete json.implicitDependencies;
delete json.targetDefaults;
delete json.workspaceLayout;
delete json.npmScope;
}
return json;
});
@ -79,11 +78,10 @@ function createAppsAndLibsFolders(tree: Tree, options: NormalizedSchema) {
function createNxJson(
tree: Tree,
{ directory, npmScope, packageManager, defaultBase, preset }: NormalizedSchema
{ directory, defaultBase, preset }: NormalizedSchema
) {
const nxJson: NxJsonConfiguration & { $schema: string } = {
$schema: './node_modules/nx/schemas/nx-schema.json',
npmScope: npmScope,
affected: {
defaultBase,
},
@ -209,7 +207,6 @@ function normalizeOptions(options: NormalizedSchema) {
const name = names(options.name).fileName;
return {
name,
npmScope: name,
...options,
defaultBase,
};

View File

@ -39,7 +39,6 @@ describe('new', () => {
...defaultOptions,
name: 'my-workspace',
directory: 'my-workspace',
npmScope: 'npmScope',
appName: 'app',
});
expect(readJson(tree, 'my-workspace/nx.json')).toMatchSnapshot();
@ -51,7 +50,6 @@ describe('new', () => {
...defaultOptions,
name: 'my-workspace',
directory: 'my-workspace',
npmScope: 'npmScope',
appName: 'app',
preset: Preset.Empty,
});
@ -64,7 +62,6 @@ describe('new', () => {
...defaultOptions,
name: 'my-workspace',
directory: 'my-workspace',
npmScope: 'npmScope',
appName: 'app',
preset: Preset.ReactMonorepo,
bundler: 'vite',
@ -85,7 +82,6 @@ describe('new', () => {
...defaultOptions,
name: 'my-workspace',
directory: 'my-workspace',
npmScope: 'npmScope',
appName: 'app',
preset: Preset.AngularMonorepo,
});
@ -140,7 +136,6 @@ describe('new', () => {
...defaultOptions,
name: 'my-workspace',
directory: 'my-workspace',
npmScope: 'npmScope',
appName: 'app',
preset,
});
@ -177,7 +172,6 @@ describe('new', () => {
...defaultOptions,
name: 'my-workspace',
directory: 'my-workspace',
npmScope: 'npmScope',
appName: 'app',
});
@ -193,7 +187,6 @@ describe('new', () => {
...defaultOptions,
name: 'my-workspace',
directory: 'my-workspace',
npmScope: 'npmScope',
appName: 'app',
});
fail('Generating into a non-empty directory should error.');

View File

@ -16,7 +16,6 @@ interface Schema {
directory: string;
name: string;
appName?: string;
npmScope?: string;
skipInstall?: boolean;
style?: string;
nxCloud?: boolean;

View File

@ -25,10 +25,6 @@
"type": "boolean",
"default": true
},
"npmScope": {
"type": "string",
"description": "Npm scope for importing libs."
},
"standaloneApi": {
"description": "Use Standalone Components if generating an Angular application.",
"type": "boolean",

View File

@ -9,7 +9,7 @@ import {
writeJson,
} from '@nx/devkit';
import { join } from 'path';
import { getImportPath } from 'nx/src/utils/path';
import { getImportPath } from '../../utilities/get-import-path';
export interface ProjectOptions {
name: string;
@ -20,15 +20,10 @@ function normalizeOptions(options: ProjectOptions): ProjectOptions {
return options;
}
function addFiles(
projectRoot: string,
tree: Tree,
npmScope: string,
options: ProjectOptions
) {
function addFiles(projectRoot: string, tree: Tree, options: ProjectOptions) {
const packageJsonPath = join(projectRoot, 'package.json');
writeJson(tree, packageJsonPath, {
name: getImportPath(npmScope, options.name),
name: getImportPath(tree, options.name),
version: '0.0.0',
scripts: {
test: 'node index.js',
@ -41,7 +36,7 @@ function addFiles(
export async function npmPackageGenerator(tree: Tree, options: ProjectOptions) {
options = normalizeOptions(options);
const { libsDir, npmScope } = getWorkspaceLayout(tree);
const { libsDir } = getWorkspaceLayout(tree);
const projectRoot = join(libsDir, options.name);
addProjectConfiguration(tree, options.name, {
@ -53,7 +48,7 @@ export async function npmPackageGenerator(tree: Tree, options: ProjectOptions) {
const isEmpty = fileCount === 0 || (fileCount === 1 && projectJsonExists);
if (isEmpty) {
addFiles(projectRoot, tree, npmScope, options);
addFiles(projectRoot, tree, options);
}
await formatFiles(tree);

View File

@ -3,7 +3,6 @@ import { PackageManager } from '@nx/devkit';
export interface Schema {
name: string;
npmScope?: string;
style?: string;
linter?: string;
preset: Preset;

View File

@ -14,10 +14,6 @@
"description": "The name of the application.",
"type": "string"
},
"npmScope": {
"description": "Npm scope for importing libs.",
"type": "string"
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",

View File

@ -0,0 +1,25 @@
import { Tree } from 'nx/src/generators/tree';
import { readNxJson } from 'nx/src/generators/utils/nx-json';
import { readJson } from 'nx/src/generators/utils/json';
export function getImportPath(tree: Tree, projectDirectory: string): string {
const npmScope = getNpmScope(tree);
return npmScope
? `${npmScope === '@' ? '' : '@'}${npmScope}/${projectDirectory}`
: projectDirectory;
}
function getNpmScope(tree: Tree) {
const nxJson = readNxJson(tree);
// TODO(v17): Remove reading this from nx.json
if (nxJson.npmScope) {
return nxJson.npmScope;
}
const { name } = readJson<{ name?: string }>(tree, 'package.json');
if (name?.startsWith('@')) {
return name.split('/')[0].substring(1);
}
}