feat(angular): remove decorate-angular-cli (#14226)
This commit is contained in:
parent
c82f7c3848
commit
a5707c8b75
@ -16,7 +16,6 @@ This will enable you to use the Nx CLI in your existing Angular CLI workspace wh
|
||||
|
||||
- The `nx`, `@nrwl/workspace` and `prettier` packages will be installed.
|
||||
- An `nx.json` file will be created in the root of your workspace.
|
||||
- A `decorate-angular-cli.js` file will be added to the root of your workspace, and a `postinstall` script will be added to your `package.json` to run this script when your dependencies are updated. (The script forwards the `ng` commands to the Nx CLI (`nx`) to enable features such as [Computation Caching](/concepts/how-caching-works).)
|
||||
- For an Angular 15+ repo, the `angular.json` file is split into separate `project.json` files for each project.
|
||||
|
||||
After the process completes, you can continue using the same `serve/build/lint/test` commands you are used to.
|
||||
@ -104,7 +103,6 @@ After the changes are applied, your workspace file structure should look similar
|
||||
├── .gitignore
|
||||
├── .prettierignore
|
||||
├── .prettierrc
|
||||
├── decorate-angular-cli.js
|
||||
├── karma.conf.js
|
||||
├── nx.json
|
||||
├── package.json
|
||||
@ -359,7 +357,6 @@ The script will make the following changes:
|
||||
- If you opted into Nx Cloud, `@nrwl/nx-cloud` will be installed as well.
|
||||
- If your project's Angular version is greater than or equal to version 13, then the `@nrwl/angular` package will be installed as well.
|
||||
- Creates an `nx.json` file in the root of your workspace.
|
||||
- Adds a `decorate-angular-cli.js` to the root of your workspace, and a `postinstall` script in your `package.json` to run the script when your dependencies are updated. The script forwards the `ng` commands to the Nx CLI (`nx`) to enable features such as [Computation Caching](/concepts/how-caching-works).
|
||||
|
||||
By running this command and accepting Nx Cloud, Nx distributed caching is now enabled.
|
||||
|
||||
|
||||
@ -129,12 +129,11 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
|
||||
const updatedPackageJson = readJson('package.json');
|
||||
expect(updatedPackageJson.description).toEqual('some description');
|
||||
expect(updatedPackageJson.scripts).toEqual({
|
||||
ng: 'nx',
|
||||
ng: 'ng',
|
||||
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();
|
||||
expect(updatedPackageJson.devDependencies['@angular/cli']).toBeDefined();
|
||||
|
||||
@ -148,33 +148,14 @@ describe('workspace', () => {
|
||||
await migrateFromAngularCli(tree, {});
|
||||
|
||||
expect(readJson(tree, 'package.json').scripts).toStrictEqual({
|
||||
ng: 'nx',
|
||||
ng: 'ng',
|
||||
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({
|
||||
name: '@my-org/my-monorepo',
|
||||
scripts: {
|
||||
postinstall: 'node some-awesome-script.js',
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
await migrateFromAngularCli(tree, {});
|
||||
|
||||
expect(readJson(tree, 'package.json').scripts.postinstall).toEqual(
|
||||
'node some-awesome-script.js && node ./decorate-angular-cli.js'
|
||||
);
|
||||
});
|
||||
|
||||
it('should remove the angular.json file', async () => {
|
||||
tree.write(
|
||||
'/angular.json',
|
||||
@ -586,14 +567,6 @@ describe('workspace', () => {
|
||||
expect(readJson(tree, 'nx.json')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should create decorate-angular-cli.js', async () => {
|
||||
await migrateFromAngularCli(tree, { preserveAngularCliLayout: true });
|
||||
|
||||
expect(tree.exists('/decorate-angular-cli.js')).toBe(true);
|
||||
const { scripts } = readJson(tree, 'package.json');
|
||||
expect(scripts.postinstall).toBe('node ./decorate-angular-cli.js');
|
||||
});
|
||||
|
||||
it('should support multiple projects', async () => {
|
||||
const angularJson = {
|
||||
$schema: './node_modules/@angular/cli/lib/config/schema.json',
|
||||
@ -663,11 +636,9 @@ describe('workspace', () => {
|
||||
await migrateFromAngularCli(tree, { preserveAngularCliLayout: true });
|
||||
|
||||
expect(tree.exists('angular.json')).toBe(false);
|
||||
expect(tree.exists('decorate-angular-cli.js')).toBe(true);
|
||||
expect(tree.exists('.prettierignore')).toBe(true);
|
||||
expect(tree.exists('.prettierrc')).toBe(true);
|
||||
const { scripts } = readJson(tree, 'package.json');
|
||||
expect(scripts.postinstall).toBe('node ./decorate-angular-cli.js');
|
||||
expect(readJson(tree, 'nx.json')).toMatchSnapshot();
|
||||
expect(readJson(tree, 'project.json')).toMatchSnapshot();
|
||||
expect(readJson(tree, 'projects/app2/project.json')).toMatchSnapshot();
|
||||
|
||||
@ -16,7 +16,6 @@ import {
|
||||
createNxJson,
|
||||
createRootKarmaConfig,
|
||||
createWorkspaceFiles,
|
||||
decorateAngularCli,
|
||||
deleteAngularJson,
|
||||
deleteGitKeepFilesIfNotNeeded,
|
||||
formatFilesTask,
|
||||
@ -53,7 +52,6 @@ export async function migrateFromAngularCli(
|
||||
}
|
||||
);
|
||||
createNxJson(tree, options, angularJson.defaultProject);
|
||||
decorateAngularCli(tree);
|
||||
updateVsCodeRecommendedExtensions(tree);
|
||||
await updatePrettierConfig(tree);
|
||||
|
||||
@ -96,7 +94,6 @@ export async function migrateFromAngularCli(
|
||||
updateWorkspaceConfigDefaults(tree);
|
||||
updateRootTsConfig(tree);
|
||||
updatePackageJson(tree);
|
||||
decorateAngularCli(tree);
|
||||
await createWorkspaceFiles(tree);
|
||||
|
||||
// migrate all projects
|
||||
|
||||
@ -16,9 +16,6 @@ import { deduceDefaultBase } from '@nrwl/workspace/src/utilities/default-base';
|
||||
import { resolveUserExistingPrettierConfig } from '@nrwl/workspace/src/utilities/prettier';
|
||||
import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
|
||||
import { prettierVersion } from '@nrwl/workspace/src/utils/versions';
|
||||
import { readFileSync } from 'fs';
|
||||
import { readModulePackageJson } from 'nx/src/utils/package-json';
|
||||
import { dirname, join } from 'path';
|
||||
import { angularDevkitVersion, nxVersion } from '../../../utils/versions';
|
||||
import type { ProjectMigrator } from '../migrators';
|
||||
import type { GeneratorOptions } from '../schema';
|
||||
@ -136,37 +133,6 @@ function getWorkspaceCommonTargets(tree: Tree): {
|
||||
return targets;
|
||||
}
|
||||
|
||||
export function decorateAngularCli(tree: Tree): void {
|
||||
const nrwlWorkspacePath = readModulePackageJson('@nrwl/workspace').path;
|
||||
const decorateCli = readFileSync(
|
||||
join(
|
||||
dirname(nrwlWorkspacePath),
|
||||
'src/generators/utils/decorate-angular-cli.js__tmpl__'
|
||||
),
|
||||
'utf-8'
|
||||
);
|
||||
tree.write('decorate-angular-cli.js', decorateCli);
|
||||
|
||||
updateJson(tree, 'package.json', (json) => {
|
||||
if (
|
||||
json.scripts &&
|
||||
json.scripts.postinstall &&
|
||||
!json.scripts.postinstall.includes('decorate-angular-cli.js')
|
||||
) {
|
||||
// if exists, add execution of this script
|
||||
json.scripts.postinstall += ' && node ./decorate-angular-cli.js';
|
||||
} else {
|
||||
json.scripts ??= {};
|
||||
// if doesn't exist, set to execute this script
|
||||
json.scripts.postinstall = 'node ./decorate-angular-cli.js';
|
||||
}
|
||||
if (json.scripts.ng) {
|
||||
json.scripts.ng = 'nx';
|
||||
}
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
export function updateWorkspaceConfigDefaults(tree: Tree): void {
|
||||
const nxJson = readNxJson(tree);
|
||||
delete (nxJson as any).newProjectRoot;
|
||||
|
||||
@ -1 +0,0 @@
|
||||
export * from 'nx/src/adapter/decorate-cli';
|
||||
@ -1,16 +0,0 @@
|
||||
import { readFileSync, writeFileSync } from 'fs';
|
||||
|
||||
export function decorateCli() {
|
||||
const path = 'node_modules/@angular/cli/lib/cli/index.js';
|
||||
const angularCLIInit = readFileSync(path, 'utf-8');
|
||||
const start = angularCLIInit.indexOf(`(options) {`) + 11;
|
||||
|
||||
const newContent = `${angularCLIInit.slice(0, start)}
|
||||
if (!process.env['NX_CLI_SET']) {
|
||||
require('nx/bin/nx');
|
||||
return new Promise(function(res, rej) {});
|
||||
}
|
||||
${angularCLIInit.substring(start)}
|
||||
`;
|
||||
writeFileSync(path, newContent);
|
||||
}
|
||||
@ -55,11 +55,6 @@
|
||||
"ignore": ["**/tsconfig*.json", "project.json", ".eslintrc.json"],
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/workspace",
|
||||
"glob": "**/**/decorate-angular-cli.js__tmpl__",
|
||||
"output": "/"
|
||||
},
|
||||
{
|
||||
"input": "packages/workspace",
|
||||
"glob": "**/*.{js,css,html,svg}",
|
||||
|
||||
@ -14,10 +14,7 @@ Object {
|
||||
"license": "MIT",
|
||||
"name": "my-workspace",
|
||||
"private": true,
|
||||
"scripts": Object {
|
||||
"ng": "nx",
|
||||
"postinstall": "node ./decorate-angular-cli.js",
|
||||
},
|
||||
"scripts": Object {},
|
||||
"version": "0.0.0",
|
||||
}
|
||||
`;
|
||||
|
||||
@ -198,37 +198,6 @@ describe('@nrwl/workspace:generateWorkspaceFiles', () => {
|
||||
expect(recommendations).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should add decorate-angular-cli when used with angular cli', async () => {
|
||||
await generateWorkspaceFiles(tree, {
|
||||
name: 'proj',
|
||||
directory: 'proj',
|
||||
preset: Preset.AngularMonorepo,
|
||||
defaultBase: 'main',
|
||||
});
|
||||
expect(tree.exists('/proj/decorate-angular-cli.js')).toBe(true);
|
||||
|
||||
const { scripts } = readJson(tree, '/proj/package.json');
|
||||
expect(scripts).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"ng": "nx",
|
||||
"postinstall": "node ./decorate-angular-cli.js",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not add decorate-angular-cli when used with nx cli', async () => {
|
||||
await generateWorkspaceFiles(tree, {
|
||||
name: 'proj',
|
||||
directory: 'proj',
|
||||
preset: Preset.Empty,
|
||||
defaultBase: 'main',
|
||||
});
|
||||
expect(tree.exists('/proj/decorate-angular-cli.js')).toBe(false);
|
||||
|
||||
const { scripts } = readJson(tree, '/proj/package.json');
|
||||
expect(scripts).toMatchInlineSnapshot(`Object {}`);
|
||||
});
|
||||
|
||||
it('should create a workspace using NPM preset (npm package manager)', async () => {
|
||||
tree.write('/proj/package.json', JSON.stringify({}));
|
||||
await generateWorkspaceFiles(tree, {
|
||||
|
||||
@ -15,7 +15,6 @@ import {
|
||||
prettierVersion,
|
||||
typescriptVersion,
|
||||
} from '../../utils/versions';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join, join as pathJoin } from 'path';
|
||||
import { Preset } from '../utils/presets';
|
||||
import { deduceDefaultBase } from '../../utilities/default-base';
|
||||
@ -37,9 +36,7 @@ export async function generateWorkspaceFiles(
|
||||
createFiles(tree, options);
|
||||
createNxJson(tree, options);
|
||||
createPrettierrc(tree, options);
|
||||
if (options.preset === Preset.AngularMonorepo) {
|
||||
decorateAngularClI(tree, options);
|
||||
}
|
||||
|
||||
const [packageMajor] = getPackageManagerVersion(
|
||||
options.packageManager as PackageManager
|
||||
).split('.');
|
||||
@ -56,13 +53,6 @@ export async function generateWorkspaceFiles(
|
||||
await formatFiles(tree);
|
||||
}
|
||||
|
||||
function decorateAngularClI(tree: Tree, options: NormalizedSchema) {
|
||||
const decorateCli = readFileSync(
|
||||
pathJoin(__dirname as any, '..', 'utils', 'decorate-angular-cli.js__tmpl__')
|
||||
).toString();
|
||||
tree.write(join(options.directory, 'decorate-angular-cli.js'), decorateCli);
|
||||
}
|
||||
|
||||
function setPresetProperty(tree: Tree, options: NormalizedSchema) {
|
||||
updateJson(tree, join(options.directory, 'nx.json'), (json) => {
|
||||
if (options.preset === Preset.Core || options.preset === Preset.NPM) {
|
||||
@ -204,16 +194,6 @@ function createYarnrcYml(tree: Tree, options: NormalizedSchema) {
|
||||
}
|
||||
|
||||
function addNpmScripts(tree: Tree, options: NormalizedSchema) {
|
||||
if (options.preset === Preset.AngularMonorepo) {
|
||||
updateJson(tree, join(options.directory, 'package.json'), (json) => {
|
||||
Object.assign(json.scripts, {
|
||||
ng: 'nx',
|
||||
postinstall: 'node ./decorate-angular-cli.js',
|
||||
});
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
options.preset === Preset.AngularStandalone ||
|
||||
options.preset === Preset.ReactStandalone
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
/**
|
||||
* 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 running your task.
|
||||
*
|
||||
* 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('nx/src/adapter/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' });
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user