Skip to content

Commit 3df6fba

Browse files
clydinalan-agius4
authored andcommitted
refactor(@angular/cli): support bootstrapping with CommonJS startup code
To support the eventual migration of the CLI to ESM, the CLI commandline tool is now bootstrapped by dynamically importing the main initialization code. This is done to allow the main bin file (`ng`) to remain CommonJS so that older versions of Node.js can be checked and validated prior to the execution of the CLI. This separate bootstrap file is needed to allow the use of a dynamic import expression without crashing older versions of Node.js that do not support dynamic import expressions and would otherwise throw a syntax error. This bootstrap file is required from the main bin file only after the Node.js version is determined to be in the supported range. The use of the dynamic import expression allows CommonJS code to execute either CommonJS or ESM code.
1 parent a7de97e commit 3df6fba

File tree

6 files changed

+57
-7
lines changed

6 files changed

+57
-7
lines changed

packages/angular/cli/bin/bootstrap.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
/**
10+
* @fileoverview
11+
*
12+
* This file is used to bootstrap the CLI process by dynamically importing the main initialization code.
13+
* This is done to allow the main bin file (`ng`) to remain CommonJS so that older versions of Node.js
14+
* can be checked and validated prior to the execution of the CLI. This separate bootstrap file is
15+
* needed to allow the use of a dynamic import expression without crashing older versions of Node.js that
16+
* do not support dynamic import expressions and would otherwise throw a syntax error. This bootstrap file
17+
* is required from the main bin file only after the Node.js version is determined to be in the supported
18+
* range.
19+
*/
20+
21+
import('../lib/init.js');

packages/angular/cli/bin/ng renamed to packages/angular/cli/bin/ng.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
#!/usr/bin/env node
2+
/**
3+
* @license
4+
* Copyright Google LLC All Rights Reserved.
5+
*
6+
* Use of this source code is governed by an MIT-style license that can be
7+
* found in the LICENSE file at https://angular.io/license
8+
*/
9+
10+
/* eslint-disable no-console */
11+
/* eslint-disable import/no-unassigned-import */
212
'use strict';
313

414
// Provide a title to the process in `ps`.
@@ -13,7 +23,6 @@ try {
1323
// This node version check ensures that extremely old versions of node are not used.
1424
// These may not support ES2015 features such as const/let/async/await/etc.
1525
// These would then crash with a hard to diagnose error message.
16-
// tslint:disable-next-line: no-var-keyword
1726
var version = process.versions.node.split('.').map((part) => Number(part));
1827
if (version[0] % 2 === 1 && version[0] > 14) {
1928
// Allow new odd numbered releases with a warning (currently v15+)
@@ -25,23 +34,23 @@ if (version[0] % 2 === 1 && version[0] > 14) {
2534
' For more information, please see https://nodejs.org/en/about/releases/.',
2635
);
2736

28-
require('../lib/init');
37+
require('./bootstrap');
2938
} else if (
3039
version[0] < 12 ||
3140
version[0] === 13 ||
3241
(version[0] === 12 && version[1] < 20) ||
3342
(version[0] === 14 && version[1] < 15)
3443
) {
35-
// Error and exit if less than 12.14 or 13.x or less than 14.15
44+
// Error and exit if less than 12.20 or 13.x or less than 14.15
3645
console.error(
3746
'Node.js version ' +
3847
process.version +
3948
' detected.\n' +
40-
'The Angular CLI requires a minimum Node.js version of either v12.14 or v14.15.\n\n' +
49+
'The Angular CLI requires a minimum Node.js version of either v12.20 or v14.15.\n\n' +
4150
'Please update your Node.js version or visit https://nodejs.org/ for additional instructions.\n',
4251
);
4352

4453
process.exitCode = 3;
4554
} else {
46-
require('../lib/init');
55+
require('./bootstrap');
4756
}

packages/angular/cli/bin/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"type": "commonjs"
3+
}

packages/angular/cli/bin/postinstall/analytics-prompt.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
19
'use strict';
2-
// This file is ES6 because it needs to be executed as is.
10+
// This file is ES5 because it needs to be executed as is.
311

412
if ('NG_CLI_ANALYTICS' in process.env) {
513
return;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
#!/usr/bin/env node
2+
/**
3+
* @license
4+
* Copyright Google LLC All Rights Reserved.
5+
*
6+
* Use of this source code is governed by an MIT-style license that can be
7+
* found in the LICENSE file at https://angular.io/license
8+
*/
9+
210
'use strict';
311

412
// These should not fail but if they do they should not block installation of the package
513
try {
14+
// eslint-disable-next-line import/no-unassigned-import
615
require('./analytics-prompt');
716
} catch (_) {}

packages/angular/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "CLI tool for Angular",
55
"main": "lib/cli/index.js",
66
"bin": {
7-
"ng": "./bin/ng"
7+
"ng": "./bin/ng.js"
88
},
99
"keywords": [
1010
"angular",

0 commit comments

Comments
 (0)