Skip to content

Commit ea8f387

Browse files
filipesilvaBrocco
authored andcommitted
fix(@ngtools/webpack): check for compiler-cli on plugin constructor
Fix #7904
1 parent 66dadce commit ea8f387

File tree

7 files changed

+61
-42
lines changed

7 files changed

+61
-42
lines changed

packages/@ngtools/webpack/src/angular_compiler_plugin.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
// @ignoreDep @angular/compiler-cli
21
import * as fs from 'fs';
32
import { fork, ChildProcess } from 'child_process';
43
import * as path from 'path';
54
import * as ts from 'typescript';
65

7-
const { __NGTOOLS_PRIVATE_API_2, VERSION } = require('@angular/compiler-cli');
86
const ContextElementDependency = require('webpack/lib/dependencies/ContextElementDependency');
97
const NodeWatchFileSystem = require('webpack/lib/node/NodeWatchFileSystem');
108
const treeKill = require('tree-kill');
@@ -29,6 +27,9 @@ import { time, timeEnd } from './benchmark';
2927
import { InitMessage, UpdateMessage } from './type_checker';
3028
import { gatherDiagnostics, hasErrors } from './gather_diagnostics';
3129
import {
30+
CompilerCliIsSupported,
31+
__NGTOOLS_PRIVATE_API_2,
32+
VERSION,
3233
DEFAULT_ERROR_CODE,
3334
UNKNOWN_ERROR_CODE,
3435
SOURCE,
@@ -41,7 +42,7 @@ import {
4142
createCompilerHost,
4243
formatDiagnostics,
4344
EmitFlags,
44-
} from './ngtools_api2';
45+
} from './ngtools_api';
4546

4647

4748
/**
@@ -106,6 +107,7 @@ export class AngularCompilerPlugin implements Tapable {
106107
private _typeCheckerProcess: ChildProcess;
107108

108109
constructor(options: AngularCompilerPluginOptions) {
110+
CompilerCliIsSupported();
109111
this._options = Object.assign({}, options);
110112
this._setupOptions(this._options);
111113
}
@@ -121,7 +123,7 @@ export class AngularCompilerPlugin implements Tapable {
121123
}
122124

123125
static isSupported() {
124-
return parseInt(VERSION.major) >= 5;
126+
return VERSION && parseInt(VERSION.major) >= 5;
125127
}
126128

127129
private _setupOptions(options: AngularCompilerPluginOptions) {

packages/@ngtools/webpack/src/extract_i18n_plugin.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
// @ignoreDep @angular/compiler-cli
21
import * as ts from 'typescript';
32
import * as path from 'path';
43
import * as fs from 'fs';
54

6-
const {__NGTOOLS_PRIVATE_API_2, VERSION} = require('@angular/compiler-cli');
7-
5+
import {__NGTOOLS_PRIVATE_API_2, VERSION} from './ngtools_api';
86
import {Tapable} from './webpack';
97
import {WebpackResourceLoader} from './resource_loader';
108

packages/@ngtools/webpack/src/gather_diagnostics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as ts from 'typescript';
22

33
import { time, timeEnd } from './benchmark';
4-
import { Program, Diagnostics } from './ngtools_api2';
4+
import { Program, Diagnostics } from './ngtools_api';
55

66

77
export class CancellationToken implements ts.CancellationToken {

packages/@ngtools/webpack/src/index.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,3 @@
1-
// @ignoreDep @angular/compiler-cli
2-
import * as path from 'path';
3-
4-
let version;
5-
6-
// Check that Angular is available.
7-
try {
8-
version = require('@angular/compiler-cli').VERSION;
9-
} catch (e) {
10-
throw new Error('The "@angular/compiler-cli" package was not properly installed. Error: ' + e);
11-
}
12-
13-
// Check that Angular is also not part of this module's node_modules (it should be the project's).
14-
const compilerCliPath = require.resolve('@angular/compiler-cli');
15-
if (compilerCliPath.startsWith(path.dirname(__dirname))) {
16-
throw new Error('The @ngtools/webpack plugin now relies on the project @angular/compiler-cli. '
17-
+ 'Please clean your node_modules and reinstall.');
18-
}
19-
20-
// Throw if we're neither 2.3.1 or more, nor 4.x.y, nor 5.x.y.
21-
if (!( version.major == '5'
22-
|| version.major == '4'
23-
|| (version.major == '2'
24-
&& ( version.minor == '4'
25-
|| version.minor == '3' && version.patch == '1')))) {
26-
throw new Error('Version of @angular/compiler-cli needs to be 2.3.1 or greater. '
27-
+ `Current version is "${version.full}".`);
28-
}
29-
301
export * from './plugin';
312
export * from './angular_compiler_plugin';
323
export * from './extract_i18n_plugin';

packages/@ngtools/webpack/src/ngtools_api2.ts renamed to packages/@ngtools/webpack/src/ngtools_api.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
// @ignoreDep @angular/compiler-cli
12
/**
23
* This is a copy of types in @compiler-cli/src/ngtools_api.d.ts file,
3-
* together with a safe import to support cases where Angular versions is below 5.
4+
* together with safe imports for private apis for cases where @angular/compiler-cli isn't
5+
* available or is below version 5.
46
*/
7+
import * as path from 'path';
58
import * as ts from 'typescript';
69

