Navigation Menu

Skip to content

Commit

Permalink
feat(angular): update ng-add generator so the migration result is mor…
Browse files Browse the repository at this point in the history
…e aligned with new nx workspaces (#9630)
  • Loading branch information
leosvelperez committed Mar 31, 2022
1 parent 72c0a5b commit 18776f6
Show file tree
Hide file tree
Showing 12 changed files with 217 additions and 126 deletions.
19 changes: 10 additions & 9 deletions docs/generated/api-nx-devkit/index.md
Expand Up @@ -792,9 +792,9 @@ Use this to expose a compatible Angular Builder

### convertNxGenerator

**convertNxGenerator**<`T`\>(`generator`): (`options`: `T`) => (`tree`: `any`, `context`: `any`) => `Promise`<`any`\>
**convertNxGenerator**<`T`\>(`generator`, `skipWritingConfigInOldFormat?`): (`generatorOptions`: `T`) => (`tree`: `any`, `context`: `any`) => `Promise`<`any`\>

Convert an Nx Generator into an Angular Devkit Schematic
Convert an Nx Generator into an Angular Devkit Schematic.

#### Type parameters

Expand All @@ -804,21 +804,22 @@ Convert an Nx Generator into an Angular Devkit Schematic

#### Parameters

| Name | Type |
| :---------- | :--------------------------------------------------- |
| `generator` | [`Generator`](../../nx-devkit/index#generator)<`T`\> |
| Name | Type | Default value | Description |
| :----------------------------- | :--------------------------------------------------- | :------------ | :------------------------------------------------------------------------------------------------ |
| `generator` | [`Generator`](../../nx-devkit/index#generator)<`T`\> | `undefined` | The Nx generator to convert to an Angular Devkit Schematic. |
| `skipWritingConfigInOldFormat` | `boolean` | `false` | Whether to skip writing the configuration in the old format (the one used by the Angular DevKit). |

#### Returns

`fn`

▸ (`options`): (`tree`: `any`, `context`: `any`) => `Promise`<`any`\>
▸ (`generatorOptions`): (`tree`: `any`, `context`: `any`) => `Promise`<`any`\>

##### Parameters

| Name | Type |
| :-------- | :--- |
| `options` | `T` |
| Name | Type |
| :----------------- | :--- |
| `generatorOptions` | `T` |

##### Returns

Expand Down
100 changes: 40 additions & 60 deletions e2e/angular-core/src/ng-add.test.ts
Expand Up @@ -121,28 +121,10 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
expect(updatedPackageJson.description).toEqual('some description');
expect(updatedPackageJson.scripts).toEqual({
ng: 'nx',
start: 'ng serve',
build: 'ng build',
watch: 'ng build --watch --configuration development',
test: 'ng test',
nx: 'nx',
'affected:apps': 'nx affected:apps',
'affected:libs': 'nx affected:libs',
'affected:build': 'nx affected:build',
'affected:e2e': 'nx affected:e2e',
'affected:test': 'nx affected:test',
'affected:lint': 'nx affected:lint',
'affected:graph': 'nx affected:graph',
affected: 'nx affected',
format: 'nx format:write',
'format:write': 'nx format:write',
'format:check': 'nx format:check',
update: 'ng update @nrwl/workspace',
'update:check': 'ng update',
lint: 'nx workspace-lint && ng lint',
graph: 'nx graph',
'workspace-generator': 'nx workspace-generator',
help: 'nx help',
start: 'nx serve',
build: 'nx build',
watch: 'nx build --watch --configuration development',
test: 'nx test',
postinstall: 'node ./decorate-angular-cli.js',
});
expect(updatedPackageJson.devDependencies['@nrwl/workspace']).toBeDefined();
Expand Down Expand Up @@ -186,15 +168,20 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
});

// check angular.json
const updatedAngularCLIJson = readJson('angular.json');
expect(updatedAngularCLIJson.projects[project].root).toEqual(
`apps/${project}`
);
expect(updatedAngularCLIJson.projects[project].sourceRoot).toEqual(
`apps/${project}/src`
);
expect(updatedAngularCLIJson.projects[project].architect.build).toEqual({
builder: '@angular-devkit/build-angular:browser',
expect(readJson('angular.json')).toStrictEqual({
version: 2,
projects: {
[project]: `apps/${project}`,
[`${project}-e2e`]: `apps/${project}-e2e`,
},
});

// check project configuration
const projectConfig = readJson(`apps/${project}/project.json`);
expect(projectConfig.root).toEqual(`apps/${project}`);
expect(projectConfig.sourceRoot).toEqual(`apps/${project}/src`);
expect(projectConfig.targets.build).toEqual({
executor: '@angular-devkit/build-angular:browser',
options: {
outputPath: `dist/apps/${project}`,
index: `apps/${project}/src/index.html`,
Expand Down Expand Up @@ -241,16 +228,16 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
},
defaultConfiguration: 'production',
});
expect(updatedAngularCLIJson.projects[project].architect.serve).toEqual({
builder: '@angular-devkit/build-angular:dev-server',
expect(projectConfig.targets.serve).toEqual({
executor: '@angular-devkit/build-angular:dev-server',
configurations: {
production: { browserTarget: `${project}:build:production` },
development: { browserTarget: `${project}:build:development` },
},
defaultConfiguration: 'development',
});
expect(updatedAngularCLIJson.projects[project].architect.test).toEqual({
builder: '@angular-devkit/build-angular:karma',
expect(projectConfig.targets.test).toEqual({
executor: '@angular-devkit/build-angular:karma',
options: {
main: `apps/${project}/src/test.ts`,
polyfills: `apps/${project}/src/polyfills.ts`,
Expand All @@ -264,18 +251,13 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
scripts: [`apps/${project}/src/scripts.ts`],
},
});
expect(projectConfig.targets.e2e).toBeUndefined();

// check e2e project config
expect(
updatedAngularCLIJson.projects[project].architect.e2e
).toBeUndefined();
expect(updatedAngularCLIJson.projects[`${project}-e2e`].root).toEqual(
`apps/${project}-e2e`
);
expect(
updatedAngularCLIJson.projects[`${project}-e2e`].architect.e2e
).toEqual({
builder: '@angular-devkit/build-angular:protractor',
const e2eProjectConfig = readJson(`apps/${project}-e2e/project.json`);
expect(e2eProjectConfig.root).toEqual(`apps/${project}-e2e`);
expect(e2eProjectConfig.targets.e2e).toEqual({
executor: '@angular-devkit/build-angular:protractor',
options: {
protractorConfig: `apps/${project}-e2e/protractor.conf.js`,
devServerTarget: `${project}:serve`,
Expand Down Expand Up @@ -363,18 +345,16 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
`apps/${e2eProject}/src/support/index.ts`
);

const angularJson = readJson('angular.json');
const projectConfig = readJson(`apps/${project}/project.json`);
expect(projectConfig.targets['cypress-run']).toBeUndefined();
expect(projectConfig.targets['cypress-open']).toBeUndefined();
expect(projectConfig.targets.e2e).toBeUndefined();

// check e2e project config
expect(
angularJson.projects[project].architect['cypress-run']
).toBeUndefined();
expect(
angularJson.projects[project].architect['cypress-open']
).toBeUndefined();
expect(angularJson.projects[project].architect.e2e).toBeUndefined();
expect(angularJson.projects[e2eProject].root).toEqual(`apps/${e2eProject}`);
expect(angularJson.projects[e2eProject].architect['cypress-run']).toEqual({
builder: '@nrwl/cypress:cypress',
const e2eProjectConfig = readJson(`apps/${project}-e2e/project.json`);
expect(e2eProjectConfig.root).toEqual(`apps/${e2eProject}`);
expect(e2eProjectConfig.targets['cypress-run']).toEqual({
executor: '@nrwl/cypress:cypress',
options: {
devServerTarget: `${project}:serve`,
cypressConfig: `apps/${e2eProject}/cypress.json`,
Expand All @@ -385,15 +365,15 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
},
},
});
expect(angularJson.projects[e2eProject].architect['cypress-open']).toEqual({
builder: '@nrwl/cypress:cypress',
expect(e2eProjectConfig.targets['cypress-open']).toEqual({
executor: '@nrwl/cypress:cypress',
options: {
watch: true,
cypressConfig: `apps/${e2eProject}/cypress.json`,
},
});
expect(angularJson.projects[e2eProject].architect.e2e).toEqual({
builder: '@nrwl/cypress:cypress',
expect(e2eProjectConfig.targets.e2e).toEqual({
executor: '@nrwl/cypress:cypress',
options: {
devServerTarget: `${project}:serve`,
watch: true,
Expand Down
Expand Up @@ -197,13 +197,46 @@ Object {
}
`;

exports[`workspace move to nx layout should update project configuration 1`] = `
Object {
"root": "apps/myApp",
"sourceRoot": "apps/myApp/src",
"targets": Object {
"build": Object {
"configurations": Object {},
"options": Object {
"tsConfig": "apps/myApp/tsconfig.app.json",
},
},
"lint": Object {
"options": Object {
"tsConfig": Array [
"apps/myApp/tsconfig.app.json",
"apps/myApp/tsconfig.spec.json",
],
},
},
"test": Object {
"options": Object {
"karmaConfig": "apps/myApp/karma.conf.js",
"tsConfig": "apps/myApp/tsconfig.spec.json",
},
},
},
}
`;

exports[`workspace move to nx layout should update tsconfig.base.json if present 1`] = `
Object {
"compilerOptions": Object {
"baseUrl": ".",
"paths": Object {},
"rootDir": ".",
},
"exclude": Array [
"node_modules",
"tmp",
],
}
`;

Expand All @@ -214,5 +247,9 @@ Object {
"paths": Object {},
"rootDir": ".",
},
"exclude": Array [
"node_modules",
"tmp",
],
}
`;
2 changes: 1 addition & 1 deletion packages/angular/src/generators/ng-add/compat.ts
@@ -1,4 +1,4 @@
import { convertNxGenerator } from '@nrwl/devkit';
import { ngAddGenerator } from './ng-add';

export default convertNxGenerator(ngAddGenerator);
export default convertNxGenerator(ngAddGenerator, true);
@@ -1 +1,4 @@
# Add files here to ignore them from prettier formatting

/dist
/coverage
Expand Up @@ -189,6 +189,57 @@ describe('workspace', () => {
).rejects.toThrow('Can only convert projects with one app');
});

it('should update project configuration', async () => {
await migrateFromAngularCli(tree, { name: 'myApp' });

const angularJson = readJson(tree, 'angular.json');
expect(angularJson.projects.myApp).toBe('apps/myApp');
expect(readJson(tree, 'apps/myApp/project.json')).toMatchSnapshot();
});

it('should update the npm scripts', async () => {
tree.write(
'package.json',
JSON.stringify({
scripts: {
ng: 'ng',
start: 'ng serve',
build: 'ng build',
watch: 'ng build --watch --configuration development',
test: 'ng test',
},
})
);

await migrateFromAngularCli(tree, { name: 'myApp' });

expect(readJson(tree, 'package.json').scripts).toStrictEqual({
ng: 'nx',
start: 'nx serve',
build: 'nx build',
watch: 'nx build --watch --configuration development',
test: 'nx test',
postinstall: 'node ./decorate-angular-cli.js',
});
});

it('should handle existing postinstall script', async () => {
tree.write(
'package.json',
JSON.stringify({
scripts: {
postinstall: 'node some-awesome-script.js',
},
})
);

await migrateFromAngularCli(tree, { name: 'myApp' });

expect(readJson(tree, 'package.json').scripts.postinstall).toEqual(
'node some-awesome-script.js && node ./decorate-angular-cli.js'
);
});

it('should remove the newProjectRoot key from configuration', async () => {
tree.write(
'/angular.json',
Expand Down
Expand Up @@ -3,6 +3,7 @@ import {
formatFiles,
installPackagesTask,
Tree,
updateJson,
} from '@nrwl/devkit';
import { nxVersion } from '../../utils/versions';
import type { GeneratorOptions } from './schema';
Expand Down Expand Up @@ -52,6 +53,11 @@ export async function migrateFromAngularCli(
// multiple projects are supported

// create and update root files and configurations
updateJson(tree, 'angular.json', (json) => ({
...json,
version: 2,
$schema: undefined,
}));
createNxJson(tree, options);
updateWorkspaceConfigDefaults(tree);
updateRootTsConfig(tree);
Expand Down
12 changes: 9 additions & 3 deletions packages/angular/src/generators/ng-add/utilities/app.migrator.ts
Expand Up @@ -5,6 +5,7 @@ import {
updateJson,
updateProjectConfiguration,
} from '@nrwl/devkit';
import { convertToNxProjectGenerator } from '@nrwl/workspace/generators';
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
import { GeneratorOptions } from '../schema';
import { E2eProjectMigrator } from './e2e-project.migrator';
Expand All @@ -25,10 +26,10 @@ export class AppMigrator extends ProjectMigrator {
}

async migrate(): Promise<void> {
this.e2eMigrator.migrate();
await this.e2eMigrator.migrate();

this.moveProjectFiles();
this.updateProjectConfiguration();
await this.updateProjectConfiguration();
this.updateTsConfigs();
// TODO: check later if it's still needed
this.updateProjectTsLint();
Expand Down Expand Up @@ -77,7 +78,7 @@ export class AppMigrator extends ProjectMigrator {
this.moveDir(this.project.oldSourceRoot, this.project.newSourceRoot);
}

private updateProjectConfiguration(): void {
private async updateProjectConfiguration(): Promise<void> {
this.projectConfig.root = this.project.newRoot;
this.projectConfig.sourceRoot = this.project.newSourceRoot;

Expand Down Expand Up @@ -129,6 +130,11 @@ export class AppMigrator extends ProjectMigrator {
updateProjectConfiguration(this.tree, this.project.name, {
...this.projectConfig,
});

await convertToNxProjectGenerator(this.tree, {
project: this.project.name,
skipFormat: true,
});
}

private updateTsConfigs(): void {
Expand Down

1 comment on commit 18776f6

@vercel
Copy link

@vercel vercel bot commented on 18776f6 Mar 31, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.