@angular-devkit/build-angular 15.0.0-next.1 → 15.0.0-next.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 +15 -17
- package/src/babel/presets/application.d.ts +1 -2
- package/src/babel/presets/application.js +1 -4
- package/src/babel/webpack-loader.js +8 -22
- package/src/builders/app-shell/index.js +16 -8
- package/src/builders/browser/index.d.ts +1 -1
- package/src/builders/browser/index.js +4 -16
- package/src/builders/browser/schema.d.ts +6 -2
- package/src/builders/browser/schema.json +18 -4
- package/src/builders/browser-esbuild/compiler-plugin.d.ts +1 -0
- package/src/builders/browser-esbuild/compiler-plugin.js +20 -17
- package/src/builders/browser-esbuild/experimental-warnings.js +0 -1
- package/src/builders/browser-esbuild/index.js +18 -5
- package/src/builders/browser-esbuild/options.js +6 -1
- package/src/builders/browser-esbuild/schema.d.ts +8 -6
- package/src/builders/browser-esbuild/schema.json +29 -34
- package/src/builders/browser-esbuild/stylesheets.d.ts +1 -0
- package/src/builders/browser-esbuild/stylesheets.js +1 -0
- package/src/builders/extract-i18n/index.js +1 -1
- package/src/builders/karma/find-tests-plugin.d.ts +19 -0
- package/src/builders/karma/{find-tests.js → find-tests-plugin.js} +49 -5
- package/src/builders/karma/index.js +40 -38
- package/src/builders/karma/schema.d.ts +7 -3
- package/src/builders/karma/schema.json +20 -5
- package/src/builders/server/index.d.ts +1 -1
- package/src/builders/server/index.js +42 -10
- package/src/builders/server/platform-server-exports-loader.d.ts +13 -0
- package/src/builders/server/platform-server-exports-loader.js +24 -0
- package/src/builders/server/schema.d.ts +0 -5
- package/src/builders/server/schema.json +0 -5
- package/src/sass/sass-service-legacy.d.ts +51 -0
- package/src/sass/sass-service-legacy.js +175 -0
- package/src/sass/sass-service.d.ts +6 -9
- package/src/sass/sass-service.js +69 -52
- package/src/{builders/karma/find-tests.d.ts → sass/worker-legacy.d.ts} +1 -1
- package/src/sass/worker-legacy.js +44 -0
- package/src/sass/worker.js +64 -14
- package/src/utils/build-options.d.ts +2 -4
- package/src/utils/environment-options.d.ts +1 -0
- package/src/utils/environment-options.js +11 -1
- package/src/utils/esbuild-targets.d.ts +12 -0
- package/src/utils/esbuild-targets.js +39 -0
- package/src/utils/i18n-inlining.d.ts +1 -1
- package/src/utils/i18n-inlining.js +3 -4
- package/src/utils/normalize-builder-schema.d.ts +3 -2
- package/src/utils/normalize-builder-schema.js +5 -4
- package/src/utils/normalize-polyfills.d.ts +8 -0
- package/src/utils/normalize-polyfills.js +24 -0
- package/src/utils/process-bundle.d.ts +0 -1
- package/src/utils/process-bundle.js +29 -57
- package/src/utils/supported-browsers.d.ts +2 -1
- package/src/utils/supported-browsers.js +18 -2
- package/src/utils/webpack-browser-config.d.ts +0 -2
- package/src/utils/webpack-browser-config.js +2 -8
- package/src/utils/webpack-diagnostics.d.ts +1 -1
- package/src/utils/webpack-diagnostics.js +2 -3
- package/src/webpack/configs/common.js +37 -24
- package/src/webpack/configs/dev-server.js +1 -1
- package/src/webpack/configs/styles.js +63 -80
- package/src/webpack/plugins/any-component-style-budget-checker.js +1 -1
- package/src/webpack/plugins/css-optimizer-plugin.d.ts +0 -1
- package/src/webpack/plugins/css-optimizer-plugin.js +3 -26
- package/src/webpack/plugins/hmr/hmr-loader.d.ts +1 -1
- package/src/webpack/plugins/hmr/hmr-loader.js +2 -5
- package/src/webpack/plugins/javascript-optimizer-plugin.d.ts +4 -6
- package/src/webpack/plugins/javascript-optimizer-plugin.js +7 -16
- package/src/webpack/plugins/javascript-optimizer-worker.d.ts +3 -2
- package/src/webpack/plugins/javascript-optimizer-worker.js +21 -46
- package/src/webpack/plugins/karma/karma.js +4 -5
- package/src/webpack/plugins/transfer-size-plugin.js +2 -1
- package/src/webpack/plugins/typescript.js +14 -25
- package/src/webpack/utils/helpers.d.ts +0 -3
- package/src/webpack/utils/helpers.js +1 -36
- package/src/webpack/plugins/single-test-transform.d.ts +0 -27
- package/src/webpack/plugins/single-test-transform.js +0 -44
|
@@ -0,0 +1,175 @@
|
|
|
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.SassLegacyWorkerImplementation = void 0;
|
|
11
|
+
const path_1 = require("path");
|
|
12
|
+
const worker_threads_1 = require("worker_threads");
|
|
13
|
+
const environment_options_1 = require("../utils/environment-options");
|
|
14
|
+
/**
|
|
15
|
+
* The maximum number of Workers that will be created to execute render requests.
|
|
16
|
+
*/
|
|
17
|
+
const MAX_RENDER_WORKERS = environment_options_1.maxWorkers;
|
|
18
|
+
/**
|
|
19
|
+
* A Sass renderer implementation that provides an interface that can be used by Webpack's
|
|
20
|
+
* `sass-loader`. The implementation uses a Worker thread to perform the Sass rendering
|
|
21
|
+
* with the `dart-sass` package. The `dart-sass` synchronous render function is used within
|
|
22
|
+
* the worker which can be up to two times faster than the asynchronous variant.
|
|
23
|
+
*/
|
|
24
|
+
class SassLegacyWorkerImplementation {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.workers = [];
|
|
27
|
+
this.availableWorkers = [];
|
|
28
|
+
this.requests = new Map();
|
|
29
|
+
this.workerPath = (0, path_1.join)(__dirname, './worker-legacy.js');
|
|
30
|
+
this.idCounter = 1;
|
|
31
|
+
this.nextWorkerIndex = 0;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Provides information about the Sass implementation.
|
|
35
|
+
* This mimics enough of the `dart-sass` value to be used with the `sass-loader`.
|
|
36
|
+
*/
|
|
37
|
+
get info() {
|
|
38
|
+
return 'dart-sass\tworker';
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The synchronous render function is not used by the `sass-loader`.
|
|
42
|
+
*/
|
|
43
|
+
renderSync() {
|
|
44
|
+
throw new Error('Sass renderSync is not supported.');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Asynchronously request a Sass stylesheet to be renderered.
|
|
48
|
+
*
|
|
49
|
+
* @param options The `dart-sass` options to use when rendering the stylesheet.
|
|
50
|
+
* @param callback The function to execute when the rendering is complete.
|
|
51
|
+
*/
|
|
52
|
+
render(options, callback) {
|
|
53
|
+
// The `functions`, `logger` and `importer` options are JavaScript functions that cannot be transferred.
|
|
54
|
+
// If any additional function options are added in the future, they must be excluded as well.
|
|
55
|
+
const { functions, importer, logger, ...serializableOptions } = options;
|
|
56
|
+
// The CLI's configuration does not use or expose the ability to defined custom Sass functions
|
|
57
|
+
if (functions && Object.keys(functions).length > 0) {
|
|
58
|
+
throw new Error('Sass custom functions are not supported.');
|
|
59
|
+
}
|
|
60
|
+
let workerIndex = this.availableWorkers.pop();
|
|
61
|
+
if (workerIndex === undefined) {
|
|
62
|
+
if (this.workers.length < MAX_RENDER_WORKERS) {
|
|
63
|
+
workerIndex = this.workers.length;
|
|
64
|
+
this.workers.push(this.createWorker());
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
workerIndex = this.nextWorkerIndex++;
|
|
68
|
+
if (this.nextWorkerIndex >= this.workers.length) {
|
|
69
|
+
this.nextWorkerIndex = 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const request = this.createRequest(workerIndex, callback, importer);
|
|
74
|
+
this.requests.set(request.id, request);
|
|
75
|
+
this.workers[workerIndex].postMessage({
|
|
76
|
+
id: request.id,
|
|
77
|
+
hasImporter: !!importer,
|
|
78
|
+
options: serializableOptions,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Shutdown the Sass render worker.
|
|
83
|
+
* Executing this method will stop any pending render requests.
|
|
84
|
+
*/
|
|
85
|
+
close() {
|
|
86
|
+
for (const worker of this.workers) {
|
|
87
|
+
try {
|
|
88
|
+
void worker.terminate();
|
|
89
|
+
}
|
|
90
|
+
catch { }
|
|
91
|
+
}
|
|
92
|
+
this.requests.clear();
|
|
93
|
+
}
|
|
94
|
+
createWorker() {
|
|
95
|
+
const { port1: mainImporterPort, port2: workerImporterPort } = new worker_threads_1.MessageChannel();
|
|
96
|
+
const importerSignal = new Int32Array(new SharedArrayBuffer(4));
|
|
97
|
+
const worker = new worker_threads_1.Worker(this.workerPath, {
|
|
98
|
+
workerData: { workerImporterPort, importerSignal },
|
|
99
|
+
transferList: [workerImporterPort],
|
|
100
|
+
});
|
|
101
|
+
worker.on('message', (response) => {
|
|
102
|
+
const request = this.requests.get(response.id);
|
|
103
|
+
if (!request) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this.requests.delete(response.id);
|
|
107
|
+
this.availableWorkers.push(request.workerIndex);
|
|
108
|
+
if (response.result) {
|
|
109
|
+
// The results are expected to be Node.js `Buffer` objects but will each be transferred as
|
|
110
|
+
// a Uint8Array that does not have the expected `toString` behavior of a `Buffer`.
|
|
111
|
+
const { css, map, stats } = response.result;
|
|
112
|
+
const result = {
|
|
113
|
+
// This `Buffer.from` override will use the memory directly and avoid making a copy
|
|
114
|
+
css: Buffer.from(css.buffer, css.byteOffset, css.byteLength),
|
|
115
|
+
stats,
|
|
116
|
+
};
|
|
117
|
+
if (map) {
|
|
118
|
+
// This `Buffer.from` override will use the memory directly and avoid making a copy
|
|
119
|
+
result.map = Buffer.from(map.buffer, map.byteOffset, map.byteLength);
|
|
120
|
+
}
|
|
121
|
+
request.callback(undefined, result);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
request.callback(response.error);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
mainImporterPort.on('message', ({ id, url, prev, fromImport, }) => {
|
|
128
|
+
const request = this.requests.get(id);
|
|
129
|
+
if (!(request === null || request === void 0 ? void 0 : request.importers)) {
|
|
130
|
+
mainImporterPort.postMessage(null);
|
|
131
|
+
Atomics.store(importerSignal, 0, 1);
|
|
132
|
+
Atomics.notify(importerSignal, 0);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.processImporters(request.importers, url, prev, fromImport)
|
|
136
|
+
.then((result) => {
|
|
137
|
+
mainImporterPort.postMessage(result);
|
|
138
|
+
})
|
|
139
|
+
.catch((error) => {
|
|
140
|
+
mainImporterPort.postMessage(error);
|
|
141
|
+
})
|
|
142
|
+
.finally(() => {
|
|
143
|
+
Atomics.store(importerSignal, 0, 1);
|
|
144
|
+
Atomics.notify(importerSignal, 0);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
mainImporterPort.unref();
|
|
148
|
+
return worker;
|
|
149
|
+
}
|
|
150
|
+
async processImporters(importers, url, prev, fromImport) {
|
|
151
|
+
let result = null;
|
|
152
|
+
for (const importer of importers) {
|
|
153
|
+
result = await new Promise((resolve) => {
|
|
154
|
+
// Importers can be both sync and async
|
|
155
|
+
const innerResult = importer.call({ fromImport }, url, prev, resolve);
|
|
156
|
+
if (innerResult !== undefined) {
|
|
157
|
+
resolve(innerResult);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
if (result) {
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
createRequest(workerIndex, callback, importer) {
|
|
167
|
+
return {
|
|
168
|
+
id: this.idCounter++,
|
|
169
|
+
workerIndex,
|
|
170
|
+
callback,
|
|
171
|
+
importers: !importer || Array.isArray(importer) ? importer : [importer],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.SassLegacyWorkerImplementation = SassLegacyWorkerImplementation;
|
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
/**
|
|
10
|
-
* The callback type for the `dart-sass` asynchronous render function.
|
|
11
|
-
*/
|
|
12
|
-
declare type RenderCallback = (error?: Exception, result?: CompileResult) => void;
|
|
8
|
+
import { CompileResult, StringOptionsWithImporter, StringOptionsWithoutImporter } from 'sass';
|
|
13
9
|
/**
|
|
14
10
|
* A Sass renderer implementation that provides an interface that can be used by Webpack's
|
|
15
11
|
* `sass-loader`. The implementation uses a Worker thread to perform the Sass rendering
|
|
@@ -20,6 +16,7 @@ export declare class SassWorkerImplementation {
|
|
|
20
16
|
private readonly workers;
|
|
21
17
|
private readonly availableWorkers;
|
|
22
18
|
private readonly requests;
|
|
19
|
+
private readonly workerPath;
|
|
23
20
|
private idCounter;
|
|
24
21
|
private nextWorkerIndex;
|
|
25
22
|
/**
|
|
@@ -30,14 +27,14 @@ export declare class SassWorkerImplementation {
|
|
|
30
27
|
/**
|
|
31
28
|
* The synchronous render function is not used by the `sass-loader`.
|
|
32
29
|
*/
|
|
33
|
-
|
|
30
|
+
compileString(): never;
|
|
34
31
|
/**
|
|
35
32
|
* Asynchronously request a Sass stylesheet to be renderered.
|
|
36
33
|
*
|
|
34
|
+
* @param source The contents to compile.
|
|
37
35
|
* @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
36
|
*/
|
|
40
|
-
|
|
37
|
+
compileStringAsync(source: string, options: StringOptionsWithImporter<'async'> | StringOptionsWithoutImporter<'async'>): Promise<CompileResult>;
|
|
41
38
|
/**
|
|
42
39
|
* Shutdown the Sass render worker.
|
|
43
40
|
* Executing this method will stop any pending render requests.
|
|
@@ -46,5 +43,5 @@ export declare class SassWorkerImplementation {
|
|
|
46
43
|
private createWorker;
|
|
47
44
|
private processImporters;
|
|
48
45
|
private createRequest;
|
|
46
|
+
private isImporter;
|
|
49
47
|
}
|
|
50
|
-
export {};
|
package/src/sass/sass-service.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.SassWorkerImplementation = void 0;
|
|
11
|
+
const path_1 = require("path");
|
|
12
|
+
const url_1 = require("url");
|
|
11
13
|
const worker_threads_1 = require("worker_threads");
|
|
12
14
|
const environment_options_1 = require("../utils/environment-options");
|
|
13
15
|
/**
|
|
@@ -25,6 +27,7 @@ class SassWorkerImplementation {
|
|
|
25
27
|
this.workers = [];
|
|
26
28
|
this.availableWorkers = [];
|
|
27
29
|
this.requests = new Map();
|
|
30
|
+
this.workerPath = (0, path_1.join)(__dirname, './worker.js');
|
|
28
31
|
this.idCounter = 1;
|
|
29
32
|
this.nextWorkerIndex = 0;
|
|
30
33
|
}
|
|
@@ -38,42 +41,64 @@ class SassWorkerImplementation {
|
|
|
38
41
|
/**
|
|
39
42
|
* The synchronous render function is not used by the `sass-loader`.
|
|
40
43
|
*/
|
|
41
|
-
|
|
42
|
-
throw new Error('Sass
|
|
44
|
+
compileString() {
|
|
45
|
+
throw new Error('Sass compileString is not supported.');
|
|
43
46
|
}
|
|
44
47
|
/**
|
|
45
48
|
* Asynchronously request a Sass stylesheet to be renderered.
|
|
46
49
|
*
|
|
50
|
+
* @param source The contents to compile.
|
|
47
51
|
* @param options The `dart-sass` options to use when rendering the stylesheet.
|
|
48
|
-
* @param callback The function to execute when the rendering is complete.
|
|
49
52
|
*/
|
|
50
|
-
|
|
53
|
+
compileStringAsync(source, options) {
|
|
51
54
|
// The `functions`, `logger` and `importer` options are JavaScript functions that cannot be transferred.
|
|
52
55
|
// If any additional function options are added in the future, they must be excluded as well.
|
|
53
|
-
const { functions,
|
|
56
|
+
const { functions, importers, url, logger, ...serializableOptions } = options;
|
|
54
57
|
// The CLI's configuration does not use or expose the ability to defined custom Sass functions
|
|
55
58
|
if (functions && Object.keys(functions).length > 0) {
|
|
56
59
|
throw new Error('Sass custom functions are not supported.');
|
|
57
60
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.nextWorkerIndex
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
let workerIndex = this.availableWorkers.pop();
|
|
63
|
+
if (workerIndex === undefined) {
|
|
64
|
+
if (this.workers.length < MAX_RENDER_WORKERS) {
|
|
65
|
+
workerIndex = this.workers.length;
|
|
66
|
+
this.workers.push(this.createWorker());
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
workerIndex = this.nextWorkerIndex++;
|
|
70
|
+
if (this.nextWorkerIndex >= this.workers.length) {
|
|
71
|
+
this.nextWorkerIndex = 0;
|
|
72
|
+
}
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
const callback = (error, result) => {
|
|
76
|
+
if (error) {
|
|
77
|
+
const url = error === null || error === void 0 ? void 0 : error.span.url;
|
|
78
|
+
if (url) {
|
|
79
|
+
error.span.url = (0, url_1.pathToFileURL)(url);
|
|
80
|
+
}
|
|
81
|
+
reject(error);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!result) {
|
|
85
|
+
reject(new Error('No result.'));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
resolve(result);
|
|
89
|
+
};
|
|
90
|
+
const request = this.createRequest(workerIndex, callback, importers);
|
|
91
|
+
this.requests.set(request.id, request);
|
|
92
|
+
this.workers[workerIndex].postMessage({
|
|
93
|
+
id: request.id,
|
|
94
|
+
source,
|
|
95
|
+
hasImporter: !!(importers === null || importers === void 0 ? void 0 : importers.length),
|
|
96
|
+
options: {
|
|
97
|
+
...serializableOptions,
|
|
98
|
+
// URL is not serializable so to convert to string here and back to URL in the worker.
|
|
99
|
+
url: url ? (0, url_1.fileURLToPath)(url) : undefined,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
77
102
|
});
|
|
78
103
|
}
|
|
79
104
|
/**
|
|
@@ -92,8 +117,7 @@ class SassWorkerImplementation {
|
|
|
92
117
|
createWorker() {
|
|
93
118
|
const { port1: mainImporterPort, port2: workerImporterPort } = new worker_threads_1.MessageChannel();
|
|
94
119
|
const importerSignal = new Int32Array(new SharedArrayBuffer(4));
|
|
95
|
-
const
|
|
96
|
-
const worker = new worker_threads_1.Worker(workerPath, {
|
|
120
|
+
const worker = new worker_threads_1.Worker(this.workerPath, {
|
|
97
121
|
workerData: { workerImporterPort, importerSignal },
|
|
98
122
|
transferList: [workerImporterPort],
|
|
99
123
|
});
|
|
@@ -105,25 +129,17 @@ class SassWorkerImplementation {
|
|
|
105
129
|
this.requests.delete(response.id);
|
|
106
130
|
this.availableWorkers.push(request.workerIndex);
|
|
107
131
|
if (response.result) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
css: Buffer.from(css.buffer, css.byteOffset, css.byteLength),
|
|
114
|
-
stats,
|
|
115
|
-
};
|
|
116
|
-
if (map) {
|
|
117
|
-
// This `Buffer.from` override will use the memory directly and avoid making a copy
|
|
118
|
-
result.map = Buffer.from(map.buffer, map.byteOffset, map.byteLength);
|
|
119
|
-
}
|
|
120
|
-
request.callback(undefined, result);
|
|
132
|
+
request.callback(undefined, {
|
|
133
|
+
...response.result,
|
|
134
|
+
// URL is not serializable so in the worker we convert to string and here back to URL.
|
|
135
|
+
loadedUrls: response.result.loadedUrls.map((p) => (0, url_1.pathToFileURL)(p)),
|
|
136
|
+
});
|
|
121
137
|
}
|
|
122
138
|
else {
|
|
123
139
|
request.callback(response.error);
|
|
124
140
|
}
|
|
125
141
|
});
|
|
126
|
-
mainImporterPort.on('message', ({ id, url,
|
|
142
|
+
mainImporterPort.on('message', ({ id, url, options }) => {
|
|
127
143
|
const request = this.requests.get(id);
|
|
128
144
|
if (!(request === null || request === void 0 ? void 0 : request.importers)) {
|
|
129
145
|
mainImporterPort.postMessage(null);
|
|
@@ -131,7 +147,7 @@ class SassWorkerImplementation {
|
|
|
131
147
|
Atomics.notify(importerSignal, 0);
|
|
132
148
|
return;
|
|
133
149
|
}
|
|
134
|
-
this.processImporters(request.importers, url,
|
|
150
|
+
this.processImporters(request.importers, url, options)
|
|
135
151
|
.then((result) => {
|
|
136
152
|
mainImporterPort.postMessage(result);
|
|
137
153
|
})
|
|
@@ -146,29 +162,30 @@ class SassWorkerImplementation {
|
|
|
146
162
|
mainImporterPort.unref();
|
|
147
163
|
return worker;
|
|
148
164
|
}
|
|
149
|
-
async processImporters(importers, url,
|
|
150
|
-
let result = null;
|
|
165
|
+
async processImporters(importers, url, options) {
|
|
151
166
|
for (const importer of importers) {
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
167
|
+
if (this.isImporter(importer)) {
|
|
168
|
+
// Importer
|
|
169
|
+
throw new Error('Only File Importers are supported.');
|
|
170
|
+
}
|
|
171
|
+
// File importer (Can be sync or aync).
|
|
172
|
+
const result = await importer.findFileUrl(url, options);
|
|
159
173
|
if (result) {
|
|
160
|
-
|
|
174
|
+
return (0, url_1.fileURLToPath)(result);
|
|
161
175
|
}
|
|
162
176
|
}
|
|
163
|
-
return
|
|
177
|
+
return null;
|
|
164
178
|
}
|
|
165
|
-
createRequest(workerIndex, callback,
|
|
179
|
+
createRequest(workerIndex, callback, importers) {
|
|
166
180
|
return {
|
|
167
181
|
id: this.idCounter++,
|
|
168
182
|
workerIndex,
|
|
169
183
|
callback,
|
|
170
|
-
importers
|
|
184
|
+
importers,
|
|
171
185
|
};
|
|
172
186
|
}
|
|
187
|
+
isImporter(value) {
|
|
188
|
+
return 'canonicalize' in value && 'load' in value;
|
|
189
|
+
}
|
|
173
190
|
}
|
|
174
191
|
exports.SassWorkerImplementation = SassWorkerImplementation;
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
export
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
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 || !worker_threads_1.workerData) {
|
|
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
|
+
const { workerImporterPort, importerSignal } = worker_threads_1.workerData;
|
|
17
|
+
worker_threads_1.parentPort.on('message', ({ id, hasImporter, options }) => {
|
|
18
|
+
try {
|
|
19
|
+
if (hasImporter) {
|
|
20
|
+
// When a custom importer function is present, the importer request must be proxied
|
|
21
|
+
// back to the main thread where it can be executed.
|
|
22
|
+
// This process must be synchronous from the perspective of dart-sass. The `Atomics`
|
|
23
|
+
// functions combined with the shared memory `importSignal` and the Node.js
|
|
24
|
+
// `receiveMessageOnPort` function are used to ensure synchronous behavior.
|
|
25
|
+
options.importer = function (url, prev) {
|
|
26
|
+
var _a;
|
|
27
|
+
Atomics.store(importerSignal, 0, 0);
|
|
28
|
+
const { fromImport } = this;
|
|
29
|
+
workerImporterPort.postMessage({ id, url, prev, fromImport });
|
|
30
|
+
Atomics.wait(importerSignal, 0, 0);
|
|
31
|
+
return (_a = (0, worker_threads_1.receiveMessageOnPort)(workerImporterPort)) === null || _a === void 0 ? void 0 : _a.message;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// The synchronous Sass render function can be up to two times faster than the async variant
|
|
35
|
+
const result = (0, sass_1.renderSync)(options);
|
|
36
|
+
worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage({ id, result });
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
// Needed because V8 will only serialize the message and stack properties of an Error instance.
|
|
41
|
+
const { formatted, file, line, column, message, stack } = error;
|
|
42
|
+
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 } });
|
|
43
|
+
}
|
|
44
|
+
});
|
package/src/sass/worker.js
CHANGED
|
@@ -8,13 +8,17 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
const sass_1 = require("sass");
|
|
11
|
+
const url_1 = require("url");
|
|
11
12
|
const worker_threads_1 = require("worker_threads");
|
|
12
13
|
if (!worker_threads_1.parentPort || !worker_threads_1.workerData) {
|
|
13
14
|
throw new Error('Sass worker must be executed as a Worker.');
|
|
14
15
|
}
|
|
15
16
|
// The importer variables are used to proxy import requests to the main thread
|
|
16
17
|
const { workerImporterPort, importerSignal } = worker_threads_1.workerData;
|
|
17
|
-
worker_threads_1.parentPort.on('message', ({ id, hasImporter, options }) => {
|
|
18
|
+
worker_threads_1.parentPort.on('message', ({ id, hasImporter, source, options }) => {
|
|
19
|
+
if (!worker_threads_1.parentPort) {
|
|
20
|
+
throw new Error('"parentPort" is not defined. Sass worker must be executed as a Worker.');
|
|
21
|
+
}
|
|
18
22
|
try {
|
|
19
23
|
if (hasImporter) {
|
|
20
24
|
// When a custom importer function is present, the importer request must be proxied
|
|
@@ -22,23 +26,69 @@ worker_threads_1.parentPort.on('message', ({ id, hasImporter, options }) => {
|
|
|
22
26
|
// This process must be synchronous from the perspective of dart-sass. The `Atomics`
|
|
23
27
|
// functions combined with the shared memory `importSignal` and the Node.js
|
|
24
28
|
// `receiveMessageOnPort` function are used to ensure synchronous behavior.
|
|
25
|
-
options.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
options.importers = [
|
|
30
|
+
{
|
|
31
|
+
findFileUrl: (url, options) => {
|
|
32
|
+
var _a;
|
|
33
|
+
Atomics.store(importerSignal, 0, 0);
|
|
34
|
+
workerImporterPort.postMessage({ id, url, options });
|
|
35
|
+
Atomics.wait(importerSignal, 0, 0);
|
|
36
|
+
const result = (_a = (0, worker_threads_1.receiveMessageOnPort)(workerImporterPort)) === null || _a === void 0 ? void 0 : _a.message;
|
|
37
|
+
return result ? (0, url_1.pathToFileURL)(result) : null;
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
];
|
|
33
41
|
}
|
|
34
42
|
// The synchronous Sass render function can be up to two times faster than the async variant
|
|
35
|
-
const result = (0, sass_1.
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
const result = (0, sass_1.compileString)(source, {
|
|
44
|
+
...options,
|
|
45
|
+
// URL is not serializable so to convert to string in the parent and back to URL here.
|
|
46
|
+
url: options.url ? (0, url_1.pathToFileURL)(options.url) : undefined,
|
|
47
|
+
});
|
|
48
|
+
worker_threads_1.parentPort.postMessage({
|
|
49
|
+
id,
|
|
50
|
+
result: {
|
|
51
|
+
...result,
|
|
52
|
+
// URL is not serializable so to convert to string here and back to URL in the parent.
|
|
53
|
+
loadedUrls: result.loadedUrls.map((p) => (0, url_1.fileURLToPath)(p)),
|
|
54
|
+
},
|
|
55
|
+
});
|
|
38
56
|
}
|
|
39
57
|
catch (error) {
|
|
40
58
|
// Needed because V8 will only serialize the message and stack properties of an Error instance.
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
if (error instanceof sass_1.Exception) {
|
|
60
|
+
const { span, message, stack, sassMessage, sassStack } = error;
|
|
61
|
+
worker_threads_1.parentPort.postMessage({
|
|
62
|
+
id,
|
|
63
|
+
error: {
|
|
64
|
+
span: {
|
|
65
|
+
text: span.text,
|
|
66
|
+
context: span.context,
|
|
67
|
+
end: {
|
|
68
|
+
column: span.end.column,
|
|
69
|
+
offset: span.end.offset,
|
|
70
|
+
line: span.end.line,
|
|
71
|
+
},
|
|
72
|
+
start: {
|
|
73
|
+
column: span.start.column,
|
|
74
|
+
offset: span.start.offset,
|
|
75
|
+
line: span.start.line,
|
|
76
|
+
},
|
|
77
|
+
url: span.url ? (0, url_1.fileURLToPath)(span.url) : undefined,
|
|
78
|
+
},
|
|
79
|
+
message,
|
|
80
|
+
stack,
|
|
81
|
+
sassMessage,
|
|
82
|
+
sassStack,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else if (error instanceof Error) {
|
|
87
|
+
const { message, stack } = error;
|
|
88
|
+
worker_threads_1.parentPort.postMessage({ id, error: { message, stack } });
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
worker_threads_1.parentPort.postMessage({ id, error: { message: 'An unknown error has occurred.' } });
|
|
92
|
+
}
|
|
43
93
|
}
|
|
44
94
|
});
|
|
@@ -27,7 +27,6 @@ export interface BuildOptions {
|
|
|
27
27
|
progress?: boolean;
|
|
28
28
|
localize?: Localize;
|
|
29
29
|
i18nMissingTranslation?: I18NTranslation;
|
|
30
|
-
bundleDependencies?: boolean;
|
|
31
30
|
externalDependencies?: string[];
|
|
32
31
|
watch?: boolean;
|
|
33
32
|
outputHashing?: OutputHashing;
|
|
@@ -45,7 +44,7 @@ export interface BuildOptions {
|
|
|
45
44
|
statsJson: boolean;
|
|
46
45
|
hmr?: boolean;
|
|
47
46
|
main: string;
|
|
48
|
-
polyfills
|
|
47
|
+
polyfills: string[];
|
|
49
48
|
budgets: Budget[];
|
|
50
49
|
assets: AssetPatternClass[];
|
|
51
50
|
scripts: ScriptElement[];
|
|
@@ -60,7 +59,7 @@ export interface BuildOptions {
|
|
|
60
59
|
cache: NormalizedCachedOptions;
|
|
61
60
|
codeCoverage?: boolean;
|
|
62
61
|
codeCoverageExclude?: string[];
|
|
63
|
-
supportedBrowsers
|
|
62
|
+
supportedBrowsers?: string[];
|
|
64
63
|
}
|
|
65
64
|
export interface WebpackDevServerOptions extends BuildOptions, Omit<DevServerSchema, 'optimization' | 'sourceMap' | 'browserTarget'> {
|
|
66
65
|
}
|
|
@@ -72,6 +71,5 @@ export interface WebpackConfigOptions<T = BuildOptions> {
|
|
|
72
71
|
buildOptions: T;
|
|
73
72
|
tsConfig: ParsedConfiguration;
|
|
74
73
|
tsConfigPath: string;
|
|
75
|
-
scriptTarget: import('typescript').ScriptTarget;
|
|
76
74
|
projectName: string;
|
|
77
75
|
}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.maxWorkers = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
10
|
+
exports.useLegacySass = exports.maxWorkers = exports.allowMinify = exports.shouldBeautify = exports.allowMangle = void 0;
|
|
11
|
+
const color_1 = require("./color");
|
|
11
12
|
function isDisabled(variable) {
|
|
12
13
|
return variable === '0' || variable.toLowerCase() === 'false';
|
|
13
14
|
}
|
|
@@ -67,3 +68,12 @@ exports.allowMinify = debugOptimize.minify;
|
|
|
67
68
|
*/
|
|
68
69
|
const maxWorkersVariable = process.env['NG_BUILD_MAX_WORKERS'];
|
|
69
70
|
exports.maxWorkers = isPresent(maxWorkersVariable) ? +maxWorkersVariable : 4;
|
|
71
|
+
const legacySassVariable = process.env['NG_BUILD_LEGACY_SASS'];
|
|
72
|
+
exports.useLegacySass = (() => {
|
|
73
|
+
if (!isPresent(legacySassVariable)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
// eslint-disable-next-line no-console
|
|
77
|
+
console.warn(color_1.colors.yellow(`Warning: 'NG_BUILD_LEGACY_SASS' environment variable support will be removed in version 16.`));
|
|
78
|
+
return isEnabled(legacySassVariable);
|
|
79
|
+
})();
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
* Transform browserlists result to esbuild target.
|
|
10
|
+
* @see https://esbuild.github.io/api/#target
|
|
11
|
+
*/
|
|
12
|
+
export declare function transformSupportedBrowsersToTargets(supportedBrowsers: string[]): string[];
|