710
export const DEFAULT_ERROR_CODE = 100;
@@ -102,6 +105,52 @@ export interface FormatDiagnosticsInterface {
102105
(options: CompilerOptions, diags: Diagnostics): string;
103106
}
104107

108+
// Manually check for Compiler CLI availability and supported version.
109+
// This is needed because @ngtools/webpack does not depend directly on @angular/compiler-cli, since
110+
// it is installed as part of global Angular CLI installs and compiler-cli is not of its
111+
// dependencies.
112+
export function CompilerCliIsSupported() {
113+
let version;
114+
115+
// Check that Angular is available.
116+
try {
117+
version = require('@angular/compiler-cli').VERSION;
118+
} catch (e) {
119+
throw new Error('The "@angular/compiler-cli" package was not properly installed. Error: ' + e);
120+
}
121+
122+
// Check that Angular is also not part of this module's node_modules (it should be the project's).
123+
const compilerCliPath = require.resolve('@angular/compiler-cli');
124+
if (compilerCliPath.startsWith(path.dirname(__dirname))) {
125+
throw new Error('The @ngtools/webpack plugin now relies on the project @angular/compiler-cli. '
126+
+ 'Please clean your node_modules and reinstall.');
127+
}
128+
129+
// Throw if we're neither 2.3.1 or more, nor 4.x.y, nor 5.x.y.
130+
if (!(version.major == '5'
131+
|| version.major == '4'
132+
|| (version.major == '2'
133+
&& (version.minor == '4'
134+
|| version.minor == '3' && version.patch == '1')))) {
135+
throw new Error('Version of @angular/compiler-cli needs to be 2.3.1 or greater. '
136+
+ `Current version is "${version.full}".`);
137+
}
138+
}
139+
140+
// These imports do not exist on a global install for Angular CLI, so we cannot use a static ES6
141+
// import.
142+
let compilerCli: any = {};
143+
try {
144+
compilerCli = require('@angular/compiler-cli');
145+
} catch (e) {
146+
// Don't throw an error if the private API does not exist.
147+
// Instead, the `CompilerCliIsSupported` method should return throw and indicate the
148+
// plugin cannot be used.
149+
}
150+
151+
export const VERSION = compilerCli.VERSION;
152+
export const __NGTOOLS_PRIVATE_API_2 = compilerCli.__NGTOOLS_PRIVATE_API_2;
153+
105154
// These imports do not exist on Angular versions lower than 5, so we cannot use a static ES6
106155
// import.
107156
let ngtools2: any = {};

packages/@ngtools/webpack/src/plugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
// @ignoreDep @angular/compiler-cli
21
import * as fs from 'fs';
32
import * as path from 'path';
43
import * as ts from 'typescript';
54
import * as SourceMap from 'source-map';
65

7-
const {__NGTOOLS_PRIVATE_API_2, VERSION} = require('@angular/compiler-cli');
86
const ContextElementDependency = require('webpack/lib/dependencies/ContextElementDependency');
97
const NodeWatchFileSystem = require('webpack/lib/node/NodeWatchFileSystem');
108

9+
import {CompilerCliIsSupported, __NGTOOLS_PRIVATE_API_2, VERSION} from './ngtools_api';
1110
import {WebpackResourceLoader} from './resource_loader';
1211
import {WebpackCompilerHost} from './compiler_host';
1312
import {resolveEntryModuleFromMain} from './entry_resolver';
@@ -80,6 +79,7 @@ export class AotPlugin implements Tapable {
8079
private _firstRun = true;
8180

8281
constructor(options: AotPluginOptions) {
82+
CompilerCliIsSupported();
8383
this._options = Object.assign({}, options);
8484
this._setupOptions(this._options);
8585
}

packages/@ngtools/webpack/src/type_checker.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// @ignoreDep @angular/compiler-cli
21
import * as process from 'process';
32
import * as ts from 'typescript';
43
import * as chalk from 'chalk';
@@ -13,7 +12,7 @@ import {
1312
createProgram,
1413
createCompilerHost,
1514
formatDiagnostics,
16-
} from './ngtools_api2';
15+
} from './ngtools_api';
1716

1817
// Force basic color support on terminals with no color support.
1918
// Chalk typings don't have the correct constructor parameters.

0 commit comments

Comments
 (0)