@angular-devkit/build-angular 17.1.0-next.0 → 17.1.0-next.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 +22 -19
- package/src/builders/application/build-action.d.ts +1 -0
- package/src/builders/application/build-action.js +20 -12
- package/src/builders/application/execute-post-bundle.js +8 -4
- package/src/builders/application/index.js +9 -1
- package/src/builders/application/options.js +1 -1
- package/src/builders/browser-esbuild/builder-status-warnings.js +1 -3
- package/src/builders/dev-server/builder.js +5 -0
- package/src/builders/dev-server/vite-server.js +12 -5
- package/src/builders/karma/index.js +4 -1
- package/src/builders/karma/schema.d.ts +6 -2
- package/src/builders/karma/schema.json +12 -2
- package/src/builders/ssr-dev-server/index.js +27 -18
- package/src/tools/esbuild/angular/angular-host.js +6 -0
- package/src/tools/esbuild/angular/compiler-plugin.js +1 -1
- package/src/tools/esbuild/angular/component-stylesheets.js +1 -1
- package/src/tools/esbuild/angular/jit-plugin-callbacks.d.ts +2 -1
- package/src/tools/esbuild/angular/jit-plugin-callbacks.js +15 -15
- package/src/tools/esbuild/angular/source-file-cache.js +0 -1
- package/src/tools/esbuild/compiler-plugin-options.js +4 -2
- package/src/tools/esbuild/global-styles.js +4 -2
- package/src/tools/esbuild/i18n-locale-plugin.d.ts +4 -0
- package/src/tools/esbuild/i18n-locale-plugin.js +48 -18
- package/src/tools/esbuild/stylesheets/bundle-options.d.ts +3 -0
- package/src/tools/esbuild/stylesheets/bundle-options.js +11 -6
- package/src/tools/esbuild/stylesheets/css-inline-fonts-plugin.d.ts +25 -0
- package/src/tools/esbuild/stylesheets/css-inline-fonts-plugin.js +57 -0
- package/src/tools/esbuild/watcher.d.ts +1 -0
- package/src/tools/esbuild/watcher.js +56 -106
- package/src/tools/sass/rebasing-importer.js +29 -4
- package/src/utils/check-port.js +15 -29
- package/src/utils/delete-output-dir.d.ts +1 -1
- package/src/utils/delete-output-dir.js +11 -2
- package/src/utils/index-file/inline-fonts.d.ts +6 -1
- package/src/utils/index-file/inline-fonts.js +30 -14
- package/src/utils/server-rendering/esm-in-memory-loader/node-18-utils.js +6 -5
- package/src/utils/server-rendering/esm-in-memory-loader/register-hooks.js +1 -3
- package/src/utils/spinner.js +1 -1
|
@@ -6,13 +6,11 @@
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
-
};
|
|
12
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
10
|
exports.setupJitPluginCallbacks = void 0;
|
|
14
11
|
const promises_1 = require("node:fs/promises");
|
|
15
|
-
const node_path_1 =
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
const load_result_cache_1 = require("../load-result-cache");
|
|
16
14
|
const uri_1 = require("./uri");
|
|
17
15
|
/**
|
|
18
16
|
* Loads/extracts the contents from a load callback Angular JIT entry.
|
|
@@ -27,7 +25,7 @@ const uri_1 = require("./uri");
|
|
|
27
25
|
*/
|
|
28
26
|
async function loadEntry(entry, root, skipRead) {
|
|
29
27
|
if (entry.startsWith('file:')) {
|
|
30
|
-
const specifier = node_path_1.
|
|
28
|
+
const specifier = (0, node_path_1.join)(root, entry.slice(5));
|
|
31
29
|
return {
|
|
32
30
|
path: specifier,
|
|
33
31
|
contents: skipRead ? undefined : await (0, promises_1.readFile)(specifier, 'utf-8'),
|
|
@@ -36,7 +34,7 @@ async function loadEntry(entry, root, skipRead) {
|
|
|
36
34
|
else if (entry.startsWith('inline:')) {
|
|
37
35
|
const [importer, data] = entry.slice(7).split(';', 2);
|
|
38
36
|
return {
|
|
39
|
-
path: node_path_1.
|
|
37
|
+
path: (0, node_path_1.join)(root, importer),
|
|
40
38
|
contents: Buffer.from(data, 'base64').toString(),
|
|
41
39
|
};
|
|
42
40
|
}
|
|
@@ -53,7 +51,7 @@ async function loadEntry(entry, root, skipRead) {
|
|
|
53
51
|
* @param styleOptions The options to use when bundling stylesheets.
|
|
54
52
|
* @param additionalResultFiles A Map where stylesheet resources will be added.
|
|
55
53
|
*/
|
|
56
|
-
function setupJitPluginCallbacks(build, stylesheetBundler, additionalResultFiles, inlineStyleLanguage) {
|
|
54
|
+
function setupJitPluginCallbacks(build, stylesheetBundler, additionalResultFiles, inlineStyleLanguage, loadCache) {
|
|
57
55
|
const root = build.initialOptions.absWorkingDir ?? '';
|
|
58
56
|
// Add a resolve callback to capture and parse any JIT URIs that were added by the
|
|
59
57
|
// JIT resource TypeScript transformer.
|
|
@@ -68,13 +66,13 @@ function setupJitPluginCallbacks(build, stylesheetBundler, additionalResultFiles
|
|
|
68
66
|
return {
|
|
69
67
|
// Use a relative path to prevent fully resolved paths in the metafile (JSON stats file).
|
|
70
68
|
// This is only necessary for custom namespaces. esbuild will handle the file namespace.
|
|
71
|
-
path: 'file:' + node_path_1.
|
|
69
|
+
path: 'file:' + (0, node_path_1.relative)(root, (0, node_path_1.join)((0, node_path_1.dirname)(args.importer), specifier)),
|
|
72
70
|
namespace,
|
|
73
71
|
};
|
|
74
72
|
}
|
|
75
73
|
else {
|
|
76
74
|
// Inline data may need the importer to resolve imports/references within the content
|
|
77
|
-
const importer = node_path_1.
|
|
75
|
+
const importer = (0, node_path_1.relative)(root, args.importer);
|
|
78
76
|
return {
|
|
79
77
|
path: `inline:${importer};${specifier}`,
|
|
80
78
|
namespace,
|
|
@@ -82,7 +80,7 @@ function setupJitPluginCallbacks(build, stylesheetBundler, additionalResultFiles
|
|
|
82
80
|
}
|
|
83
81
|
});
|
|
84
82
|
// Add a load callback to handle Component stylesheets (both inline and external)
|
|
85
|
-
build.onLoad({ filter: /./, namespace: uri_1.JIT_STYLE_NAMESPACE }, async (args) => {
|
|
83
|
+
build.onLoad({ filter: /./, namespace: uri_1.JIT_STYLE_NAMESPACE }, (0, load_result_cache_1.createCachedLoad)(loadCache, async (args) => {
|
|
86
84
|
// skipRead is used here because the stylesheet bundling will read a file stylesheet
|
|
87
85
|
// directly either via a preprocessor or esbuild itself.
|
|
88
86
|
const entry = await loadEntry(args.path, root, true /* skipRead */);
|
|
@@ -94,24 +92,26 @@ function setupJitPluginCallbacks(build, stylesheetBundler, additionalResultFiles
|
|
|
94
92
|
else {
|
|
95
93
|
stylesheetResult = await stylesheetBundler.bundleInline(entry.contents, entry.path, inlineStyleLanguage);
|
|
96
94
|
}
|
|
97
|
-
const { contents, resourceFiles, errors, warnings, metafile } = stylesheetResult;
|
|
95
|
+
const { contents, resourceFiles, errors, warnings, metafile, referencedFiles } = stylesheetResult;
|
|
98
96
|
additionalResultFiles.set(entry.path, { outputFiles: resourceFiles, metafile });
|
|
99
97
|
return {
|
|
100
98
|
errors,
|
|
101
99
|
warnings,
|
|
102
100
|
contents,
|
|
103
101
|
loader: 'text',
|
|
102
|
+
watchFiles: referencedFiles && [...referencedFiles],
|
|
104
103
|
};
|
|
105
|
-
});
|
|
104
|
+
}));
|
|
106
105
|
// Add a load callback to handle Component templates
|
|
107
106
|
// NOTE: While this callback supports both inline and external templates, the transformer
|
|
108
107
|
// currently only supports generating URIs for external templates.
|
|
109
|
-
build.onLoad({ filter: /./, namespace: uri_1.JIT_TEMPLATE_NAMESPACE }, async (args) => {
|
|
110
|
-
const { contents } = await loadEntry(args.path, root);
|
|
108
|
+
build.onLoad({ filter: /./, namespace: uri_1.JIT_TEMPLATE_NAMESPACE }, (0, load_result_cache_1.createCachedLoad)(loadCache, async (args) => {
|
|
109
|
+
const { contents, path } = await loadEntry(args.path, root);
|
|
111
110
|
return {
|
|
112
111
|
contents,
|
|
113
112
|
loader: 'text',
|
|
113
|
+
watchFiles: [path],
|
|
114
114
|
};
|
|
115
|
-
});
|
|
115
|
+
}));
|
|
116
116
|
}
|
|
117
117
|
exports.setupJitPluginCallbacks = setupJitPluginCallbacks;
|
|
@@ -52,7 +52,6 @@ class SourceFileCache extends Map {
|
|
|
52
52
|
}
|
|
53
53
|
for (let file of files) {
|
|
54
54
|
file = path.normalize(file);
|
|
55
|
-
this.typeScriptFileCache.delete(file);
|
|
56
55
|
this.loadResultCache.invalidate(file);
|
|
57
56
|
// Normalize separators to allow matching TypeScript Host paths
|
|
58
57
|
if (USING_WINDOWS) {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.createCompilerPluginOptions = void 0;
|
|
11
11
|
function createCompilerPluginOptions(options, target, sourceFileCache) {
|
|
12
|
-
const { workspaceRoot, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, inlineStyleLanguage, jit, tailwindConfiguration, } = options;
|
|
12
|
+
const { workspaceRoot, optimizationOptions, sourcemapOptions, tsconfig, outputNames, fileReplacements, externalDependencies, preserveSymlinks, stylePreprocessorOptions, advancedOptimizations, inlineStyleLanguage, jit, cacheOptions, tailwindConfiguration, publicPath, } = options;
|
|
13
13
|
return {
|
|
14
14
|
// JS/TS options
|
|
15
15
|
pluginOptions: {
|
|
@@ -26,6 +26,7 @@ function createCompilerPluginOptions(options, target, sourceFileCache) {
|
|
|
26
26
|
// Component stylesheet options
|
|
27
27
|
styleOptions: {
|
|
28
28
|
workspaceRoot,
|
|
29
|
+
inlineFonts: !!optimizationOptions.fonts.inline,
|
|
29
30
|
optimization: !!optimizationOptions.styles.minify,
|
|
30
31
|
sourcemap:
|
|
31
32
|
// Hidden component stylesheet sourcemaps are inaccessible which is effectively
|
|
@@ -39,7 +40,8 @@ function createCompilerPluginOptions(options, target, sourceFileCache) {
|
|
|
39
40
|
inlineStyleLanguage,
|
|
40
41
|
preserveSymlinks,
|
|
41
42
|
tailwindConfiguration,
|
|
42
|
-
|
|
43
|
+
cacheOptions,
|
|
44
|
+
publicPath,
|
|
43
45
|
},
|
|
44
46
|
};
|
|
45
47
|
}
|
|
@@ -15,7 +15,7 @@ const node_assert_1 = __importDefault(require("node:assert"));
|
|
|
15
15
|
const bundle_options_1 = require("./stylesheets/bundle-options");
|
|
16
16
|
const virtual_module_plugin_1 = require("./virtual-module-plugin");
|
|
17
17
|
function createGlobalStylesBundleOptions(options, target, initial) {
|
|
18
|
-
const { workspaceRoot, optimizationOptions, sourcemapOptions, outputNames, globalStyles, preserveSymlinks, externalDependencies, stylePreprocessorOptions, tailwindConfiguration, } = options;
|
|
18
|
+
const { workspaceRoot, optimizationOptions, sourcemapOptions, outputNames, globalStyles, preserveSymlinks, externalDependencies, stylePreprocessorOptions, tailwindConfiguration, cacheOptions, publicPath, } = options;
|
|
19
19
|
const namespace = 'angular:styles/global';
|
|
20
20
|
const entryPoints = {};
|
|
21
21
|
let found = false;
|
|
@@ -33,6 +33,7 @@ function createGlobalStylesBundleOptions(options, target, initial) {
|
|
|
33
33
|
const buildOptions = (0, bundle_options_1.createStylesheetBundleOptions)({
|
|
34
34
|
workspaceRoot,
|
|
35
35
|
optimization: !!optimizationOptions.styles.minify,
|
|
36
|
+
inlineFonts: !!optimizationOptions.fonts.inline,
|
|
36
37
|
sourcemap: !!sourcemapOptions.styles,
|
|
37
38
|
preserveSymlinks,
|
|
38
39
|
target,
|
|
@@ -45,7 +46,8 @@ function createGlobalStylesBundleOptions(options, target, initial) {
|
|
|
45
46
|
},
|
|
46
47
|
includePaths: stylePreprocessorOptions?.includePaths,
|
|
47
48
|
tailwindConfiguration,
|
|
48
|
-
|
|
49
|
+
cacheOptions,
|
|
50
|
+
publicPath,
|
|
49
51
|
}, loadCache);
|
|
50
52
|
// Keep special CSS comments `/*! comment */` in place when `removeSpecialComments` is disabled.
|
|
51
53
|
// These comments are special for a number of CSS tools such as Critters and PurgeCSS.
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import type { Plugin } from 'esbuild';
|
|
9
|
+
/**
|
|
10
|
+
* The internal namespace used by generated locale import statements and Angular locale data plugin.
|
|
11
|
+
*/
|
|
12
|
+
export declare const LOCALE_DATA_NAMESPACE = "angular:locale/data";
|
|
9
13
|
/**
|
|
10
14
|
* The base module location used to search for locale specific data.
|
|
11
15
|
*/
|
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.createAngularLocaleDataPlugin = exports.LOCALE_DATA_BASE_MODULE = void 0;
|
|
10
|
+
exports.createAngularLocaleDataPlugin = exports.LOCALE_DATA_BASE_MODULE = exports.LOCALE_DATA_NAMESPACE = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* The internal namespace used by generated locale import statements and Angular locale data plugin.
|
|
13
|
+
*/
|
|
14
|
+
exports.LOCALE_DATA_NAMESPACE = 'angular:locale/data';
|
|
11
15
|
/**
|
|
12
16
|
* The base module location used to search for locale specific data.
|
|
13
17
|
*/
|
|
@@ -33,12 +37,37 @@ function createAngularLocaleDataPlugin() {
|
|
|
33
37
|
}
|
|
34
38
|
build.onResolve({ filter: /^angular:locale\/data:/ }, async ({ path }) => {
|
|
35
39
|
// Extract the locale from the path
|
|
36
|
-
const
|
|
37
|
-
//
|
|
38
|
-
let
|
|
40
|
+
const rawLocaleTag = path.split(':', 3)[2];
|
|
41
|
+
// Extract and normalize the base name of the raw locale tag
|
|
42
|
+
let partialLocaleTag;
|
|
43
|
+
try {
|
|
44
|
+
const locale = new Intl.Locale(rawLocaleTag);
|
|
45
|
+
partialLocaleTag = locale.baseName;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return {
|
|
49
|
+
path: rawLocaleTag,
|
|
50
|
+
namespace: exports.LOCALE_DATA_NAMESPACE,
|
|
51
|
+
errors: [
|
|
52
|
+
{
|
|
53
|
+
text: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
39
58
|
let exact = true;
|
|
40
|
-
while (
|
|
41
|
-
|
|
59
|
+
while (partialLocaleTag) {
|
|
60
|
+
// Angular embeds the `en`/`en-US` locale into the framework and it does not need to be included again here.
|
|
61
|
+
// The onLoad hook below for the locale data namespace has an `empty` loader that will prevent inclusion.
|
|
62
|
+
// Angular does not contain exact locale data for `en-US` but `en` is equivalent.
|
|
63
|
+
if (partialLocaleTag === 'en' || partialLocaleTag === 'en-US') {
|
|
64
|
+
return {
|
|
65
|
+
path: rawLocaleTag,
|
|
66
|
+
namespace: exports.LOCALE_DATA_NAMESPACE,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Attempt to resolve the locale tag data within the Angular base module location
|
|
70
|
+
const potentialPath = `${exports.LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`;
|
|
42
71
|
const result = await build.resolve(potentialPath, {
|
|
43
72
|
kind: 'import-statement',
|
|
44
73
|
resolveDir: build.initialOptions.absWorkingDir,
|
|
@@ -54,36 +83,37 @@ function createAngularLocaleDataPlugin() {
|
|
|
54
83
|
...result.warnings,
|
|
55
84
|
{
|
|
56
85
|
location: null,
|
|
57
|
-
text: `Locale data for '${
|
|
86
|
+
text: `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`,
|
|
58
87
|
},
|
|
59
88
|
],
|
|
60
89
|
};
|
|
61
90
|
}
|
|
62
91
|
}
|
|
63
|
-
// Remove the last subtag and try again with a less specific locale
|
|
64
|
-
|
|
65
|
-
|
|
92
|
+
// Remove the last subtag and try again with a less specific locale.
|
|
93
|
+
// Usually the match is exact so the string splitting here is not done until actually needed after the exact
|
|
94
|
+
// match fails to resolve.
|
|
95
|
+
const parts = partialLocaleTag.split('-');
|
|
96
|
+
partialLocaleTag = parts.slice(0, -1).join('-');
|
|
66
97
|
exact = false;
|
|
67
|
-
// The locales "en" and "en-US" are considered exact to retain existing behavior
|
|
68
|
-
if (originalLocale === 'en-US' && partialLocale === 'en') {
|
|
69
|
-
exact = true;
|
|
70
|
-
}
|
|
71
98
|
}
|
|
72
99
|
// Not found so issue a warning and use an empty loader. Framework built-in `en-US` data will be used.
|
|
73
100
|
// This retains existing behavior as in the Webpack-based builder.
|
|
74
101
|
return {
|
|
75
|
-
path:
|
|
76
|
-
namespace:
|
|
102
|
+
path: rawLocaleTag,
|
|
103
|
+
namespace: exports.LOCALE_DATA_NAMESPACE,
|
|
77
104
|
warnings: [
|
|
78
105
|
{
|
|
79
106
|
location: null,
|
|
80
|
-
text: `Locale data for '${
|
|
107
|
+
text: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`,
|
|
81
108
|
},
|
|
82
109
|
],
|
|
83
110
|
};
|
|
84
111
|
});
|
|
85
112
|
// Locales that cannot be found will be loaded as empty content with a warning from the resolve step
|
|
86
|
-
build.onLoad({ filter: /./, namespace:
|
|
113
|
+
build.onLoad({ filter: /./, namespace: exports.LOCALE_DATA_NAMESPACE }, () => ({
|
|
114
|
+
contents: '',
|
|
115
|
+
loader: 'empty',
|
|
116
|
+
}));
|
|
87
117
|
},
|
|
88
118
|
};
|
|
89
119
|
}
|
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import type { BuildOptions } from 'esbuild';
|
|
9
|
+
import { NormalizedCachedOptions } from '../../../utils/normalize-cache';
|
|
9
10
|
import { LoadResultCache } from '../load-result-cache';
|
|
10
11
|
export interface BundleStylesheetOptions {
|
|
11
12
|
workspaceRoot: string;
|
|
12
13
|
optimization: boolean;
|
|
14
|
+
inlineFonts: boolean;
|
|
13
15
|
preserveSymlinks?: boolean;
|
|
14
16
|
sourcemap: boolean | 'external' | 'inline';
|
|
15
17
|
outputNames: {
|
|
@@ -24,6 +26,7 @@ export interface BundleStylesheetOptions {
|
|
|
24
26
|
package: string;
|
|
25
27
|
};
|
|
26
28
|
publicPath?: string;
|
|
29
|
+
cacheOptions: NormalizedCachedOptions;
|
|
27
30
|
}
|
|
28
31
|
export declare function createStylesheetBundleOptions(options: BundleStylesheetOptions, cache?: LoadResultCache, inlineComponentData?: Record<string, string>): BuildOptions & {
|
|
29
32
|
plugins: NonNullable<BuildOptions['plugins']>;
|
|
@@ -12,6 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.createStylesheetBundleOptions = void 0;
|
|
14
14
|
const node_path_1 = __importDefault(require("node:path"));
|
|
15
|
+
const css_inline_fonts_plugin_1 = require("./css-inline-fonts-plugin");
|
|
15
16
|
const css_language_1 = require("./css-language");
|
|
16
17
|
const css_resource_plugin_1 = require("./css-resource-plugin");
|
|
17
18
|
const less_language_1 = require("./less-language");
|
|
@@ -26,6 +27,15 @@ function createStylesheetBundleOptions(options, cache, inlineComponentData) {
|
|
|
26
27
|
inlineComponentData,
|
|
27
28
|
tailwindConfiguration: options.tailwindConfiguration,
|
|
28
29
|
}, cache);
|
|
30
|
+
const plugins = [
|
|
31
|
+
pluginFactory.create(sass_language_1.SassStylesheetLanguage),
|
|
32
|
+
pluginFactory.create(less_language_1.LessStylesheetLanguage),
|
|
33
|
+
pluginFactory.create(css_language_1.CssStylesheetLanguage),
|
|
34
|
+
(0, css_resource_plugin_1.createCssResourcePlugin)(cache),
|
|
35
|
+
];
|
|
36
|
+
if (options.inlineFonts) {
|
|
37
|
+
plugins.push((0, css_inline_fonts_plugin_1.createCssInlineFontsPlugin)({ cache, cacheOptions: options.cacheOptions }));
|
|
38
|
+
}
|
|
29
39
|
return {
|
|
30
40
|
absWorkingDir: options.workspaceRoot,
|
|
31
41
|
bundle: true,
|
|
@@ -44,12 +54,7 @@ function createStylesheetBundleOptions(options, cache, inlineComponentData) {
|
|
|
44
54
|
publicPath: options.publicPath,
|
|
45
55
|
conditions: ['style', 'sass', 'less'],
|
|
46
56
|
mainFields: ['style', 'sass'],
|
|
47
|
-
plugins
|
|
48
|
-
pluginFactory.create(sass_language_1.SassStylesheetLanguage),
|
|
49
|
-
pluginFactory.create(less_language_1.LessStylesheetLanguage),
|
|
50
|
-
pluginFactory.create(css_language_1.CssStylesheetLanguage),
|
|
51
|
-
(0, css_resource_plugin_1.createCssResourcePlugin)(cache),
|
|
52
|
-
],
|
|
57
|
+
plugins,
|
|
53
58
|
};
|
|
54
59
|
}
|
|
55
60
|
exports.createStylesheetBundleOptions = createStylesheetBundleOptions;
|
|
@@ -0,0 +1,25 @@
|
|
|
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 type { Plugin } from 'esbuild';
|
|
9
|
+
import { NormalizedCachedOptions } from '../../../utils/normalize-cache';
|
|
10
|
+
import { LoadResultCache } from '../load-result-cache';
|
|
11
|
+
/**
|
|
12
|
+
* Options for the createCssInlineFontsPlugin
|
|
13
|
+
* @see createCssInlineFontsPlugin
|
|
14
|
+
*/
|
|
15
|
+
export interface CssInlineFontsPluginOptions {
|
|
16
|
+
/** Disk cache normalized options */
|
|
17
|
+
cacheOptions?: NormalizedCachedOptions;
|
|
18
|
+
/** Load results cache. */
|
|
19
|
+
cache?: LoadResultCache;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates an esbuild {@link Plugin} that inlines fonts imported via import-rule.
|
|
23
|
+
* within the build configuration.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createCssInlineFontsPlugin({ cache, cacheOptions, }: CssInlineFontsPluginOptions): Plugin;
|
|
@@ -0,0 +1,57 @@
|
|
|
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.createCssInlineFontsPlugin = void 0;
|
|
11
|
+
const inline_fonts_1 = require("../../../utils/index-file/inline-fonts");
|
|
12
|
+
const load_result_cache_1 = require("../load-result-cache");
|
|
13
|
+
/**
|
|
14
|
+
* Creates an esbuild {@link Plugin} that inlines fonts imported via import-rule.
|
|
15
|
+
* within the build configuration.
|
|
16
|
+
*/
|
|
17
|
+
function createCssInlineFontsPlugin({ cache, cacheOptions, }) {
|
|
18
|
+
return {
|
|
19
|
+
name: 'angular-css-inline-fonts-plugin',
|
|
20
|
+
setup(build) {
|
|
21
|
+
const inlineFontsProcessor = new inline_fonts_1.InlineFontsProcessor({ cache: cacheOptions, minify: false });
|
|
22
|
+
build.onResolve({ filter: /fonts\.googleapis\.com|use\.typekit\.net/ }, (args) => {
|
|
23
|
+
// Only attempt to resolve import-rule tokens which only exist inside CSS.
|
|
24
|
+
if (args.kind !== 'import-rule') {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
if (!inlineFontsProcessor.canInlineRequest(args.path)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
path: args.path,
|
|
32
|
+
namespace: 'css-inline-fonts',
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
build.onLoad({ filter: /./, namespace: 'css-inline-fonts' }, (0, load_result_cache_1.createCachedLoad)(cache, async (args) => {
|
|
36
|
+
try {
|
|
37
|
+
return {
|
|
38
|
+
contents: await inlineFontsProcessor.processURL(args.path),
|
|
39
|
+
loader: 'css',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return {
|
|
44
|
+
loader: 'css',
|
|
45
|
+
errors: [
|
|
46
|
+
{
|
|
47
|
+
text: `Failed to inline external stylesheet '${args.path}'.`,
|
|
48
|
+
detail: error,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
exports.createCssInlineFontsPlugin = createCssInlineFontsPlugin;
|
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
9
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
13
|
exports.createWatcher = exports.ChangedFiles = void 0;
|
|
11
|
-
const
|
|
12
|
-
const node_path_1 = require("node:path");
|
|
14
|
+
const watchpack_1 = __importDefault(require("watchpack"));
|
|
13
15
|
class ChangedFiles {
|
|
14
16
|
added = new Set();
|
|
15
17
|
modified = new Set();
|
|
@@ -28,105 +30,30 @@ class ChangedFiles {
|
|
|
28
30
|
}
|
|
29
31
|
exports.ChangedFiles = ChangedFiles;
|
|
30
32
|
function createWatcher(options) {
|
|
31
|
-
const watcher = new
|
|
32
|
-
|
|
33
|
-
interval: options?.interval,
|
|
33
|
+
const watcher = new watchpack_1.default({
|
|
34
|
+
poll: options?.polling ? options?.interval ?? true : false,
|
|
34
35
|
ignored: options?.ignored,
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
followSymlinks: options?.followSymlinks,
|
|
37
|
+
aggregateTimeout: 250,
|
|
37
38
|
});
|
|
39
|
+
const watchedFiles = new Set();
|
|
38
40
|
const nextQueue = [];
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
* Example:
|
|
45
|
-
* rename | 'C:/../src/app/app.component.css'
|
|
46
|
-
* rename | 'C:/../src/app/app.component.css'
|
|
47
|
-
* change | 'C:/../src/app/app.component.css'
|
|
48
|
-
*
|
|
49
|
-
*/
|
|
50
|
-
let currentEvents;
|
|
51
|
-
/**
|
|
52
|
-
* Using `watcher.on('all')` does not capture some of events fired when using Visual studio and this does not happen all the time,
|
|
53
|
-
* but only after a file has been changed 3 or more times.
|
|
54
|
-
*
|
|
55
|
-
* Also, some IDEs such as Visual Studio (not VS Code) will fire a rename event instead of unlink when a file is renamed or changed.
|
|
56
|
-
*
|
|
57
|
-
* Example:
|
|
58
|
-
* ```
|
|
59
|
-
* watcher.on('raw')
|
|
60
|
-
* Change 1
|
|
61
|
-
* rename | 'C:/../src/app/app.component.css'
|
|
62
|
-
* rename | 'C:/../src/app/app.component.css'
|
|
63
|
-
* change | 'C:/../src/app/app.component.css'
|
|
64
|
-
*
|
|
65
|
-
* Change 2
|
|
66
|
-
* rename | 'C:/../src/app/app.component.css'
|
|
67
|
-
* rename | 'C:/../src/app/app.component.css'
|
|
68
|
-
* change | 'C:/../src/app/app.component.css'
|
|
69
|
-
*
|
|
70
|
-
* Change 3
|
|
71
|
-
* rename | 'C:/../src/app/app.component.css'
|
|
72
|
-
* rename | 'C:/../src/app/app.component.css'
|
|
73
|
-
* change | 'C:/../src/app/app.component.css'
|
|
74
|
-
*
|
|
75
|
-
* watcher.on('all')
|
|
76
|
-
* Change 1
|
|
77
|
-
* change | 'C:\\..\\src\\app\\app.component.css'
|
|
78
|
-
*
|
|
79
|
-
* Change 2
|
|
80
|
-
* unlink | 'C:\\..\\src\\app\\app.component.css'
|
|
81
|
-
*
|
|
82
|
-
* Change 3
|
|
83
|
-
* ... (Nothing)
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
watcher.on('raw', (event, path, { watchedPath }) => {
|
|
87
|
-
switch (event) {
|
|
88
|
-
case 'add':
|
|
89
|
-
case 'change':
|
|
90
|
-
// When using Visual Studio the rename event is fired before a change event when the contents of the file changed
|
|
91
|
-
// or instead of `unlink` when the file has been renamed.
|
|
92
|
-
case 'unlink':
|
|
93
|
-
case 'rename':
|
|
94
|
-
// When polling is enabled `watchedPath` can be undefined.
|
|
95
|
-
// `path` is always normalized unlike `watchedPath`.
|
|
96
|
-
const changedPath = watchedPath ? (0, node_path_1.normalize)(watchedPath) : path;
|
|
97
|
-
currentEvents ??= new Map();
|
|
98
|
-
currentEvents.set(changedPath, event);
|
|
99
|
-
break;
|
|
100
|
-
default:
|
|
101
|
-
return;
|
|
41
|
+
let currentChangedFiles;
|
|
42
|
+
watcher.on('aggregated', (changes, removals) => {
|
|
43
|
+
const changedFiles = currentChangedFiles ?? new ChangedFiles();
|
|
44
|
+
for (const file of changes) {
|
|
45
|
+
changedFiles.modified.add(file);
|
|
102
46
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
switch (event) {
|
|
114
|
-
case 'add':
|
|
115
|
-
currentChanges.added.add(path);
|
|
116
|
-
break;
|
|
117
|
-
case 'change':
|
|
118
|
-
currentChanges.modified.add(path);
|
|
119
|
-
break;
|
|
120
|
-
case 'unlink':
|
|
121
|
-
case 'rename':
|
|
122
|
-
currentChanges.removed.add(path);
|
|
123
|
-
break;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
next(currentChanges);
|
|
127
|
-
}
|
|
128
|
-
}, 250);
|
|
129
|
-
nextWaitTimeout?.unref();
|
|
47
|
+
for (const file of removals) {
|
|
48
|
+
changedFiles.removed.add(file);
|
|
49
|
+
}
|
|
50
|
+
const next = nextQueue.shift();
|
|
51
|
+
if (next) {
|
|
52
|
+
currentChangedFiles = undefined;
|
|
53
|
+
next(changedFiles);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
currentChangedFiles = changedFiles;
|
|
130
57
|
}
|
|
131
58
|
});
|
|
132
59
|
return {
|
|
@@ -134,9 +61,9 @@ function createWatcher(options) {
|
|
|
134
61
|
return this;
|
|
135
62
|
},
|
|
136
63
|
async next() {
|
|
137
|
-
if (
|
|
138
|
-
const result = { value:
|
|
139
|
-
|
|
64
|
+
if (currentChangedFiles && nextQueue.length === 0) {
|
|
65
|
+
const result = { value: currentChangedFiles };
|
|
66
|
+
currentChangedFiles = undefined;
|
|
140
67
|
return result;
|
|
141
68
|
}
|
|
142
69
|
return new Promise((resolve) => {
|
|
@@ -144,17 +71,40 @@ function createWatcher(options) {
|
|
|
144
71
|
});
|
|
145
72
|
},
|
|
146
73
|
add(paths) {
|
|
147
|
-
|
|
74
|
+
const previousSize = watchedFiles.size;
|
|
75
|
+
if (typeof paths === 'string') {
|
|
76
|
+
watchedFiles.add(paths);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
for (const file of paths) {
|
|
80
|
+
watchedFiles.add(file);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (previousSize !== watchedFiles.size) {
|
|
84
|
+
watcher.watch({
|
|
85
|
+
files: watchedFiles,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
148
88
|
},
|
|
149
89
|
remove(paths) {
|
|
150
|
-
|
|
90
|
+
const previousSize = watchedFiles.size;
|
|
91
|
+
if (typeof paths === 'string') {
|
|
92
|
+
watchedFiles.delete(paths);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
for (const file of paths) {
|
|
96
|
+
watchedFiles.delete(file);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (previousSize !== watchedFiles.size) {
|
|
100
|
+
watcher.watch({
|
|
101
|
+
files: watchedFiles,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
151
104
|
},
|
|
152
105
|
async close() {
|
|
153
106
|
try {
|
|
154
|
-
|
|
155
|
-
if (nextWaitTimeout) {
|
|
156
|
-
clearTimeout(nextWaitTimeout);
|
|
157
|
-
}
|
|
107
|
+
watcher.close();
|
|
158
108
|
}
|
|
159
109
|
finally {
|
|
160
110
|
let next;
|