Skip to content

Commit

Permalink
feat(core): make npmScope optional (#10018)
Browse files Browse the repository at this point in the history
  • Loading branch information
meeroslav committed Jun 23, 2022
1 parent 251af50 commit 62bae5a
Show file tree
Hide file tree
Showing 26 changed files with 261 additions and 73 deletions.
39 changes: 39 additions & 0 deletions docs/generated/devkit/index.md
Expand Up @@ -135,8 +135,10 @@ It only uses language primitives and immutable objects
- [createProjectGraphAsync](../../devkit/index#createprojectgraphasync)
- [defaultTasksRunner](../../devkit/index#defaulttasksrunner)
- [detectPackageManager](../../devkit/index#detectpackagemanager)
- [detectWorkspaceScope](../../devkit/index#detectworkspacescope)
- [formatFiles](../../devkit/index#formatfiles)
- [generateFiles](../../devkit/index#generatefiles)
- [getImportPath](../../devkit/index#getimportpath)
- [getOutputsForTargetAndConfiguration](../../devkit/index#getoutputsfortargetandconfiguration)
- [getPackageManagerCommand](../../devkit/index#getpackagemanagercommand)
- [getPackageManagerVersion](../../devkit/index#getpackagemanagerversion)
Expand Down Expand Up @@ -971,6 +973,24 @@ 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`

---

### formatFiles

**formatFiles**(`tree`): `Promise`<`void`\>
Expand Down Expand Up @@ -1030,6 +1050,25 @@ 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`

---

### getOutputsForTargetAndConfiguration

**getOutputsForTargetAndConfiguration**(`task`, `node`): `any`
Expand Down
2 changes: 1 addition & 1 deletion docs/generated/packages/devkit.json

Large diffs are not rendered by default.

115 changes: 115 additions & 0 deletions e2e/nx-misc/src/workspace.test.ts
Expand Up @@ -115,6 +115,7 @@ describe('Workspace Tests', () => {
expect(result).toContain('Hello World');
});
});

describe('workspace-generator', () => {
let custom: string;
let failing: string;
Expand Down Expand Up @@ -679,6 +680,120 @@ describe('Workspace Tests', () => {
delete nxJson.workspaceLayout;
updateFile('nx.json', JSON.stringify(nxJson));
});

it('should work for libraries when scope is unset', () => {
const json = readJson('nx.json');
delete json.npmScope;
updateFile('nx.json', JSON.stringify(json));

const lib1 = uniq('mylib');
const lib2 = uniq('mylib');
const lib3 = uniq('mylib');
runCLI(`generate @nrwl/workspace:lib ${lib1}/data-access`);
let rootTsConfig = readJson('tsconfig.base.json');
expect(
rootTsConfig.compilerOptions.paths[`@${proj}/${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[`${lib1}/data-access`]
).toBeDefined();

updateFile(
`libs/${lib1}/data-access/src/lib/${lib1}-data-access.ts`,
`export function fromLibOne() { console.log('This is completely pointless'); }`
);

updateFile(
`libs/${lib1}/data-access/src/index.ts`,
`export * from './lib/${lib1}-data-access.ts'`
);

/**
* Create a library which imports a class from lib1
*/

runCLI(`generate @nrwl/workspace:lib ${lib2}/ui`);

updateFile(
`libs/${lib2}/ui/src/lib/${lib2}-ui.ts`,
`import { fromLibOne } from '${lib1}/data-access';
export const fromLibTwo = () => fromLibOne();`
);

/**
* Create a library which has an implicit dependency on lib1
*/

runCLI(`generate @nrwl/workspace:lib ${lib3}`);
updateProjectConfig(lib3, (config) => {
config.implicitDependencies = [`${lib1}-data-access`];
return config;
});

/**
* Now try to move lib1
*/

const moveOutput = runCLI(
`generate @nrwl/workspace:move --project ${lib1}-data-access shared/${lib1}/data-access`
);

expect(moveOutput).toContain(`DELETE libs/${lib1}/data-access`);
expect(exists(`libs/${lib1}/data-access`)).toBeFalsy();

const newPath = `libs/shared/${lib1}/data-access`;
const newName = `shared-${lib1}-data-access`;

const readmePath = `${newPath}/README.md`;
expect(moveOutput).toContain(`CREATE ${readmePath}`);
checkFilesExist(readmePath);

const indexPath = `${newPath}/src/index.ts`;
expect(moveOutput).toContain(`CREATE ${indexPath}`);
checkFilesExist(indexPath);

const rootClassPath = `${newPath}/src/lib/${lib1}-data-access.ts`;
expect(moveOutput).toContain(`CREATE ${rootClassPath}`);
checkFilesExist(rootClassPath);

const newConfig = readProjectConfig(newName);
expect(newConfig).toMatchObject({
tags: [],
});
const lib3Config = readProjectConfig(lib3);
expect(lib3Config.implicitDependencies).toEqual([
`shared-${lib1}-data-access`,
]);

expect(moveOutput).toContain('UPDATE tsconfig.base.json');
rootTsConfig = readJson('tsconfig.base.json');
expect(
rootTsConfig.compilerOptions.paths[`${lib1}/data-access`]
).toBeUndefined();
expect(
rootTsConfig.compilerOptions.paths[`shared-${lib1}-data-access`]
).toEqual([`libs/shared/${lib1}/data-access/src/index.ts`]);

expect(moveOutput).toContain(`UPDATE workspace.json`);
const workspaceJson = readJson(workspaceConfigName());
expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined();
const project = readProjectConfig(newName);
expect(project).toBeTruthy();
expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`,
]);

/**
* Check that the import in lib2 has been updated
*/
const lib2FilePath = `libs/${lib2}/ui/src/lib/${lib2}-ui.ts`;
const lib2File = readFile(lib2FilePath);
expect(lib2File).toContain(
`import { fromLibOne } from 'shared-${lib1}-data-access';`
);
});
});

describe('remove project', () => {
Expand Down
7 changes: 3 additions & 4 deletions e2e/utils/index.ts
Expand Up @@ -22,13 +22,12 @@ import {
} from 'fs-extra';
import * as path from 'path';
import { join } from 'path';
import { coerce } from 'semver';
import { check as portCheck } from 'tcp-port-used';
import { dirSync } from 'tmp';
import { promisify } from 'util';
import chalk = require('chalk');
import isCI = require('is-ci');
import treeKill = require('tree-kill');
import * as chalk from 'chalk';
import * as isCI from 'is-ci';
import * as treeKill from 'tree-kill';
import { Workspaces } from '../../packages/nx/src/config/workspaces';
import { PackageManager } from 'nx/src/utils/package-manager';

Expand Down
Expand Up @@ -5,6 +5,7 @@ import {
readJson,
Tree,
} from '@nrwl/devkit';
import { getImportPath } from 'nx/src/utils/path';
import { Schema } from '../schema';
import { NormalizedSchema } from './normalized-schema';
import { names } from '@nrwl/devkit';
Expand Down Expand Up @@ -55,7 +56,8 @@ export function normalizeOptions(

options.standaloneConfig = options.standaloneConfig ?? standaloneAsDefault;

const importPath = options.importPath || `@${npmScope}/${projectDirectory}`;
const importPath =
options.importPath || getImportPath(npmScope, projectDirectory);

// Determine the roots where @schematics/angular will place the projects
// This might not be where the projects actually end up
Expand Down
Expand Up @@ -12,7 +12,6 @@ Object {
"devDependencies": "*",
},
},
"npmScope": "my-scope",
"targetDefaults": Object {
"build": Object {
"dependsOn": Array [
Expand Down Expand Up @@ -52,7 +51,6 @@ Object {
"devDependencies": "*",
},
},
"npmScope": "my-scope",
"targetDefaults": Object {
"build": Object {
"dependsOn": Array [
Expand Down
@@ -1,4 +1,10 @@
import { joinPathFragments, names, readJson, Tree } from '@nrwl/devkit';
import {
detectWorkspaceScope,
joinPathFragments,
names,
readJson,
Tree,
} from '@nrwl/devkit';
import { GeneratorOptions } from '../schema';
import { WorkspaceProjects } from './types';

Expand All @@ -25,21 +31,16 @@ export function normalizeOptions(
tree,
joinPathFragments(lib.config.root, 'package.json')
);
if (name.startsWith('@')) {
npmScope = name.split('/')[0].substring(1);
npmScope = detectWorkspaceScope(name);
if (npmScope) {
break;
}
}
}

if (!npmScope) {
// use the name (scope if exists) in the root package.json
const { name } = readJson(tree, 'package.json');

if (name) {
npmScope = name.startsWith('@') ? name.split('/')[0].substring(1) : name;
}
}
// use the name (scope if exists) in the root package.json
npmScope =
npmScope || detectWorkspaceScope(readJson(tree, 'package.json').name);

return { ...options, npmScope };
}
Expand Up @@ -47,9 +47,10 @@ export function createNxJson(
setWorkspaceLayoutAsNewProjectRoot: boolean = false
): void {
const { newProjectRoot = '' } = readJson(tree, 'angular.json');
const { npmScope } = options;

writeJson<NxJsonConfiguration>(tree, 'nx.json', {
npmScope: options.npmScope,
...(npmScope ? { npmScope } : {}),
affected: {
defaultBase: options.defaultBase ?? deduceDefaultBase(),
},
Expand Down
7 changes: 6 additions & 1 deletion packages/devkit/index.ts
Expand Up @@ -272,7 +272,12 @@ export { stripIndents } from 'nx/src/utils/strip-indents';
/**
* @category Utils
*/
export { joinPathFragments, normalizePath } from 'nx/src/utils/path';
export {
joinPathFragments,
normalizePath,
getImportPath,
detectWorkspaceScope,
} from 'nx/src/utils/path';

/**
* @category Utils
Expand Down
3 changes: 1 addition & 2 deletions packages/devkit/src/utils/get-workspace-layout.ts
@@ -1,5 +1,4 @@
import {
getWorkspacePath,
readNxJson,
shouldDefaultToUsingStandaloneConfigs,
} from 'nx/src/generators/utils/project-configuration';
Expand Down Expand Up @@ -28,7 +27,7 @@ export function getWorkspaceLayout(tree: Tree): {
return {
appsDir: nxJson?.workspaceLayout?.appsDir ?? 'apps',
libsDir: nxJson?.workspaceLayout?.libsDir ?? 'libs',
npmScope: nxJson?.npmScope ?? '',
npmScope: nxJson?.npmScope,
standaloneAsDefault: shouldDefaultToUsingStandaloneConfigs(tree),
};
}
5 changes: 3 additions & 2 deletions packages/js/src/generators/library/library.ts
Expand Up @@ -15,6 +15,7 @@ import {
readJson,
writeJson,
} from '@nrwl/devkit';
import { getImportPath } from 'nx/src/utils/path';
import { jestProjectGenerator } from '@nrwl/jest';
import { Linter, lintProjectGenerator } from '@nrwl/linter';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
Expand Down Expand Up @@ -359,8 +360,8 @@ function normalizeOptions(
? options.tags.split(',').map((s) => s.trim())
: [];

const defaultImportPath = `@${npmScope}/${projectDirectory}`;
const importPath = options.importPath || defaultImportPath;
const importPath =
options.importPath || getImportPath(npmScope, projectDirectory);

return {
...options,
Expand Down
7 changes: 3 additions & 4 deletions packages/node/src/generators/library/library.ts
Expand Up @@ -12,7 +12,7 @@ import {
updateProjectConfiguration,
updateTsConfigsToJs,
} from '@nrwl/devkit';

import { getImportPath } from 'nx/src/utils/path';
import { Schema } from './schema';
import { libraryGenerator as workspaceLibraryGenerator } from '@nrwl/workspace/generators';
import { join } from 'path';
Expand Down Expand Up @@ -62,7 +62,6 @@ export const librarySchematic = convertNxGenerator(libraryGenerator);

function normalizeOptions(tree: Tree, options: Schema): NormalizedSchema {
const { npmScope, libsDir } = getWorkspaceLayout(tree);
const defaultPrefix = npmScope;
const name = names(options.name).fileName;
const projectDirectory = options.directory
? `${names(options.directory).fileName}/${name}`
Expand All @@ -80,11 +79,11 @@ function normalizeOptions(tree: Tree, options: Schema): NormalizedSchema {
: [];

const importPath =
options.importPath || `@${defaultPrefix}/${projectDirectory}`;
options.importPath || getImportPath(npmScope, projectDirectory);

return {
...options,
prefix: defaultPrefix, // we could also allow customizing this
prefix: npmScope, // we could also allow customizing this
fileName,
name: projectName,
projectRoot,
Expand Down
12 changes: 2 additions & 10 deletions packages/nx-plugin/src/generators/plugin/utils/normalize-schema.ts
@@ -1,4 +1,5 @@
import {
getImportPath,
getWorkspaceLayout,
joinPathFragments,
names,
Expand Down Expand Up @@ -34,8 +35,7 @@ export function normalizeOptions(
? options.tags.split(',').map((s) => s.trim())
: [];

const npmPackageName =
options.importPath || resolvePackageName(npmScope, name);
const npmPackageName = options.importPath || getImportPath(npmScope, name);

return {
...options,
Expand All @@ -49,11 +49,3 @@ export function normalizeOptions(
npmPackageName,
};
}

function resolvePackageName(npmScope: string, name: string): string {
if (npmScope && npmScope !== '') {
return `@${npmScope}/${name}`;
} else {
return name;
}
}

1 comment on commit 62bae5a

@vercel
Copy link

@vercel vercel bot commented on 62bae5a Jun 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-git-master-nrwl.vercel.app
nx-five.vercel.app
nx.dev
nx-dev-nrwl.vercel.app

Please sign in to comment.