Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(@angular-devkit/build-angular): improve rebuild performance with loaders and prebundling #27146

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
*/

import type { Plugin } from 'esbuild';
import { extname } from 'node:path';

const EXTERNAL_PACKAGE_RESOLUTION = Symbol('EXTERNAL_PACKAGE_RESOLUTION');
import { extname, isAbsolute } from 'node:path';

/**
* Creates a plugin that marks any resolved path as external if it is within a node modules directory.
Expand All @@ -34,49 +32,31 @@ export function createExternalPackagesPlugin(options?: { exclude?: string[] }):
return;
}

const loaderFileExtensions = new Set(loaderOptionKeys);
const loaderFileExtensions = loaderOptionKeys && new Set(loaderOptionKeys);

// Only attempt resolve of non-relative and non-absolute paths
// esbuild's external packages option considers any package-like path as external
// which would exclude paths that are absolute or explicitly relative
build.onResolve({ filter: /^[^./]/ }, async (args) => {
Comment on lines +37 to 39
Copy link

@sod sod Feb 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this evanw/esbuild#3667 help to exclude this callback to run already in esbuild? Like

const loaders = loaderFileExtensions ? `(${Array.from(loaderFileExtensions).join('|')})$` : '';
const libraries = '^(@angular|rxjs|@ngrx)\/)`';
const exclude = loaders ? `(${libraries}|${loaders})` : libraries;

build.onResolve({ filter: /^[^./]/, exclude }, async (args) => {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No particularly for this use-case.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like my esbuild PR is not happening. At least I got no feedback for 3 months. No urgency on my part, as we patch angular cli via yarn patch to apply #27120 ourself.

if (args.pluginData?.[EXTERNAL_PACKAGE_RESOLUTION]) {
return null;
}

// Skip marking excluded packages
if (exclusions?.has(args.path)) {
return null;
}

const { importer, kind, resolveDir, namespace, pluginData = {} } = args;
pluginData[EXTERNAL_PACKAGE_RESOLUTION] = true;

const result = await build.resolve(args.path, {
importer,
kind,
namespace,
pluginData,
resolveDir,
});

// Return result if unable to resolve or explicitly marked external (externalDependencies option)
if (!result.path || result.external) {
return result;
}

// Allow customized loaders to run against configured paths regardless of location
if (loaderFileExtensions.has(extname(result.path))) {
return result;
if (loaderFileExtensions?.has(extname(args.path))) {
return null;
}

// Mark paths from a node modules directory as external
if (/[\\/]node_modules[\\/]/.test(result.path)) {
return {
path: args.path,
external: true,
};
// Avoid considering Windows absolute paths as package paths
if (isAbsolute(args.path)) {
return null;
}

// Otherwise return original result
return result;
// Consider the path a package and external
return {
path: args.path,
external: true,
};
});
},
};
Expand Down
Loading