Skip to content

Commit

Permalink
perf(@angular-devkit/build-angular): reduce babel transformation in e…
Browse files Browse the repository at this point in the history
…sbuild builder

When using the experimental esbuild-based browser application builder, babel transformation
is now only performed on a file if the file requires the specific transformations enabled
for the build. This has the benefit of removing the need to parse and process files that
will not be affected by the enabled transformations.
From initial testing, this provides a 30% build time improvement for development builds of a
newly generated application and a 10% improvement for production builds.
  • Loading branch information
clydin authored and dgp1130 committed Aug 4, 2022
1 parent 8f9cee3 commit 3e3dc69
Showing 1 changed file with 36 additions and 11 deletions.
Expand Up @@ -323,11 +323,23 @@ export function createCompilerPlugin(
};
}

const data = typescriptResult.content ?? '';
const forceAsyncTransformation = /for\s+await\s*\(|async\s+function\s*\*/.test(data);
const useInputSourcemap =
pluginOptions.sourcemap &&
(!!pluginOptions.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(args.path));

const data = typescriptResult.content ?? '';
// If no additional transformations are needed, return the TypeScript output directly
if (!forceAsyncTransformation && !pluginOptions.advancedOptimizations) {
return {
// Strip sourcemaps if they should not be used
contents: useInputSourcemap
? data
: data.replace(/^\/\/# sourceMappingURL=[^\r\n]*/gm, ''),
loader: 'js',
};
}

const babelResult = await transformAsync(data, {
filename: args.path,
inputSourceMap: (useInputSourcemap ? undefined : false) as undefined,
Expand All @@ -341,7 +353,7 @@ export function createCompilerPlugin(
[
angularApplicationPreset,
{
forceAsyncTransformation: /for\s+await\s*\(|async\s+function\s*\*/.test(data),
forceAsyncTransformation,
optimize: pluginOptions.advancedOptimizations && {},
},
],
Expand All @@ -356,6 +368,26 @@ export function createCompilerPlugin(
);

build.onLoad({ filter: /\.[cm]?js$/ }, async (args) => {
const data = await fs.readFile(args.path, 'utf-8');
const forceAsyncTransformation =
!/[\\/][_f]?esm2015[\\/]/.test(args.path) &&
/for\s+await\s*\(|async\s+function\s*\*/.test(data);
const shouldLink = await requiresLinking(args.path, data);
const useInputSourcemap =
pluginOptions.sourcemap &&
(!!pluginOptions.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(args.path));

// If no additional transformations are needed, return the TypeScript output directly
if (!forceAsyncTransformation && !pluginOptions.advancedOptimizations && !shouldLink) {
return {
// Strip sourcemaps if they should not be used
contents: useInputSourcemap
? data
: data.replace(/^\/\/# sourceMappingURL=[^\r\n]*/gm, ''),
loader: 'js',
};
}

const angularPackage = /[\\/]node_modules[\\/]@angular[\\/]/.test(args.path);

const linkerPluginCreator = (
Expand All @@ -364,11 +396,6 @@ export function createCompilerPlugin(
)
).createEs2015LinkerPlugin;

const useInputSourcemap =
pluginOptions.sourcemap &&
(!!pluginOptions.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(args.path));

const data = await fs.readFile(args.path, 'utf-8');
const result = await transformAsync(data, {
filename: args.path,
inputSourceMap: (useInputSourcemap ? undefined : false) as undefined,
Expand All @@ -383,13 +410,11 @@ export function createCompilerPlugin(
angularApplicationPreset,
{
angularLinker: {
shouldLink: await requiresLinking(args.path, data),
shouldLink,
jitMode: false,
linkerPluginCreator,
},
forceAsyncTransformation:
!/[\\/][_f]?esm2015[\\/]/.test(args.path) &&
/for\s+await\s*\(|async\s+function\s*\*/.test(data),
forceAsyncTransformation,
optimize: pluginOptions.advancedOptimizations && {
looseEnums: angularPackage,
pureTopLevel: angularPackage,
Expand Down

0 comments on commit 3e3dc69

Please sign in to comment.