Skip to content

Commit 83000bd

Browse files
committed
refactor(@angular-devkit/build-angular): allow internal externalPackages option to exclude packages
To support future use cases, the internal `externalPackages` application builder option now also accepts an object form with an `exclude` array field in addition to the existing boolean value. The `exclude` capability allows for specifying individual packages that should always be bundled when using the external packages functionality. Currently the external packages functionality is only used by the Vite-based development server.
1 parent 2a25e06 commit 83000bd

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

packages/angular_devkit/build_angular/src/builders/application/options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ interface InternalOptions {
5858
* Indicates whether all node packages should be marked as external.
5959
* Currently used by the dev-server to support prebundling.
6060
*/
61-
externalPackages?: boolean;
61+
externalPackages?: boolean | { exclude: string[] };
6262

6363
/**
6464
* Forces the output from the localize post-processing to not create nested directories per locale output.

packages/angular_devkit/build_angular/src/tools/esbuild/application-code-bundle.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,17 @@ export function createBrowserCodeBundleOptions(
6666

6767
if (options.externalPackages) {
6868
// Package files affected by a customized loader should not be implicitly marked as external
69-
if (options.loaderExtensions || options.plugins) {
69+
if (
70+
options.loaderExtensions ||
71+
options.plugins ||
72+
typeof options.externalPackages === 'object'
73+
) {
7074
// Plugin must be added after custom plugins to ensure any added loader options are considered
71-
buildOptions.plugins?.push(createExternalPackagesPlugin());
75+
buildOptions.plugins?.push(
76+
createExternalPackagesPlugin(
77+
options.externalPackages !== true ? options.externalPackages : undefined,
78+
),
79+
);
7280
} else {
7381
// Safe to use the packages external option directly
7482
buildOptions.packages = 'external';

packages/angular_devkit/build_angular/src/tools/esbuild/external-packages-plugin.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,34 @@ const EXTERNAL_PACKAGE_RESOLUTION = Symbol('EXTERNAL_PACKAGE_RESOLUTION');
1818
*
1919
* @returns An esbuild plugin.
2020
*/
21-
export function createExternalPackagesPlugin(): Plugin {
21+
export function createExternalPackagesPlugin(options?: { exclude?: string[] }): Plugin {
22+
const exclusions = options?.exclude?.length ? new Set(options.exclude) : undefined;
23+
2224
return {
2325
name: 'angular-external-packages',
2426
setup(build) {
25-
// Safe to use native packages external option if no loader options present
26-
if (
27-
build.initialOptions.loader === undefined ||
28-
Object.keys(build.initialOptions.loader).length === 0
29-
) {
27+
const loaderOptionKeys =
28+
build.initialOptions.loader && Object.keys(build.initialOptions.loader);
29+
30+
// Safe to use native packages external option if no loader options or exclusions present
31+
if (!exclusions && !loaderOptionKeys?.length) {
3032
build.initialOptions.packages = 'external';
3133

3234
return;
3335
}
3436

35-
const loaderFileExtensions = new Set(Object.keys(build.initialOptions.loader));
37+
const loaderFileExtensions = new Set(loaderOptionKeys);
3638

3739
// Only attempt resolve of non-relative and non-absolute paths
3840
build.onResolve({ filter: /^[^./]/ }, async (args) => {
3941
if (args.pluginData?.[EXTERNAL_PACKAGE_RESOLUTION]) {
4042
return null;
4143
}
4244

45+
if (exclusions?.has(args.path)) {
46+
return null;
47+
}
48+
4349
const { importer, kind, resolveDir, namespace, pluginData = {} } = args;
4450
pluginData[EXTERNAL_PACKAGE_RESOLUTION] = true;
4551

0 commit comments

Comments
 (0)