aboutsummaryrefslogtreecommitdiff
path: root/decorate-angular-cli.js
diff options
context:
space:
mode:
Diffstat (limited to 'decorate-angular-cli.js')
-rw-r--r--decorate-angular-cli.js91
1 files changed, 91 insertions, 0 deletions
diff --git a/decorate-angular-cli.js b/decorate-angular-cli.js
new file mode 100644
index 0000000..1fe1981
--- /dev/null
+++ b/decorate-angular-cli.js
@@ -0,0 +1,91 @@
+/**
+ * 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);
+}
+
+/**
+ * Paths to files being patched
+ */
+const angularCLIInitPath = 'node_modules/@angular/cli/lib/cli/index.js';
+
+/**
+ * Patch index.js to warn you if you invoke the undecorated Angular CLI.
+ */
+function patchAngularCLI(initPath) {
+ const angularCLIInit = fs.readFileSync(initPath, 'utf-8').toString();
+
+ if (!angularCLIInit.includes('NX_CLI_SET')) {
+ fs.writeFileSync(initPath, `
+if (!process.env['NX_CLI_SET']) {
+ const { output } = require('@nrwl/workspace');
+ output.warn({ title: 'The Angular CLI was invoked instead of the Nx CLI. Use "npx ng [command]" or "nx [command]" instead.' });
+}
+${angularCLIInit}
+ `);
+ }
+}
+
+/**
+ * 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();
+ patchAngularCLI(angularCLIInitPath);
+ 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' });
+}