UNPKG

5.25 kBJavaScriptView Raw
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 */
9Object.defineProperty(exports, "__esModule", { value: true });
10exports.createCssResourcePlugin = void 0;
11const promises_1 = require("node:fs/promises");
12const node_path_1 = require("node:path");
13const stylesheet_processor_1 = require("./stylesheet-processor");
14const CSS_RESOURCE_NAMESPACE = 'angular:css-resource';
15/**
16 * Symbol marker used to indicate CSS resource resolution is being attempted.
17 * This is used to prevent an infinite loop within the plugin's resolve hook.
18 */
19const CSS_RESOURCE_RESOLUTION = Symbol('CSS_RESOURCE_RESOLUTION');
20/**
21 * Creates an esbuild {@link Plugin} that loads all CSS url token references using the
22 * built-in esbuild `file` loader. A plugin is used to allow for all file extensions
23 * and types to be supported without needing to manually specify all extensions
24 * within the build configuration.
25 *
26 * @returns An esbuild {@link Plugin} instance.
27 */
28function createCssResourcePlugin(url) {
29 return {
30 name: 'angular-css-resource',
31 setup(build) {
32 build.onResolve({ filter: /.*/ }, async (args) => {
33 var _a, _b;
34 // Only attempt to resolve url tokens which only exist inside CSS.
35 // Also, skip this plugin if already attempting to resolve the url-token.
36 if (args.kind !== 'url-token' || ((_a = args.pluginData) === null || _a === void 0 ? void 0 : _a[CSS_RESOURCE_RESOLUTION])) {
37 return null;
38 }
39 // If root-relative, absolute or protocol relative url, mark as external to leave the
40 // path/URL in place.
41 if (url !== stylesheet_processor_1.CssUrl.inline || /^((?:\w+:)?\/\/|data:|chrome:|#|\/)/.test(args.path)) {
42 return {
43 path: args.path,
44 external: true,
45 };
46 }
47 const { importer, kind, resolveDir, namespace, pluginData = {} } = args;
48 pluginData[CSS_RESOURCE_RESOLUTION] = true;
49 const result = await build.resolve(args.path, {
50 importer,
51 kind,
52 namespace,
53 pluginData,
54 resolveDir,
55 });
56 if (result.errors.length) {
57 const error = result.errors[0];
58 if (args.path[0] === '~') {
59 error.notes = [
60 {
61 location: null,
62 text: 'You can remove the tilde and use a relative path to reference it, which should remove this error.',
63 },
64 ];
65 }
66 else if (args.path[0] === '^') {
67 error.notes = [
68 {
69 location: null,
70 text: 'You can remove the caret and use a relative path to reference it, which should remove this error.',
71 },
72 ];
73 }
74 const extension = importer && (0, node_path_1.extname)(importer);
75 if (extension !== '.css') {
76 error.notes.push({
77 location: null,
78 text: 'Preprocessor stylesheets may not show the exact file location of the error.',
79 });
80 }
81 }
82 // Return results that are not files since these are most likely specific to another plugin
83 // and cannot be loaded by this plugin.
84 if (result.namespace !== 'file') {
85 return result;
86 }
87 // All file results are considered CSS resources and will be loaded via the file loader
88 return {
89 ...result,
90 // Use a relative path to prevent fully resolved paths in the metafile (JSON stats file).
91 // This is only necessary for custom namespaces. esbuild will handle the file namespace.
92 path: (0, node_path_1.relative)((_b = build.initialOptions.absWorkingDir) !== null && _b !== void 0 ? _b : '', result.path),
93 namespace: CSS_RESOURCE_NAMESPACE,
94 };
95 });
96 build.onLoad({ filter: /./, namespace: CSS_RESOURCE_NAMESPACE }, async (args) => {
97 var _a;
98 const resourcePath = (0, node_path_1.join)((_a = build.initialOptions.absWorkingDir) !== null && _a !== void 0 ? _a : '', args.path);
99 return {
100 contents: await (0, promises_1.readFile)(resourcePath),
101 loader: 'dataurl',
102 watchFiles: [resourcePath],
103 };
104 });
105 },
106 };
107}
108exports.createCssResourcePlugin = createCssResourcePlugin;
109//# sourceMappingURL=css-resource-plugin.js.map
\No newline at end of file