@ngtools/webpack 13.1.0-next.3 → 13.1.2
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 +2 -2
- package/src/ivy/diagnostics.d.ts +3 -3
- package/src/ivy/loader.js +3 -1
- package/src/ivy/plugin.d.ts +3 -0
- package/src/ivy/plugin.js +50 -42
- package/src/ivy/transformation.d.ts +0 -1
- package/src/ivy/transformation.js +1 -1
- package/src/ngcc_processor.js +1 -8
- package/src/resource_loader.js +23 -11
- package/src/transformers/replace_resources.d.ts +3 -2
- package/src/transformers/replace_resources.js +14 -12
- package/src/loaders/direct-resource.d.ts +0 -12
- package/src/loaders/direct-resource.js +0 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ngtools/webpack",
|
|
3
|
-
"version": "13.1.
|
|
3
|
+
"version": "13.1.2",
|
|
4
4
|
"description": "Webpack plugin that AoT compiles your Angular components and modules.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"typings": "src/index.d.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dependencies": {},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"@angular/compiler-cli": "^13.0.0 || ^13.1.0-next",
|
|
30
|
-
"typescript": "
|
|
30
|
+
"typescript": ">=4.4.3 <4.6",
|
|
31
31
|
"webpack": "^5.30.0"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
package/src/ivy/diagnostics.d.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
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
|
|
8
|
+
import { Diagnostic } from 'typescript';
|
|
9
9
|
import type { Compilation } from 'webpack';
|
|
10
|
-
export declare type DiagnosticsReporter = (diagnostics:
|
|
11
|
-
export declare function createDiagnosticsReporter(compilation: Compilation, formatter: (diagnostic:
|
|
10
|
+
export declare type DiagnosticsReporter = (diagnostics: readonly Diagnostic[]) => void;
|
|
11
|
+
export declare function createDiagnosticsReporter(compilation: Compilation, formatter: (diagnostic: Diagnostic) => string): DiagnosticsReporter;
|
|
12
12
|
export declare function addWarning(compilation: Compilation, message: string): void;
|
|
13
13
|
export declare function addError(compilation: Compilation, message: string): void;
|
package/src/ivy/loader.js
CHANGED
|
@@ -72,7 +72,9 @@ function angularWebpackLoader(content, map) {
|
|
|
72
72
|
callback(undefined, resultContent, resultMap);
|
|
73
73
|
})
|
|
74
74
|
.catch((err) => {
|
|
75
|
-
|
|
75
|
+
// The below is needed to hide stacktraces from users.
|
|
76
|
+
const message = err instanceof Error ? err.message : err;
|
|
77
|
+
callback(new Error(message));
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
80
|
exports.angularWebpackLoader = angularWebpackLoader;
|
package/src/ivy/plugin.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare class AngularWebpackPlugin {
|
|
|
26
26
|
private ngtscNextProgram?;
|
|
27
27
|
private builder?;
|
|
28
28
|
private sourceFileCache?;
|
|
29
|
+
private webpackCache?;
|
|
29
30
|
private readonly fileDependencies;
|
|
30
31
|
private readonly requiredFilesToEmit;
|
|
31
32
|
private readonly requiredFilesToEmitCache;
|
|
@@ -42,4 +43,6 @@ export declare class AngularWebpackPlugin {
|
|
|
42
43
|
private updateJitProgram;
|
|
43
44
|
private createFileEmitter;
|
|
44
45
|
private initializeCompilerCli;
|
|
46
|
+
private addFileEmitHistory;
|
|
47
|
+
private getFileEmitHistory;
|
|
45
48
|
}
|
package/src/ivy/plugin.js
CHANGED
|
@@ -65,9 +65,6 @@ function initializeNgccProcessor(compiler, tsconfig, compilerNgccModule) {
|
|
|
65
65
|
const processor = new ngcc_processor_1.NgccProcessor(compilerNgccModule, mainFields, warnings, errors, compiler.context, tsconfig, inputFileSystem, resolver);
|
|
66
66
|
return { processor, errors, warnings };
|
|
67
67
|
}
|
|
68
|
-
function hashContent(content) {
|
|
69
|
-
return (0, crypto_1.createHash)('md5').update(content).digest();
|
|
70
|
-
}
|
|
71
68
|
const PLUGIN_NAME = 'angular-compiler';
|
|
72
69
|
const compilationFileEmitters = new WeakMap();
|
|
73
70
|
class AngularWebpackPlugin {
|
|
@@ -97,6 +94,7 @@ class AngularWebpackPlugin {
|
|
|
97
94
|
get options() {
|
|
98
95
|
return this.pluginOptions;
|
|
99
96
|
}
|
|
97
|
+
// eslint-disable-next-line max-lines-per-function
|
|
100
98
|
apply(compiler) {
|
|
101
99
|
const { NormalModuleReplacementPlugin, util } = compiler.webpack;
|
|
102
100
|
// Setup file replacements with webpack
|
|
@@ -131,6 +129,10 @@ class AngularWebpackPlugin {
|
|
|
131
129
|
// Register plugin to ensure deterministic emit order in multi-plugin usage
|
|
132
130
|
const emitRegistration = this.registerWithCompilation(compilation);
|
|
133
131
|
this.watchMode = compiler.watchMode;
|
|
132
|
+
// Initialize webpack cache
|
|
133
|
+
if (!this.webpackCache && compilation.options.cache) {
|
|
134
|
+
this.webpackCache = compilation.getCache(PLUGIN_NAME);
|
|
135
|
+
}
|
|
134
136
|
// Initialize the resource loader if not already setup
|
|
135
137
|
if (!resourceLoader) {
|
|
136
138
|
resourceLoader = new resource_loader_1.WebpackResourceLoader(this.watchMode);
|
|
@@ -270,7 +272,7 @@ class AngularWebpackPlugin {
|
|
|
270
272
|
}
|
|
271
273
|
const filesToRebuild = new Set();
|
|
272
274
|
for (const requiredFile of this.requiredFilesToEmit) {
|
|
273
|
-
const history = this.
|
|
275
|
+
const history = await this.getFileEmitHistory(requiredFile);
|
|
274
276
|
if (history) {
|
|
275
277
|
const emitResult = await fileEmitter(requiredFile);
|
|
276
278
|
if ((emitResult === null || emitResult === void 0 ? void 0 : emitResult.content) === undefined ||
|
|
@@ -398,8 +400,10 @@ class AngularWebpackPlugin {
|
|
|
398
400
|
};
|
|
399
401
|
// Required to support asynchronous resource loading
|
|
400
402
|
// Must be done before creating transformers or getting template diagnostics
|
|
401
|
-
const pendingAnalysis = angularCompiler
|
|
402
|
-
|
|
403
|
+
const pendingAnalysis = angularCompiler
|
|
404
|
+
.analyzeAsync()
|
|
405
|
+
.then(() => {
|
|
406
|
+
var _a;
|
|
403
407
|
this.requiredFilesToEmit.clear();
|
|
404
408
|
for (const sourceFile of builder.getSourceFiles()) {
|
|
405
409
|
if (sourceFile.isDeclarationFile) {
|
|
@@ -424,29 +428,30 @@ class AngularWebpackPlugin {
|
|
|
424
428
|
}
|
|
425
429
|
}
|
|
426
430
|
}
|
|
427
|
-
// Temporary workaround during transition to ESM-only @angular/compiler-cli
|
|
428
|
-
// TODO_ESM: This workaround should be removed prior to the final release of v13
|
|
429
|
-
// and replaced with only `this.compilerCli.OptimizeFor`.
|
|
430
|
-
const OptimizeFor =
|
|
431
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
432
|
-
(_a = this.compilerCli.OptimizeFor) !== null && _a !== void 0 ? _a : require('@angular/compiler-cli/src/ngtsc/typecheck/api').OptimizeFor;
|
|
433
431
|
// Collect new Angular diagnostics for files affected by changes
|
|
432
|
+
const OptimizeFor = this.compilerCli.OptimizeFor;
|
|
434
433
|
const optimizeDiagnosticsFor = affectedFiles.size <= DIAGNOSTICS_AFFECTED_THRESHOLD
|
|
435
434
|
? OptimizeFor.SingleFile
|
|
436
435
|
: OptimizeFor.WholeProgram;
|
|
437
436
|
for (const affectedFile of affectedFiles) {
|
|
438
437
|
const angularDiagnostics = angularCompiler.getDiagnosticsForFile(affectedFile, optimizeDiagnosticsFor);
|
|
439
438
|
diagnosticsReporter(angularDiagnostics);
|
|
440
|
-
(
|
|
439
|
+
(_a = this.sourceFileCache) === null || _a === void 0 ? void 0 : _a.updateAngularDiagnostics(affectedFile, angularDiagnostics);
|
|
441
440
|
}
|
|
442
|
-
return
|
|
443
|
-
this.
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
441
|
+
return {
|
|
442
|
+
emitter: this.createFileEmitter(builder, (0, transformation_1.mergeTransformers)(angularCompiler.prepareEmit().transformers, transformers), getDependencies, (sourceFile) => {
|
|
443
|
+
this.requiredFilesToEmit.delete((0, paths_1.normalizePath)(sourceFile.fileName));
|
|
444
|
+
angularCompiler.incrementalDriver.recordSuccessfulEmit(sourceFile);
|
|
445
|
+
}),
|
|
446
|
+
};
|
|
447
|
+
})
|
|
448
|
+
.catch((err) => ({ errorMessage: err instanceof Error ? err.message : `${err}` }));
|
|
447
449
|
const analyzingFileEmitter = async (file) => {
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
+
const analysis = await pendingAnalysis;
|
|
451
|
+
if ('errorMessage' in analysis) {
|
|
452
|
+
throw new Error(analysis.errorMessage);
|
|
453
|
+
}
|
|
454
|
+
return analysis.emitter(file);
|
|
450
455
|
};
|
|
451
456
|
return {
|
|
452
457
|
fileEmitter: analyzingFileEmitter,
|
|
@@ -500,12 +505,8 @@ class AngularWebpackPlugin {
|
|
|
500
505
|
}
|
|
501
506
|
}, undefined, undefined, transformers);
|
|
502
507
|
onAfterEmit === null || onAfterEmit === void 0 ? void 0 : onAfterEmit(sourceFile);
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
// Capture emit history info for Angular rebuild analysis
|
|
506
|
-
hash = hashContent(content);
|
|
507
|
-
this.fileEmitHistory.set(filePath, { length: content.length, hash });
|
|
508
|
-
}
|
|
508
|
+
// Capture emit history info for Angular rebuild analysis
|
|
509
|
+
const hash = content ? (await this.addFileEmitHistory(filePath, content)).hash : undefined;
|
|
509
510
|
const dependencies = [
|
|
510
511
|
...(this.fileDependencies.get(filePath) || []),
|
|
511
512
|
...getExtraDependencies(sourceFile),
|
|
@@ -524,24 +525,31 @@ class AngularWebpackPlugin {
|
|
|
524
525
|
// this, a Function constructor is used to prevent TypeScript from changing the dynamic import.
|
|
525
526
|
// Once TypeScript provides support for keeping the dynamic import this workaround can
|
|
526
527
|
// be dropped.
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
528
|
+
this.compilerCliModule = await new Function(`return import('@angular/compiler-cli');`)();
|
|
529
|
+
this.compilerNgccModule = await new Function(`return import('@angular/compiler-cli/ngcc');`)();
|
|
530
|
+
}
|
|
531
|
+
async addFileEmitHistory(filePath, content) {
|
|
532
|
+
const historyData = {
|
|
533
|
+
length: content.length,
|
|
534
|
+
hash: (0, crypto_1.createHash)('md5').update(content).digest(),
|
|
535
|
+
};
|
|
536
|
+
if (this.webpackCache) {
|
|
537
|
+
const history = await this.getFileEmitHistory(filePath);
|
|
538
|
+
if (!history || Buffer.compare(history.hash, historyData.hash) !== 0) {
|
|
539
|
+
// Hash doesn't match or item doesn't exist.
|
|
540
|
+
await this.webpackCache.storePromise(filePath, null, historyData);
|
|
541
|
+
}
|
|
531
542
|
}
|
|
532
|
-
|
|
533
|
-
//
|
|
534
|
-
|
|
535
|
-
compilerNgccModule = await new Function(`return import('@angular/compiler-cli/ngcc/index.js');`)();
|
|
543
|
+
else if (this.watchMode) {
|
|
544
|
+
// The in memory file emit history is only required during watch mode.
|
|
545
|
+
this.fileEmitHistory.set(filePath, historyData);
|
|
536
546
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
? compilerNgccModule
|
|
544
|
-
: compilerNgccModule.default;
|
|
547
|
+
return historyData;
|
|
548
|
+
}
|
|
549
|
+
async getFileEmitHistory(filePath) {
|
|
550
|
+
return this.webpackCache
|
|
551
|
+
? this.webpackCache.getPromise(filePath, null)
|
|
552
|
+
: this.fileEmitHistory.get(filePath);
|
|
545
553
|
}
|
|
546
554
|
}
|
|
547
555
|
exports.AngularWebpackPlugin = AngularWebpackPlugin;
|
|
@@ -11,7 +11,6 @@ export declare function createAotTransformers(builder: ts.BuilderProgram, option
|
|
|
11
11
|
emitNgModuleScope?: boolean;
|
|
12
12
|
}): ts.CustomTransformers;
|
|
13
13
|
export declare function createJitTransformers(builder: ts.BuilderProgram, compilerCli: typeof import('@angular/compiler-cli'), options: {
|
|
14
|
-
directTemplateLoading?: boolean;
|
|
15
14
|
inlineStyleFileExtension?: string;
|
|
16
15
|
}): ts.CustomTransformers;
|
|
17
16
|
export declare function mergeTransformers(first: ts.CustomTransformers, second: ts.CustomTransformers): ts.CustomTransformers;
|
|
@@ -50,7 +50,7 @@ function createJitTransformers(builder, compilerCli, options) {
|
|
|
50
50
|
const getTypeChecker = () => builder.getProgram().getTypeChecker();
|
|
51
51
|
return {
|
|
52
52
|
before: [
|
|
53
|
-
(0, replace_resources_1.replaceResources)(() => true, getTypeChecker, options.
|
|
53
|
+
(0, replace_resources_1.replaceResources)(() => true, getTypeChecker, options.inlineStyleFileExtension),
|
|
54
54
|
compilerCli.constructorParametersDownlevelTransform(builder.getProgram()),
|
|
55
55
|
],
|
|
56
56
|
};
|
package/src/ngcc_processor.js
CHANGED
|
@@ -55,7 +55,6 @@ class NgccProcessor {
|
|
|
55
55
|
}
|
|
56
56
|
/** Process the entire node modules tree. */
|
|
57
57
|
process() {
|
|
58
|
-
var _a;
|
|
59
58
|
// Under Bazel when running in sandbox mode parts of the filesystem is read-only.
|
|
60
59
|
if (process.env.BAZEL_TARGET) {
|
|
61
60
|
return;
|
|
@@ -115,19 +114,13 @@ class NgccProcessor {
|
|
|
115
114
|
}
|
|
116
115
|
const timeLabel = 'NgccProcessor.process';
|
|
117
116
|
(0, benchmark_1.time)(timeLabel);
|
|
118
|
-
// Temporary workaround during transition to ESM-only @angular/compiler-cli
|
|
119
|
-
// TODO_ESM: This workaround should be removed prior to the final release of v13
|
|
120
|
-
// and replaced with only `this.compilerNgcc.ngccMainFilePath`.
|
|
121
|
-
const ngccExecutablePath =
|
|
122
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
123
|
-
(_a = this.compilerNgcc.ngccMainFilePath) !== null && _a !== void 0 ? _a : require.resolve('@angular/compiler-cli/ngcc/main-ngcc.js');
|
|
124
117
|
// We spawn instead of using the API because:
|
|
125
118
|
// - NGCC Async uses clustering which is problematic when used via the API which means
|
|
126
119
|
// that we cannot setup multiple cluster masters with different options.
|
|
127
120
|
// - We will not be able to have concurrent builds otherwise Ex: App-Shell,
|
|
128
121
|
// as NGCC will create a lock file for both builds and it will cause builds to fails.
|
|
129
122
|
const { status, error } = (0, child_process_1.spawnSync)(process.execPath, [
|
|
130
|
-
|
|
123
|
+
this.compilerNgcc.ngccMainFilePath,
|
|
131
124
|
'--source' /** basePath */,
|
|
132
125
|
this._nodeModulesDirectory,
|
|
133
126
|
'--properties' /** propertiesToConsider */,
|
package/src/resource_loader.js
CHANGED
|
@@ -32,6 +32,7 @@ const path = __importStar(require("path"));
|
|
|
32
32
|
const vm = __importStar(require("vm"));
|
|
33
33
|
const paths_1 = require("./ivy/paths");
|
|
34
34
|
const inline_resource_1 = require("./loaders/inline-resource");
|
|
35
|
+
const replace_resources_1 = require("./transformers/replace_resources");
|
|
35
36
|
class WebpackResourceLoader {
|
|
36
37
|
constructor(shouldCache) {
|
|
37
38
|
this._fileDependencies = new Map();
|
|
@@ -93,15 +94,23 @@ class WebpackResourceLoader {
|
|
|
93
94
|
if (!this._parentCompilation) {
|
|
94
95
|
throw new Error('WebpackResourceLoader cannot be used without parentCompilation');
|
|
95
96
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
const getEntry = () => {
|
|
98
|
+
if (filePath) {
|
|
99
|
+
return `${filePath}?${replace_resources_1.NG_COMPONENT_RESOURCE_QUERY}`;
|
|
100
|
+
}
|
|
101
|
+
else if (resourceType) {
|
|
102
|
+
return (
|
|
103
|
+
// app.component.ts-2.css?ngResource!=!@ngtools/webpack/src/loaders/inline-resource.js!app.component.ts
|
|
104
|
+
`${containingFile}-${this.outputPathCounter}.${fileExtension}` +
|
|
105
|
+
`?${replace_resources_1.NG_COMPONENT_RESOURCE_QUERY}!=!${this.inlineDataLoaderPath}!${containingFile}`);
|
|
106
|
+
}
|
|
107
|
+
else if (data) {
|
|
108
|
+
// Create a special URL for reading the resource from memory
|
|
109
|
+
return `angular-resource:${resourceType},${(0, crypto_1.createHash)('md5').update(data).digest('hex')}`;
|
|
110
|
+
}
|
|
111
|
+
throw new Error(`"filePath", "resourceType" or "data" must be specified.`);
|
|
112
|
+
};
|
|
113
|
+
const entry = getEntry();
|
|
105
114
|
// Simple sanity check.
|
|
106
115
|
if (filePath === null || filePath === void 0 ? void 0 : filePath.match(/\.[jt]s$/)) {
|
|
107
116
|
throw new Error(`Cannot use a JavaScript or TypeScript file (${filePath}) in a component's styleUrls or templateUrl.`);
|
|
@@ -162,8 +171,11 @@ class WebpackResourceLoader {
|
|
|
162
171
|
childCompilation.hooks.processAssets.tap({ name: 'angular-compiler', stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT }, () => {
|
|
163
172
|
var _a;
|
|
164
173
|
finalContent = (_a = childCompilation.assets[outputFilePath]) === null || _a === void 0 ? void 0 : _a.source().toString();
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
for (const { files } of childCompilation.chunks) {
|
|
175
|
+
for (const file of files) {
|
|
176
|
+
childCompilation.deleteAsset(file);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
167
179
|
});
|
|
168
180
|
});
|
|
169
181
|
return new Promise((resolve, reject) => {
|
|
@@ -6,5 +6,6 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import * as ts from 'typescript';
|
|
9
|
-
export declare
|
|
10
|
-
export declare function
|
|
9
|
+
export declare const NG_COMPONENT_RESOURCE_QUERY = "ngResource";
|
|
10
|
+
export declare function replaceResources(shouldTransform: (fileName: string) => boolean, getTypeChecker: () => ts.TypeChecker, inlineStyleFileExtension?: string): ts.TransformerFactory<ts.SourceFile>;
|
|
11
|
+
export declare function getResourceUrl(node: ts.Node): string | null;
|
|
@@ -26,11 +26,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
26
26
|
return result;
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.getResourceUrl = exports.replaceResources = void 0;
|
|
29
|
+
exports.getResourceUrl = exports.replaceResources = exports.NG_COMPONENT_RESOURCE_QUERY = void 0;
|
|
30
30
|
const ts = __importStar(require("typescript"));
|
|
31
|
-
const direct_resource_1 = require("../loaders/direct-resource");
|
|
32
31
|
const inline_resource_1 = require("../loaders/inline-resource");
|
|
33
|
-
|
|
32
|
+
exports.NG_COMPONENT_RESOURCE_QUERY = 'ngResource';
|
|
33
|
+
function replaceResources(shouldTransform, getTypeChecker, inlineStyleFileExtension) {
|
|
34
34
|
return (context) => {
|
|
35
35
|
const typeChecker = getTypeChecker();
|
|
36
36
|
const resourceImportDeclarations = [];
|
|
@@ -39,7 +39,7 @@ function replaceResources(shouldTransform, getTypeChecker, directTemplateLoading
|
|
|
39
39
|
const visitNode = (node) => {
|
|
40
40
|
if (ts.isClassDeclaration(node)) {
|
|
41
41
|
const decorators = ts.visitNodes(node.decorators, (node) => ts.isDecorator(node)
|
|
42
|
-
? visitDecorator(nodeFactory, node, typeChecker,
|
|
42
|
+
? visitDecorator(nodeFactory, node, typeChecker, resourceImportDeclarations, moduleKind, inlineStyleFileExtension)
|
|
43
43
|
: node);
|
|
44
44
|
return nodeFactory.updateClassDeclaration(node, decorators, node.modifiers, node.name, node.typeParameters, node.heritageClauses, node.members);
|
|
45
45
|
}
|
|
@@ -62,7 +62,7 @@ function replaceResources(shouldTransform, getTypeChecker, directTemplateLoading
|
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
64
|
exports.replaceResources = replaceResources;
|
|
65
|
-
function visitDecorator(nodeFactory, node, typeChecker,
|
|
65
|
+
function visitDecorator(nodeFactory, node, typeChecker, resourceImportDeclarations, moduleKind, inlineStyleFileExtension) {
|
|
66
66
|
if (!isComponentDecorator(node, typeChecker)) {
|
|
67
67
|
return node;
|
|
68
68
|
}
|
|
@@ -79,7 +79,7 @@ function visitDecorator(nodeFactory, node, typeChecker, directTemplateLoading, r
|
|
|
79
79
|
const styleReplacements = [];
|
|
80
80
|
// visit all properties
|
|
81
81
|
let properties = ts.visitNodes(objectExpression.properties, (node) => ts.isObjectLiteralElementLike(node)
|
|
82
|
-
? visitComponentMetadata(nodeFactory, node, styleReplacements,
|
|
82
|
+
? visitComponentMetadata(nodeFactory, node, styleReplacements, resourceImportDeclarations, moduleKind, inlineStyleFileExtension)
|
|
83
83
|
: node);
|
|
84
84
|
// replace properties with updated properties
|
|
85
85
|
if (styleReplacements.length > 0) {
|
|
@@ -88,7 +88,7 @@ function visitDecorator(nodeFactory, node, typeChecker, directTemplateLoading, r
|
|
|
88
88
|
}
|
|
89
89
|
return nodeFactory.updateDecorator(node, nodeFactory.updateCallExpression(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [nodeFactory.updateObjectLiteralExpression(objectExpression, properties)]));
|
|
90
90
|
}
|
|
91
|
-
function visitComponentMetadata(nodeFactory, node, styleReplacements,
|
|
91
|
+
function visitComponentMetadata(nodeFactory, node, styleReplacements, resourceImportDeclarations, moduleKind = ts.ModuleKind.ES2015, inlineStyleFileExtension) {
|
|
92
92
|
if (!ts.isPropertyAssignment(node) || ts.isComputedPropertyName(node.name)) {
|
|
93
93
|
return node;
|
|
94
94
|
}
|
|
@@ -97,8 +97,7 @@ function visitComponentMetadata(nodeFactory, node, styleReplacements, directTemp
|
|
|
97
97
|
case 'moduleId':
|
|
98
98
|
return undefined;
|
|
99
99
|
case 'templateUrl':
|
|
100
|
-
const
|
|
101
|
-
const url = getResourceUrl(node.initializer, directTemplateLoading ? `!${direct_resource_1.DirectAngularResourceLoaderPath}${loaderOptions}!` : '');
|
|
100
|
+
const url = getResourceUrl(node.initializer);
|
|
102
101
|
if (!url) {
|
|
103
102
|
return node;
|
|
104
103
|
}
|
|
@@ -122,7 +121,10 @@ function visitComponentMetadata(nodeFactory, node, styleReplacements, directTemp
|
|
|
122
121
|
if (inlineStyleFileExtension) {
|
|
123
122
|
const data = Buffer.from(node.text).toString('base64');
|
|
124
123
|
const containingFile = node.getSourceFile().fileName;
|
|
125
|
-
|
|
124
|
+
// app.component.ts.css?ngResource!=!@ngtools/webpack/src/loaders/inline-resource.js?data=...!app.component.ts
|
|
125
|
+
url =
|
|
126
|
+
`${containingFile}.${inlineStyleFileExtension}?${exports.NG_COMPONENT_RESOURCE_QUERY}` +
|
|
127
|
+
`!=!${inline_resource_1.InlineAngularResourceLoaderPath}?data=${encodeURIComponent(data)}!${containingFile}`;
|
|
126
128
|
}
|
|
127
129
|
else {
|
|
128
130
|
return nodeFactory.createStringLiteral(node.text);
|
|
@@ -148,12 +150,12 @@ function visitComponentMetadata(nodeFactory, node, styleReplacements, directTemp
|
|
|
148
150
|
return node;
|
|
149
151
|
}
|
|
150
152
|
}
|
|
151
|
-
function getResourceUrl(node
|
|
153
|
+
function getResourceUrl(node) {
|
|
152
154
|
// only analyze strings
|
|
153
155
|
if (!ts.isStringLiteral(node) && !ts.isNoSubstitutionTemplateLiteral(node)) {
|
|
154
156
|
return null;
|
|
155
157
|
}
|
|
156
|
-
return `${
|
|
158
|
+
return `${/^\.?\.\//.test(node.text) ? '' : './'}${node.text}?${exports.NG_COMPONENT_RESOURCE_QUERY}`;
|
|
157
159
|
}
|
|
158
160
|
exports.getResourceUrl = getResourceUrl;
|
|
159
161
|
function isComponentDecorator(node, typeChecker) {
|
|
@@ -1,12 +0,0 @@
|
|
|
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 { LoaderContext } from 'webpack';
|
|
9
|
-
export declare const DirectAngularResourceLoaderPath: string;
|
|
10
|
-
export default function (this: LoaderContext<{
|
|
11
|
-
esModule?: 'true' | 'false';
|
|
12
|
-
}>, content: string): string;
|
|
@@ -1,16 +0,0 @@
|
|
|
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.DirectAngularResourceLoaderPath = void 0;
|
|
11
|
-
exports.DirectAngularResourceLoaderPath = __filename;
|
|
12
|
-
function default_1(content) {
|
|
13
|
-
const { esModule } = this.getOptions();
|
|
14
|
-
return `${esModule === 'false' ? 'module.exports =' : 'export default'} ${JSON.stringify(content)};`;
|
|
15
|
-
}
|
|
16
|
-
exports.default = default_1;
|