Skip to content

Commit

Permalink
cleanup(angular): move the angular cli migration generator from @nrwl…
Browse files Browse the repository at this point in the history
…/workspace to @nrwl/angular
  • Loading branch information
leosvelperez committed Mar 9, 2022
1 parent 45bf0e5 commit 7ef21b1
Show file tree
Hide file tree
Showing 25 changed files with 410 additions and 160 deletions.
24 changes: 20 additions & 4 deletions e2e/angular-core/src/ng-add.test.ts
Expand Up @@ -156,12 +156,28 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
npmScope: 'projscope',
affected: { defaultBase: 'main' },
implicitDependencies: {
'angular.json': '*',
'package.json': '*',
'tslint.json': '*',
'package.json': {
dependencies: '*',
devDependencies: '*',
},
'.eslintrc.json': '*',
'tsconfig.base.json': '*',
'nx.json': '*',
},
tasksRunnerOptions: {
default: {
runner: '@nrwl/workspace/tasks-runners/default',
options: {
cacheableOperations: ['build', 'lint', 'test', 'e2e'],
},
},
},
targetDependencies: {
build: [
{
target: 'build',
projects: 'dependencies',
},
],
},
cli: { defaultCollection: '@nrwl/angular', packageManager },
defaultProject: project,
Expand Down
2 changes: 1 addition & 1 deletion e2e/cli/src/cli.test.ts
Expand Up @@ -125,8 +125,8 @@ describe('list', () => {

// check for schematics
expect(listOutput).toContain('workspace');
expect(listOutput).toContain('ng-add');
expect(listOutput).toContain('library');
expect(listOutput).toContain('workspace-generator');

// check for builders
expect(listOutput).toContain('run-commands');
Expand Down
4 changes: 2 additions & 2 deletions e2e/utils/index.ts
Expand Up @@ -422,8 +422,8 @@ export function runNgAdd(
}
): string {
try {
packageInstall('@nrwl/workspace');
return execSync(`npx ng add @nrwl/workspace ${command}`, {
packageInstall('@nrwl/angular');
return execSync(`npx ng add @nrwl/angular ${command}`, {
cwd: tmpProjPath(),
env: { ...(opts.env || process.env), NX_INVOKED_BY_RUNNER: undefined },
encoding: 'utf-8',
Expand Down
14 changes: 12 additions & 2 deletions packages/angular/generators.json
Expand Up @@ -42,7 +42,6 @@
"factory": "./src/generators/init/init.compat#initSchematic",
"schema": "./src/generators/init/schema.json",
"description": "Initializes the @nrwl/angular plugin.",
"aliases": ["ng-add"],
"hidden": true
},
"karma": {
Expand Down Expand Up @@ -86,6 +85,12 @@
"aliases": ["host"],
"description": "Generate a Host Angular Micro Frontend Application."
},
"ng-add": {
"factory": "./src/generators/ng-add/compat",
"schema": "./src/generators/ng-add/schema.json",
"description": "Migrates an Angular CLI workspace to Nx or adds the Angular plugin to an Nx workspace.",
"hidden": true
},
"ngrx": {
"factory": "./src/generators/ngrx/compat",
"schema": "./src/generators/ngrx/schema.json",
Expand Down Expand Up @@ -187,7 +192,6 @@
"factory": "./src/generators/init/init",
"schema": "./src/generators/init/schema.json",
"description": "Initializes the @nrwl/angular plugin.",
"aliases": ["ng-add"],
"hidden": true
},
"karma": {
Expand Down Expand Up @@ -231,6 +235,12 @@
"aliases": ["host"],
"description": "Generate a Host Angular Micro Frontend Application."
},
"ng-add": {
"factory": "./src/generators/ng-add/ng-add",
"schema": "./src/generators/ng-add/schema.json",
"description": "Migrates an Angular CLI workspace to Nx or adds the Angular plugin to an Nx workspace.",
"hidden": true
},
"ngrx": {
"factory": "./src/generators/ngrx/ngrx",
"schema": "./src/generators/ngrx/schema.json",
Expand Down
16 changes: 15 additions & 1 deletion packages/angular/src/generators/init/init.ts
Expand Up @@ -8,6 +8,7 @@ import {
updateWorkspaceConfiguration,
} from '@nrwl/devkit';
import { jestInitGenerator } from '@nrwl/jest';
import { Linter } from '@nrwl/linter';
import { runTasksInSerial } from '@nrwl/workspace/src/utilities/run-tasks-in-serial';
import { setDefaultCollection } from '@nrwl/workspace/src/utilities/set-default-collection';
import { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
Expand All @@ -22,8 +23,9 @@ import { Schema } from './schema';

export async function angularInitGenerator(
host: Tree,
options: Schema
rawOptions: Schema
): Promise<GeneratorCallback> {
const options = normalizeOptions(rawOptions);
setDefaults(host, options);
addPostInstall(host);

Expand All @@ -41,6 +43,18 @@ export async function angularInitGenerator(
return runTasksInSerial(depsTask, unitTestTask, e2eTask);
}

function normalizeOptions(options: Schema): Required<Schema> {
return {
e2eTestRunner: options.e2eTestRunner ?? E2eTestRunner.Cypress,
linter: options.linter ?? Linter.EsLint,
skipFormat: options.skipFormat ?? false,
skipInstall: options.skipInstall ?? false,
skipPackageJson: options.skipPackageJson ?? false,
style: options.style ?? 'css',
unitTestRunner: options.unitTestRunner ?? UnitTestRunner.Jest,
};
}

function setDefaults(host: Tree, options: Schema) {
const workspace = readWorkspaceConfiguration(host);

Expand Down
4 changes: 2 additions & 2 deletions packages/angular/src/generators/init/schema.d.ts
Expand Up @@ -3,11 +3,11 @@ import { E2eTestRunner, UnitTestRunner } from '../../utils/test-runners';
import type { Styles } from '../utils/types';

export interface Schema {
unitTestRunner: UnitTestRunner;
unitTestRunner?: UnitTestRunner;
e2eTestRunner?: E2eTestRunner;
skipFormat?: boolean;
skipInstall?: boolean;
style?: Styles;
linter: Exclude<Linter, Linter.TsLint>;
linter?: Exclude<Linter, Linter.TsLint>;
skipPackageJson?: boolean;
}
5 changes: 5 additions & 0 deletions packages/angular/src/generators/init/schema.json
Expand Up @@ -38,6 +38,7 @@
"description": "The file extension to be used for style files.",
"type": "string",
"default": "css",
"enum": ["css", "scss", "sass", "less"],
"x-prompt": {
"message": "Which stylesheet format would you like to use?",
"type": "list",
Expand All @@ -50,6 +51,10 @@
"value": "scss",
"label": "SASS(.scss) [ http://sass-lang.com ]"
},
{
"value": "sass",
"label": "SASS(.sass) [ http://sass-lang.com ]"
},
{
"value": "less",
"label": "LESS [ http://lesscss.org ]"
Expand Down
Expand Up @@ -167,13 +167,34 @@ Object {
"defaultProject": "myApp",
"implicitDependencies": Object {
".eslintrc.json": "*",
"angular.json": "*",
"nx.json": "*",
"package.json": "*",
"package.json": Object {
"dependencies": "*",
"devDependencies": "*",
},
"tsconfig.base.json": "*",
"tslint.json": "*",
},
"npmScope": "my-app",
"targetDependencies": Object {
"build": Array [
Object {
"projects": "dependencies",
"target": "build",
},
],
},
"tasksRunnerOptions": Object {
"default": Object {
"options": Object {
"cacheableOperations": Array [
"build",
"lint",
"test",
"e2e",
],
},
"runner": "@nrwl/workspace/tasks-runners/default",
},
},
}
`;

Expand Down
4 changes: 4 additions & 0 deletions packages/angular/src/generators/ng-add/compat.ts
@@ -0,0 +1,4 @@
import { convertNxGenerator } from '@nrwl/devkit';
import { ngAddGenerator } from './ng-add';

export default convertNxGenerator(ngAddGenerator);
@@ -0,0 +1,69 @@
/**
* This file decorates the Angular CLI with the Nx CLI to enable features such as computation caching
* and faster execution of tasks.
*
* It does this by:
*
* - Patching the Angular CLI to warn you in case you accidentally use the undecorated ng command.
* - Symlinking the ng to nx command, so all commands run through the Nx CLI
* - Updating the package.json postinstall script to give you control over this script
*
* The Nx CLI decorates the Angular CLI, so the Nx CLI is fully compatible with it.
* Every command you run should work the same when using the Nx CLI, except faster.
*
* Because of symlinking you can still type `ng build/test/lint` in the terminal. The ng command, in this case,
* will point to nx, which will perform optimizations before invoking ng. So the Angular CLI is always invoked.
* The Nx CLI simply does some optimizations before invoking the Angular CLI.
*
* To opt out of this patch:
* - Replace occurrences of nx with ng in your package.json
* - Remove the script from your postinstall script in your package.json
* - Delete and reinstall your node_modules
*/

const fs = require('fs');
const os = require('os');
const cp = require('child_process');
const isWindows = os.platform() === 'win32';
let output;
try {
output = require('@nrwl/workspace').output;
} catch (e) {
console.warn('Angular CLI could not be decorated to enable computation caching. Please ensure @nrwl/workspace is installed.');
process.exit(0);
}

/**
* Symlink of ng to nx, so you can keep using `ng build/test/lint` and still
* invoke the Nx CLI and get the benefits of computation caching.
*/
function symlinkNgCLItoNxCLI() {
try {
const ngPath = './node_modules/.bin/ng';
const nxPath = './node_modules/.bin/nx';
if (isWindows) {
/**
* This is the most reliable way to create symlink-like behavior on Windows.
* Such that it works in all shells and works with npx.
*/
['', '.cmd', '.ps1'].forEach(ext => {
if (fs.existsSync(nxPath + ext)) fs.writeFileSync(ngPath + ext, fs.readFileSync(nxPath + ext));
});
} else {
// If unix-based, symlink
cp.execSync(`ln -sf ./nx ${ngPath}`);
}
}
catch(e) {
output.error({ title: 'Unable to create a symlink from the Angular CLI to the Nx CLI:' + e.message });
throw e;
}
}

try {
symlinkNgCLItoNxCLI();
require('@nrwl/cli/lib/decorate-cli').decorateCli();
output.log({ title: 'Angular CLI has been decorated to enable computation caching.' });
} catch(e) {
output.error({ title: 'Decoration of the Angular CLI did not complete successfully' });
}
29 changes: 29 additions & 0 deletions packages/angular/src/generators/ng-add/files/root/nx.json__tmpl__
@@ -0,0 +1,29 @@
{
"npmScope": "<%= npmScope %>",
"affected": {
"defaultBase": "<%= defaultBase %>"
},
"implicitDependencies": {
"package.json": {
"dependencies": "*",
"devDependencies": "*"
},
".eslintrc.json": "*"
},
"tasksRunnerOptions": {
"default": {
"runner": "@nrwl/workspace/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "lint", "test", "e2e"]
}
}
},
"targetDependencies": {
"build": [
{
"target": "build",
"projects": "dependencies"
}
]
}
}
Empty file.

0 comments on commit 7ef21b1

Please sign in to comment.