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

@angular-devkit/build-angular always includes "@babel/plugin-transform-async-to-generator" and "@babel/plugin-proposal-async-generator-functions" #25708

Closed
1 task
Simon-Hayden-iteratec opened this issue Aug 24, 2023 · 7 comments

Comments

@Simon-Hayden-iteratec
Copy link

Simon-Hayden-iteratec commented Aug 24, 2023

Command

build

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

When I'm building an Angular project for modern browsers, I expect modern features like async/await to be used. However, when building the project, Angular uses Babel to replace async/await with calls to a helper function, which uses generator functions instead.

This means, that there is a slight overhead in performance, as well as bundle size to accommodate for the polyfill. Most annoyingly (to me at least) is that debugging can be tough, because I can't properly "step into" an async function call, without landing in Babel's helper function. Which makes understanding the code much harder.

Proposed changes

I think either the behaviour should be well documented (e.g. on the browser support site), or changed/customizable. Most browsers support async and await, so in my opinion the default should also include those features.

Minimal Reproduction

I have created a demo repo for this issue: https://github.com/Simon-Hayden-iteratec/async-await-missing

There is a readme explaining the behaviour and how to reproduce it.

But the gist of it:

  • Run ng build --optimization=false --output-hashing=none targeting only modern browsers
  • At the bottom of the built dist/<app-name>/main.js find the function _asyncToGenerator from Babel. The file will also not include an asyncs or awaits.

I investigated where this code is coming from, and I assume these lines are the cause:

      // Application code (TS files) will only contain native async if target is ES2017+.
      // However, third-party libraries can regardless of the target option.
      // APF packages with code in [f]esm2015 directories is downlevelled to ES2015 and
      // will not have native async.
      customOptions.forceAsyncTransformation =
        !/[\\/][_f]?esm2015[\\/]/.test(this.resourcePath) && source.includes('async');

It appears to be true for all source files. I assume the line was only intended to be true for Angular library builds (or similar).

When I edit the file in my local node_modules to be always false, I see a small, but measurable reduction in bundle size (measured with du -bc "dist/async-await-missing" in the linked Git repo):

Without Patch (Bit count) With Patch (Bit count) Diff
Unoptimized 2 358 530 2 354 366 -4 164
Optimized 276 531 274 741 -1 790

However, the difference is larger, for larger projects (tested in a company-private repo).

Exception or Error

There is no error message or similar.

Your Environment

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 16.2.0
Node: 16.20.1
Package Manager: npm 8.19.4
OS: linux x64

Angular: 16.2.2
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1602.0
@angular-devkit/build-angular   16.2.0
@angular-devkit/core            16.2.0
@angular-devkit/schematics      16.2.0
@angular/cli                    16.2.0
@schematics/angular             16.2.0
rxjs                            7.8.1
typescript                      5.1.6
zone.js                         0.13.1

Anything else relevant?

No response

@JeanMeche
Copy link
Member

JeanMeche commented Aug 24, 2023

Hi,

Those plugins are required because zone.js isn't compatible with native async/await.

@JeanMeche JeanMeche closed this as not planned Won't fix, can't repro, duplicate, stale Aug 24, 2023
@Simon-Hayden-iteratec
Copy link
Author

Hi, thanks for the quick response.

Could this then be documented or mentioned somewhere? I tried to google this issue for quite some time, but never found anything pointing towards zone.js being the culprit.

@JeanMeche
Copy link
Member

You're right, the only place where it's stated is here:

if (options.forceAsyncTransformation) {
// Always transform async/await to support Zone.js
plugins.push(
require('@babel/plugin-transform-async-to-generator').default,
require('@babel/plugin-proposal-async-generator-functions').default,
);
needRuntimeTransform = true;
}

@Simon-Hayden-iteratec
Copy link
Author

Now that you mention it, I've even seen this line of code, but because it is inside an if, I assumed some config was not set properly. Shouldn't the if + ApplicationPresetOptions#forceAsyncTransformation then be gone entirely? I also heard that there is a zone-less Angular initiative with the new signals feature. So I guess this should at least be optional for those use-cases, right?

I'm just throwing questions at this point, but I'm curious, sorry 😄

@JeanMeche
Copy link
Member

The forceAsyncTransformation option is set by the CLI itself if it finds an async function in a file.

The goal of signals is indeed to allow zoneless apps but we're not there yet (we still need the signal components etc.).

But I agree, zoneless apps already exist and could benefit from having that kind of options. I'll reopen to get an "offcial" response from the maintainers. 👍🏻

@JeanMeche JeanMeche reopened this Aug 24, 2023
@alan-agius4
Copy link
Collaborator

Duplicate of #22191

@alan-agius4 alan-agius4 marked this as a duplicate of #22191 Aug 24, 2023
@alan-agius4 alan-agius4 closed this as not planned Won't fix, can't repro, duplicate, stale Aug 24, 2023
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants