@angular-devkit/build-angular 12.0.0-rc.3 → 12.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +21 -21
- package/src/browser/schema.d.ts +1 -1
- package/src/browser/schema.json +1 -1
- package/src/dev-server/index.js +37 -36
- package/src/dev-server/schema.d.ts +2 -1
- package/src/dev-server/schema.json +1 -1
- package/src/extract-i18n/index.js +2 -0
- package/src/karma/schema.d.ts +1 -1
- package/src/karma/schema.json +1 -1
- package/src/sass/sass-service.d.ts +53 -0
- package/src/sass/sass-service.js +186 -0
- package/src/sass/worker.d.ts +8 -0
- package/src/sass/worker.js +49 -0
- package/src/server/schema.d.ts +1 -1
- package/src/server/schema.json +1 -1
- package/src/utils/action-executor.js +2 -2
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +12 -1
- package/src/utils/index.d.ts +0 -1
- package/src/utils/index.js +0 -1
- package/src/utils/service-worker.js +1 -1
- package/src/webpack/configs/common.js +37 -42
- package/src/webpack/configs/server.js +8 -0
- package/src/webpack/configs/stats.d.ts +4 -14
- package/src/webpack/configs/stats.js +4 -8
- package/src/webpack/configs/styles.js +47 -7
- package/src/webpack/plugins/index-html-webpack-plugin.js +1 -1
- package/src/webpack/plugins/index.d.ts +0 -1
- package/src/webpack/plugins/index.js +1 -3
- package/src/webpack/plugins/postcss-cli-resources.js +1 -1
- package/src/webpack/utils/async-chunks.js +2 -6
- package/src/webpack/utils/stats.js +2 -7
- package/src/utils/workers.d.ts +0 -22
- package/src/utils/workers.js +0 -26
- package/src/webpack/plugins/optimize-css-webpack-plugin.d.ts +0 -17
- package/src/webpack/plugins/optimize-css-webpack-plugin.js +0 -106
package/package.json
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular-devkit/build-angular",
|
|
3
|
-
"version": "12.0.
|
|
3
|
+
"version": "12.0.3",
|
|
4
4
|
"description": "Angular Webpack Build Facade",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"typings": "src/index.d.ts",
|
|
7
7
|
"builders": "builders.json",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@angular-devkit/architect": "0.1200.
|
|
10
|
-
"@angular-devkit/build-optimizer": "0.1200.
|
|
11
|
-
"@angular-devkit/build-webpack": "0.1200.
|
|
12
|
-
"@angular-devkit/core": "12.0.
|
|
13
|
-
"@babel/core": "7.14.
|
|
14
|
-
"@babel/generator": "7.14.
|
|
9
|
+
"@angular-devkit/architect": "0.1200.3",
|
|
10
|
+
"@angular-devkit/build-optimizer": "0.1200.3",
|
|
11
|
+
"@angular-devkit/build-webpack": "0.1200.3",
|
|
12
|
+
"@angular-devkit/core": "12.0.3",
|
|
13
|
+
"@babel/core": "7.14.3",
|
|
14
|
+
"@babel/generator": "7.14.3",
|
|
15
15
|
"@babel/plugin-transform-async-to-generator": "7.13.0",
|
|
16
|
-
"@babel/plugin-transform-runtime": "7.
|
|
17
|
-
"@babel/preset-env": "7.14.
|
|
16
|
+
"@babel/plugin-transform-runtime": "7.14.3",
|
|
17
|
+
"@babel/preset-env": "7.14.2",
|
|
18
18
|
"@babel/runtime": "7.14.0",
|
|
19
19
|
"@babel/template": "7.12.13",
|
|
20
20
|
"@discoveryjs/json-ext": "0.5.2",
|
|
21
21
|
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
|
|
22
|
-
"@ngtools/webpack": "12.0.
|
|
22
|
+
"@ngtools/webpack": "12.0.3",
|
|
23
23
|
"ansi-colors": "4.1.1",
|
|
24
24
|
"babel-loader": "8.2.2",
|
|
25
25
|
"browserslist": "^4.9.1",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"core-js": "3.12.0",
|
|
31
31
|
"critters": "0.0.10",
|
|
32
32
|
"css-loader": "5.2.4",
|
|
33
|
-
"
|
|
33
|
+
"css-minimizer-webpack-plugin": "3.0.0",
|
|
34
34
|
"find-cache-dir": "3.3.1",
|
|
35
35
|
"glob": "7.1.7",
|
|
36
36
|
"https-proxy-agent": "5.0.0",
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
"karma-source-map-support": "1.4.0",
|
|
40
40
|
"less": "4.1.1",
|
|
41
41
|
"less-loader": "8.1.1",
|
|
42
|
-
"license-webpack-plugin": "2.3.
|
|
42
|
+
"license-webpack-plugin": "2.3.19",
|
|
43
43
|
"loader-utils": "2.0.0",
|
|
44
44
|
"mini-css-extract-plugin": "1.5.1",
|
|
45
45
|
"minimatch": "3.0.4",
|
|
46
|
-
"open": "8.0.
|
|
46
|
+
"open": "8.0.2",
|
|
47
47
|
"ora": "5.4.0",
|
|
48
48
|
"parse5-html-rewriting-stream": "6.0.1",
|
|
49
|
-
"postcss": "8.
|
|
49
|
+
"postcss": "8.3.0",
|
|
50
50
|
"postcss-import": "14.0.1",
|
|
51
51
|
"postcss-loader": "5.2.0",
|
|
52
52
|
"postcss-preset-env": "6.7.0",
|
|
@@ -65,21 +65,21 @@
|
|
|
65
65
|
"stylus": "0.54.8",
|
|
66
66
|
"stylus-loader": "5.0.0",
|
|
67
67
|
"terser": "5.7.0",
|
|
68
|
-
"terser-webpack-plugin": "
|
|
68
|
+
"terser-webpack-plugin": "5.1.2",
|
|
69
69
|
"text-table": "0.2.0",
|
|
70
70
|
"tree-kill": "1.2.2",
|
|
71
|
-
"webpack": "5.
|
|
71
|
+
"webpack": "5.38.1",
|
|
72
72
|
"webpack-dev-middleware": "4.1.0",
|
|
73
73
|
"webpack-dev-server": "3.11.2",
|
|
74
74
|
"webpack-merge": "5.7.3",
|
|
75
75
|
"webpack-subresource-integrity": "1.5.2"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@angular/compiler-cli": "^12.0.0
|
|
79
|
-
"@angular/localize": "^12.0.0
|
|
80
|
-
"@angular/service-worker": "^12.0.0
|
|
78
|
+
"@angular/compiler-cli": "^12.0.0",
|
|
79
|
+
"@angular/localize": "^12.0.0",
|
|
80
|
+
"@angular/service-worker": "^12.0.0",
|
|
81
81
|
"karma": "^6.3.0",
|
|
82
|
-
"ng-packagr": "^12.0.0
|
|
82
|
+
"ng-packagr": "^12.0.0",
|
|
83
83
|
"protractor": "^7.0.0",
|
|
84
84
|
"tailwindcss": "^2.0.0",
|
|
85
85
|
"tslint": "^6.1.0",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"url": "https://github.com/angular/angular-cli.git"
|
|
121
121
|
},
|
|
122
122
|
"engines": {
|
|
123
|
-
"node": "^12.14.1 ||
|
|
123
|
+
"node": "^12.14.1 || >=14.0.0",
|
|
124
124
|
"npm": "^6.11.0 || ^7.5.6",
|
|
125
125
|
"yarn": ">= 1.13.0"
|
|
126
126
|
},
|
package/src/browser/schema.d.ts
CHANGED
|
@@ -407,7 +407,7 @@ export interface SourceMapClass {
|
|
|
407
407
|
*/
|
|
408
408
|
export interface StylePreprocessorOptions {
|
|
409
409
|
/**
|
|
410
|
-
* Paths to include. Paths will be resolved to
|
|
410
|
+
* Paths to include. Paths will be resolved to workspace root.
|
|
411
411
|
*/
|
|
412
412
|
includePaths?: string[];
|
|
413
413
|
}
|
package/src/browser/schema.json
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"type": "object",
|
|
52
52
|
"properties": {
|
|
53
53
|
"includePaths": {
|
|
54
|
-
"description": "Paths to include. Paths will be resolved to
|
|
54
|
+
"description": "Paths to include. Paths will be resolved to workspace root.",
|
|
55
55
|
"type": "array",
|
|
56
56
|
"items": {
|
|
57
57
|
"type": "string"
|
package/src/dev-server/index.js
CHANGED
|
@@ -84,11 +84,47 @@ function serveWebpackBrowser(options, context, transforms = {}) {
|
|
|
84
84
|
overrides.outputHashing = schema_1.OutputHashing.None;
|
|
85
85
|
logger.warn(`Warning: 'outputHashing' option is disabled when using the dev-server.`);
|
|
86
86
|
}
|
|
87
|
+
if (options.hmr) {
|
|
88
|
+
logger.warn(core_1.tags.stripIndents `NOTICE: Hot Module Replacement (HMR) is enabled for the dev server.
|
|
89
|
+
See https://webpack.js.org/guides/hot-module-replacement for information on working with HMR for Webpack.`);
|
|
90
|
+
}
|
|
91
|
+
if (!options.disableHostCheck &&
|
|
92
|
+
options.host &&
|
|
93
|
+
!/^127\.\d+\.\d+\.\d+/g.test(options.host) &&
|
|
94
|
+
options.host !== 'localhost') {
|
|
95
|
+
logger.warn(core_1.tags.stripIndent `
|
|
96
|
+
Warning: This is a simple server for use in testing or debugging Angular applications
|
|
97
|
+
locally. It hasn't been reviewed for security issues.
|
|
98
|
+
|
|
99
|
+
Binding this server to an open connection can result in compromising your application or
|
|
100
|
+
computer. Using a different host than the one passed to the "--host" flag might result in
|
|
101
|
+
websocket connection issues. You might need to use "--disableHostCheck" if that's the
|
|
102
|
+
case.
|
|
103
|
+
`);
|
|
104
|
+
}
|
|
105
|
+
if (options.disableHostCheck) {
|
|
106
|
+
logger.warn(core_1.tags.oneLine `
|
|
107
|
+
Warning: Running a server with --disable-host-check is a security risk.
|
|
108
|
+
See https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
|
|
109
|
+
for more information.
|
|
110
|
+
`);
|
|
111
|
+
}
|
|
87
112
|
// Webpack's live reload functionality adds the `strip-ansi` package which is commonJS
|
|
88
113
|
(_b = rawBrowserOptions.allowedCommonJsDependencies) !== null && _b !== void 0 ? _b : (rawBrowserOptions.allowedCommonJsDependencies = []);
|
|
89
114
|
rawBrowserOptions.allowedCommonJsDependencies.push('strip-ansi');
|
|
90
115
|
const browserName = await context.getBuilderNameForTarget(browserTarget);
|
|
91
116
|
const browserOptions = (await context.validateOptions({ ...rawBrowserOptions, ...overrides }, browserName));
|
|
117
|
+
const { styles, scripts } = utils_1.normalizeOptimization(browserOptions.optimization);
|
|
118
|
+
if (scripts || styles.minify) {
|
|
119
|
+
logger.error(core_1.tags.stripIndents `
|
|
120
|
+
****************************************************************************************
|
|
121
|
+
This is a simple server for use in testing or debugging Angular applications locally.
|
|
122
|
+
It hasn't been reviewed for security issues.
|
|
123
|
+
|
|
124
|
+
DON'T USE IT FOR PRODUCTION!
|
|
125
|
+
****************************************************************************************
|
|
126
|
+
`);
|
|
127
|
+
}
|
|
92
128
|
const { config, projectRoot, i18n } = await webpack_browser_config_1.generateI18nBrowserWebpackConfigFromContext(browserOptions, context, (wco) => [
|
|
93
129
|
configs_1.getDevServerConfig(wco),
|
|
94
130
|
configs_1.getCommonConfig(wco),
|
|
@@ -129,30 +165,6 @@ function serveWebpackBrowser(options, context, transforms = {}) {
|
|
|
129
165
|
}
|
|
130
166
|
}
|
|
131
167
|
}
|
|
132
|
-
if (options.hmr) {
|
|
133
|
-
logger.warn(core_1.tags.stripIndents `NOTICE: Hot Module Replacement (HMR) is enabled for the dev server.
|
|
134
|
-
See https://webpack.js.org/guides/hot-module-replacement for information on working with HMR for Webpack.`);
|
|
135
|
-
}
|
|
136
|
-
if (options.host &&
|
|
137
|
-
!/^127\.\d+\.\d+\.\d+/g.test(options.host) &&
|
|
138
|
-
options.host !== 'localhost') {
|
|
139
|
-
logger.warn(core_1.tags.stripIndent `
|
|
140
|
-
Warning: This is a simple server for use in testing or debugging Angular applications
|
|
141
|
-
locally. It hasn't been reviewed for security issues.
|
|
142
|
-
|
|
143
|
-
Binding this server to an open connection can result in compromising your application or
|
|
144
|
-
computer. Using a different host than the one passed to the "--host" flag might result in
|
|
145
|
-
websocket connection issues. You might need to use "--disableHostCheck" if that's the
|
|
146
|
-
case.
|
|
147
|
-
`);
|
|
148
|
-
}
|
|
149
|
-
if (options.disableHostCheck) {
|
|
150
|
-
logger.warn(core_1.tags.oneLine `
|
|
151
|
-
Warning: Running a server with --disable-host-check is a security risk.
|
|
152
|
-
See https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
|
|
153
|
-
for more information.
|
|
154
|
-
`);
|
|
155
|
-
}
|
|
156
168
|
let locale;
|
|
157
169
|
if (i18n.shouldInline) {
|
|
158
170
|
// Dev-server only supports one locale
|
|
@@ -185,7 +197,6 @@ function serveWebpackBrowser(options, context, transforms = {}) {
|
|
|
185
197
|
};
|
|
186
198
|
}
|
|
187
199
|
return rxjs_1.from(setup()).pipe(operators_1.switchMap(({ browserOptions, webpackConfig, projectRoot, locale }) => {
|
|
188
|
-
const normalizedOptimization = utils_1.normalizeOptimization(browserOptions.optimization);
|
|
189
200
|
if (browserOptions.index) {
|
|
190
201
|
const { scripts = [], styles = [], baseHref, tsConfig } = browserOptions;
|
|
191
202
|
const { options: compilerOptions } = read_tsconfig_1.readTsconfig(tsConfig, workspaceRoot);
|
|
@@ -206,22 +217,12 @@ function serveWebpackBrowser(options, context, transforms = {}) {
|
|
|
206
217
|
deployUrl: browserOptions.deployUrl,
|
|
207
218
|
sri: browserOptions.subresourceIntegrity,
|
|
208
219
|
postTransform: transforms.indexHtml,
|
|
209
|
-
optimization:
|
|
220
|
+
optimization: utils_1.normalizeOptimization(browserOptions.optimization),
|
|
210
221
|
WOFFSupportNeeded: !buildBrowserFeatures.isFeatureSupported('woff2'),
|
|
211
222
|
crossOrigin: browserOptions.crossOrigin,
|
|
212
223
|
lang: locale,
|
|
213
224
|
}));
|
|
214
225
|
}
|
|
215
|
-
if (normalizedOptimization.scripts || normalizedOptimization.styles.minify) {
|
|
216
|
-
logger.error(core_1.tags.stripIndents `
|
|
217
|
-
****************************************************************************************
|
|
218
|
-
This is a simple server for use in testing or debugging Angular applications locally.
|
|
219
|
-
It hasn't been reviewed for security issues.
|
|
220
|
-
|
|
221
|
-
DON'T USE IT FOR PRODUCTION!
|
|
222
|
-
****************************************************************************************
|
|
223
|
-
`);
|
|
224
|
-
}
|
|
225
226
|
return build_webpack_1.runWebpackDevServer(webpackConfig, context, {
|
|
226
227
|
logging: transforms.logging || stats_1.createWebpackLoggingCallback(!!options.verbose, logger),
|
|
227
228
|
webpackFactory: require('webpack'),
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"proxyConfig": {
|
|
23
23
|
"type": "string",
|
|
24
|
-
"description": "Proxy configuration file."
|
|
24
|
+
"description": "Proxy configuration file. For more information, see https://angular.io/guide/build#proxying-to-a-backend-server."
|
|
25
25
|
},
|
|
26
26
|
"ssl": {
|
|
27
27
|
"type": "boolean",
|
|
@@ -150,6 +150,7 @@ async function execute(options, context, transforms) {
|
|
|
150
150
|
configs_1.getCommonConfig(wco),
|
|
151
151
|
configs_1.getBrowserConfig(wco),
|
|
152
152
|
configs_1.getTypeScriptConfig(wco),
|
|
153
|
+
configs_1.getWorkerConfig(wco),
|
|
153
154
|
configs_1.getStatsConfig(wco),
|
|
154
155
|
];
|
|
155
156
|
// Add Ivy application file extractor support
|
|
@@ -170,6 +171,7 @@ async function execute(options, context, transforms) {
|
|
|
170
171
|
partials.push({
|
|
171
172
|
plugins: [
|
|
172
173
|
new webpack.NormalModuleReplacementPlugin(/\.(css|scss|sass|styl|less)$/, path.join(__dirname, 'empty-export-default.js')),
|
|
174
|
+
new webpack.NormalModuleReplacementPlugin(/^angular-resource:style,/, path.join(__dirname, 'empty-export-default.js')),
|
|
173
175
|
],
|
|
174
176
|
});
|
|
175
177
|
return partials;
|
package/src/karma/schema.d.ts
CHANGED
|
@@ -167,7 +167,7 @@ export interface SourceMapClass {
|
|
|
167
167
|
*/
|
|
168
168
|
export interface StylePreprocessorOptions {
|
|
169
169
|
/**
|
|
170
|
-
* Paths to include. Paths will be resolved to
|
|
170
|
+
* Paths to include. Paths will be resolved to workspace root.
|
|
171
171
|
*/
|
|
172
172
|
includePaths?: string[];
|
|
173
173
|
}
|
package/src/karma/schema.json
CHANGED
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"type": "object",
|
|
56
56
|
"properties": {
|
|
57
57
|
"includePaths": {
|
|
58
|
-
"description": "Paths to include. Paths will be resolved to
|
|
58
|
+
"description": "Paths to include. Paths will be resolved to workspace root.",
|
|
59
59
|
"type": "array",
|
|
60
60
|
"items": {
|
|
61
61
|
"type": "string"
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
import { Options, Result, SassException } from 'sass';
|
|
9
|
+
/**
|
|
10
|
+
* The callback type for the `dart-sass` asynchronous render function.
|
|
11
|
+
*/
|
|
12
|
+
declare type RenderCallback = (error?: SassException, result?: Result) => void;
|
|
13
|
+
/**
|
|
14
|
+
* A Sass renderer implementation that provides an interface that can be used by Webpack's
|
|
15
|
+
* `sass-loader`. The implementation uses a Worker thread to perform the Sass rendering
|
|
16
|
+
* with the `dart-sass` package. The `dart-sass` synchronous render function is used within
|
|
17
|
+
* the worker which can be up to two times faster than the asynchronous variant.
|
|
18
|
+
*/
|
|
19
|
+
export declare class SassWorkerImplementation {
|
|
20
|
+
private readonly workers;
|
|
21
|
+
private readonly availableWorkers;
|
|
22
|
+
private readonly requests;
|
|
23
|
+
private idCounter;
|
|
24
|
+
private nextWorkerIndex;
|
|
25
|
+
/**
|
|
26
|
+
* Provides information about the Sass implementation.
|
|
27
|
+
* This mimics enough of the `dart-sass` value to be used with the `sass-loader`.
|
|
28
|
+
*/
|
|
29
|
+
get info(): string;
|
|
30
|
+
/**
|
|
31
|
+
* The synchronous render function is not used by the `sass-loader`.
|
|
32
|
+
*/
|
|
33
|
+
renderSync(): never;
|
|
34
|
+
/**
|
|
35
|
+
* Asynchronously request a Sass stylesheet to be renderered.
|
|
36
|
+
*
|
|
37
|
+
* @param options The `dart-sass` options to use when rendering the stylesheet.
|
|
38
|
+
* @param callback The function to execute when the rendering is complete.
|
|
39
|
+
*/
|
|
40
|
+
render(options: Options, callback: RenderCallback): void;
|
|
41
|
+
/**
|
|
42
|
+
* Shutdown the Sass render worker.
|
|
43
|
+
* Executing this method will stop any pending render requests.
|
|
44
|
+
*
|
|
45
|
+
* The worker is unreferenced upon creation and will not block application exit. This method
|
|
46
|
+
* is only needed if early cleanup is needed.
|
|
47
|
+
*/
|
|
48
|
+
close(): void;
|
|
49
|
+
private createWorker;
|
|
50
|
+
private processImporters;
|
|
51
|
+
private createRequest;
|
|
52
|
+
}
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SassWorkerImplementation = void 0;
|
|
11
|
+
const worker_threads_1 = require("worker_threads");
|
|
12
|
+
const environment_options_1 = require("../utils/environment-options");
|
|
13
|
+
/**
|
|
14
|
+
* The maximum number of Workers that will be created to execute render requests.
|
|
15
|
+
*/
|
|
16
|
+
const MAX_RENDER_WORKERS = environment_options_1.maxWorkers;
|
|
17
|
+
/**
|
|
18
|
+
* Workaround required for lack of new Worker transfer list support in Node.js prior to 12.17
|
|
19
|
+
*/
|
|
20
|
+
let transferListWorkaround = false;
|
|
21
|
+
const version = process.versions.node.split('.').map((part) => Number(part));
|
|
22
|
+
if (version[0] === 12 && version[1] < 17) {
|
|
23
|
+
transferListWorkaround = true;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A Sass renderer implementation that provides an interface that can be used by Webpack's
|
|
27
|
+
* `sass-loader`. The implementation uses a Worker thread to perform the Sass rendering
|
|
28
|
+
* with the `dart-sass` package. The `dart-sass` synchronous render function is used within
|
|
29
|
+
* the worker which can be up to two times faster than the asynchronous variant.
|
|
30
|
+
*/
|
|
31
|
+
class SassWorkerImplementation {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.workers = [];
|
|
34
|
+
this.availableWorkers = [];
|
|
35
|
+
this.requests = new Map();
|
|
36
|
+
this.idCounter = 1;
|
|
37
|
+
this.nextWorkerIndex = 0;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Provides information about the Sass implementation.
|
|
41
|
+
* This mimics enough of the `dart-sass` value to be used with the `sass-loader`.
|
|
42
|
+
*/
|
|
43
|
+
get info() {
|
|
44
|
+
return 'dart-sass\tworker';
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The synchronous render function is not used by the `sass-loader`.
|
|
48
|
+
*/
|
|
49
|
+
renderSync() {
|
|
50
|
+
throw new Error('Sass renderSync is not supported.');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Asynchronously request a Sass stylesheet to be renderered.
|
|
54
|
+
*
|
|
55
|
+
* @param options The `dart-sass` options to use when rendering the stylesheet.
|
|
56
|
+
* @param callback The function to execute when the rendering is complete.
|
|
57
|
+
*/
|
|
58
|
+
render(options, callback) {
|
|
59
|
+
// The `functions` and `importer` options are JavaScript functions that cannot be transferred.
|
|
60
|
+
// If any additional function options are added in the future, they must be excluded as well.
|
|
61
|
+
const { functions, importer, ...serializableOptions } = options;
|
|
62
|
+
// The CLI's configuration does not use or expose the ability to defined custom Sass functions
|
|
63
|
+
if (functions && Object.keys(functions).length > 0) {
|
|
64
|
+
throw new Error('Sass custom functions are not supported.');
|
|
65
|
+
}
|
|
66
|
+
let workerIndex = this.availableWorkers.pop();
|
|
67
|
+
if (workerIndex === undefined) {
|
|
68
|
+
if (this.workers.length < MAX_RENDER_WORKERS) {
|
|
69
|
+
workerIndex = this.workers.length;
|
|
70
|
+
this.workers.push(this.createWorker());
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
workerIndex = this.nextWorkerIndex++;
|
|
74
|
+
if (this.nextWorkerIndex >= this.workers.length) {
|
|
75
|
+
this.nextWorkerIndex = 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const request = this.createRequest(workerIndex, callback, importer);
|
|
80
|
+
this.requests.set(request.id, request);
|
|
81
|
+
this.workers[workerIndex].postMessage({
|
|
82
|
+
id: request.id,
|
|
83
|
+
hasImporter: !!importer,
|
|
84
|
+
options: serializableOptions,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Shutdown the Sass render worker.
|
|
89
|
+
* Executing this method will stop any pending render requests.
|
|
90
|
+
*
|
|
91
|
+
* The worker is unreferenced upon creation and will not block application exit. This method
|
|
92
|
+
* is only needed if early cleanup is needed.
|
|
93
|
+
*/
|
|
94
|
+
close() {
|
|
95
|
+
for (const worker of this.workers) {
|
|
96
|
+
void worker.terminate();
|
|
97
|
+
}
|
|
98
|
+
this.requests.clear();
|
|
99
|
+
}
|
|
100
|
+
createWorker() {
|
|
101
|
+
const { port1: mainImporterPort, port2: workerImporterPort } = new worker_threads_1.MessageChannel();
|
|
102
|
+
const importerSignal = new Int32Array(new SharedArrayBuffer(4));
|
|
103
|
+
const workerPath = require.resolve('./worker');
|
|
104
|
+
const worker = new worker_threads_1.Worker(workerPath, {
|
|
105
|
+
workerData: transferListWorkaround ? undefined : { workerImporterPort, importerSignal },
|
|
106
|
+
transferList: transferListWorkaround ? undefined : [workerImporterPort],
|
|
107
|
+
});
|
|
108
|
+
if (transferListWorkaround) {
|
|
109
|
+
worker.postMessage({ init: true, workerImporterPort, importerSignal }, [workerImporterPort]);
|
|
110
|
+
}
|
|
111
|
+
worker.on('message', (response) => {
|
|
112
|
+
const request = this.requests.get(response.id);
|
|
113
|
+
if (!request) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.requests.delete(response.id);
|
|
117
|
+
this.availableWorkers.push(request.workerIndex);
|
|
118
|
+
if (response.result) {
|
|
119
|
+
// The results are expected to be Node.js `Buffer` objects but will each be transferred as
|
|
120
|
+
// a Uint8Array that does not have the expected `toString` behavior of a `Buffer`.
|
|
121
|
+
const { css, map, stats } = response.result;
|
|
122
|
+
const result = {
|
|
123
|
+
// This `Buffer.from` override will use the memory directly and avoid making a copy
|
|
124
|
+
css: Buffer.from(css.buffer, css.byteOffset, css.byteLength),
|
|
125
|
+
stats,
|
|
126
|
+
};
|
|
127
|
+
if (map) {
|
|
128
|
+
// This `Buffer.from` override will use the memory directly and avoid making a copy
|
|
129
|
+
result.map = Buffer.from(map.buffer, map.byteOffset, map.byteLength);
|
|
130
|
+
}
|
|
131
|
+
request.callback(undefined, result);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
request.callback(response.error);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
mainImporterPort.on('message', ({ id, url, prev }) => {
|
|
138
|
+
const request = this.requests.get(id);
|
|
139
|
+
if (!(request === null || request === void 0 ? void 0 : request.importers)) {
|
|
140
|
+
mainImporterPort.postMessage(null);
|
|
141
|
+
Atomics.store(importerSignal, 0, 1);
|
|
142
|
+
Atomics.notify(importerSignal, 0);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.processImporters(request.importers, url, prev)
|
|
146
|
+
.then((result) => {
|
|
147
|
+
mainImporterPort.postMessage(result);
|
|
148
|
+
})
|
|
149
|
+
.catch((error) => {
|
|
150
|
+
mainImporterPort.postMessage(error);
|
|
151
|
+
})
|
|
152
|
+
.finally(() => {
|
|
153
|
+
Atomics.store(importerSignal, 0, 1);
|
|
154
|
+
Atomics.notify(importerSignal, 0);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
worker.unref();
|
|
158
|
+
mainImporterPort.unref();
|
|
159
|
+
return worker;
|
|
160
|
+
}
|
|
161
|
+
async processImporters(importers, url, prev) {
|
|
162
|
+
let result = null;
|
|
163
|
+
for (const importer of importers) {
|
|
164
|
+
result = await new Promise((resolve) => {
|
|
165
|
+
// Importers can be both sync and async
|
|
166
|
+
const innerResult = importer(url, prev, resolve);
|
|
167
|
+
if (innerResult !== undefined) {
|
|
168
|
+
resolve(innerResult);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
if (result) {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
createRequest(workerIndex, callback, importer) {
|
|
178
|
+
return {
|
|
179
|
+
id: this.idCounter++,
|
|
180
|
+
workerIndex,
|
|
181
|
+
callback,
|
|
182
|
+
importers: !importer || Array.isArray(importer) ? importer : [importer],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
exports.SassWorkerImplementation = SassWorkerImplementation;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const sass_1 = require("sass");
|
|
11
|
+
const worker_threads_1 = require("worker_threads");
|
|
12
|
+
if (!worker_threads_1.parentPort) {
|
|
13
|
+
throw new Error('Sass worker must be executed as a Worker.');
|
|
14
|
+
}
|
|
15
|
+
// The importer variables are used to proxy import requests to the main thread
|
|
16
|
+
let { workerImporterPort, importerSignal } = (worker_threads_1.workerData || {});
|
|
17
|
+
worker_threads_1.parentPort.on('message', (message) => {
|
|
18
|
+
// The init message is only needed to support Node.js < 12.17 and can be removed once support is dropped
|
|
19
|
+
if (message.init) {
|
|
20
|
+
workerImporterPort = message.workerImporterPort;
|
|
21
|
+
importerSignal = message.importerSignal;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const { id, hasImporter, options } = message;
|
|
25
|
+
try {
|
|
26
|
+
if (hasImporter) {
|
|
27
|
+
// When a custom importer function is present, the importer request must be proxied
|
|
28
|
+
// back to the main thread where it can be executed.
|
|
29
|
+
// This process must be synchronous from the perspective of dart-sass. The `Atomics`
|
|
30
|
+
// functions combined with the shared memory `importSignal` and the Node.js
|
|
31
|
+
// `receiveMessageOnPort` function are used to ensure synchronous behavior.
|
|
32
|
+
options.importer = (url, prev) => {
|
|
33
|
+
var _a;
|
|
34
|
+
Atomics.store(importerSignal, 0, 0);
|
|
35
|
+
workerImporterPort.postMessage({ id, url, prev });
|
|
36
|
+
Atomics.wait(importerSignal, 0, 0);
|
|
37
|
+
return (_a = worker_threads_1.receiveMessageOnPort(workerImporterPort)) === null || _a === void 0 ? void 0 : _a.message;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// The synchronous Sass render function can be up to two times faster than the async variant
|
|
41
|
+
const result = sass_1.renderSync(options);
|
|
42
|
+
worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage({ id, result });
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
// Needed because V8 will only serialize the message and stack properties of an Error instance.
|
|
46
|
+
const { formatted, file, line, column, message, stack } = error;
|
|
47
|
+
worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage({ id, error: { formatted, file, line, column, message, stack } });
|
|
48
|
+
}
|
|
49
|
+
});
|
package/src/server/schema.d.ts
CHANGED
|
@@ -198,7 +198,7 @@ export interface SourceMapClass {
|
|
|
198
198
|
*/
|
|
199
199
|
export interface StylePreprocessorOptions {
|
|
200
200
|
/**
|
|
201
|
-
* Paths to include. Paths will be resolved to
|
|
201
|
+
* Paths to include. Paths will be resolved to workspace root.
|
|
202
202
|
*/
|
|
203
203
|
includePaths?: string[];
|
|
204
204
|
}
|
package/src/server/schema.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"type": "object",
|
|
25
25
|
"properties": {
|
|
26
26
|
"includePaths": {
|
|
27
|
-
"description": "Paths to include. Paths will be resolved to
|
|
27
|
+
"description": "Paths to include. Paths will be resolved to workspace root.",
|
|
28
28
|
"type": "array",
|
|
29
29
|
"items": {
|
|
30
30
|
"type": "string"
|
|
@@ -13,7 +13,7 @@ const os = require("os");
|
|
|
13
13
|
const path = require("path");
|
|
14
14
|
const v8_1 = require("v8");
|
|
15
15
|
const action_cache_1 = require("./action-cache");
|
|
16
|
-
const
|
|
16
|
+
const environment_options_1 = require("./environment-options");
|
|
17
17
|
let workerFile = require.resolve('./process-bundle');
|
|
18
18
|
workerFile =
|
|
19
19
|
path.extname(workerFile) === '.ts' ? require.resolve('./process-bundle-bootstrap') : workerFile;
|
|
@@ -36,7 +36,7 @@ class BundleActionExecutor {
|
|
|
36
36
|
return (this.largeWorker = new jest_worker_1.default(workerFile, {
|
|
37
37
|
exposedMethods: ['process', 'inlineLocales'],
|
|
38
38
|
setupArgs: [[...v8_1.serialize(this.workerOptions)]],
|
|
39
|
-
numWorkers:
|
|
39
|
+
numWorkers: environment_options_1.maxWorkers,
|
|
40
40
|
}));
|
|
41
41
|
}
|
|
42
42
|
ensureSmall() {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.profilingEnabled = exports.cachingBasePath = exports.cachingDisabled = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
10
|
+
exports.maxWorkers = exports.profilingEnabled = exports.cachingBasePath = exports.cachingDisabled = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
11
11
|
const path = require("path");
|
|
12
12
|
function isDisabled(variable) {
|
|
13
13
|
return variable === '0' || variable.toLowerCase() === 'false';
|
|
@@ -72,3 +72,14 @@ exports.cachingBasePath = (() => {
|
|
|
72
72
|
// Build profiling
|
|
73
73
|
const profilingVariable = process.env['NG_BUILD_PROFILING'];
|
|
74
74
|
exports.profilingEnabled = isPresent(profilingVariable) && isEnabled(profilingVariable);
|
|
75
|
+
/**
|
|
76
|
+
* Some environments, like CircleCI which use Docker report a number of CPUs by the host and not the count of available.
|
|
77
|
+
* This cause `Error: Call retries were exceeded` errors when trying to use them.
|
|
78
|
+
*
|
|
79
|
+
* @see https://github.com/nodejs/node/issues/28762
|
|
80
|
+
* @see https://github.com/webpack-contrib/terser-webpack-plugin/issues/143
|
|
81
|
+
* @see https://ithub.com/angular/angular-cli/issues/16860#issuecomment-588828079
|
|
82
|
+
*
|
|
83
|
+
*/
|
|
84
|
+
const maxWorkersVariable = process.env['NG_BUILD_MAX_WORKERS'];
|
|
85
|
+
exports.maxWorkers = isPresent(maxWorkersVariable) ? +maxWorkersVariable : 4;
|
package/src/utils/index.d.ts
CHANGED