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 should *not* disable Webpack's import.meta.url parsing (for WebAssembly files, at least) #24617

Closed
1 task
dhdaines opened this issue Jan 27, 2023 · 6 comments

Comments

@dhdaines
Copy link

dhdaines commented Jan 27, 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

Actually, Angular should just make up its h*cking mind (see #24616).

Currently, its mysterious and ephemeral built-in webpack configuration disables module.parser.javascript.url, so assets imported with new URL(..., import.meta.url) do not get packaged by default.

Okay, that's fine, if you're into that kind of thing, but at the same time it keeps module.parser.java.importmeta enabled, leading webpack to output entirely useless file:// URLs instead of doing any packaging.

End result is that you just can't use any ES6 module (such as anything compiled with Emscripten's EXPORT_ES6 option) that tries to load some possibly really important asset, like, say, a WebAssembly file. You are damned if you do and damned if you don't! If you do what is suggested in #22351 and try to use the assets option, the actually generated code will not reference this asset because import.meta.url got rewritten to some path on your build filesystem.

But if you then disable module.parser.java.importmeta manually in a custom webpack config, then you end up with import.meta.url in the output code, which utterly breaks testing with karma (since karma does not do ES6 modules, because that's like not groovy, man) and of course also any possibility of targeting a non-ES6-aware browser.

This is the opposite of webpack's perfectly good and sane defaults. A reasonable workaround is to create a custom webpack config which enables module.parser.java.url, like this:

module.exports = {
  module: {
    parser: {
      javascript: {
        url: true,
      },
    },
  },
};

Minimal Reproduction

From an Angular app, try to load an ES6 module (like https://www.npmjs.com/package/soundswallower?activeTab=explore) that has an accompanying WASM file, or any kind of asset that is loaded with new URL(..., import.meta.url). The relevant code output by Emscripten is:

 wasmBinaryFile = new URL("soundswallower.web.wasm", import.meta.url).href;

Exception or Error

No response

Your Environment

Angular CLI: 15.1.2
Node: 18.12.1
Package Manager: npm 9.1.3
OS: linux x64

Angular: 15.1.1
... animations, cdk, common, compiler, compiler-cli, core, forms
... localize, material, platform-browser
... platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1501.2
@angular-devkit/build-angular   15.1.2
@angular-devkit/core            15.1.2
@angular-devkit/schematics      15.1.2
@angular/cli                    15.1.2
@schematics/angular             15.1.2
rxjs                            7.5.7
typescript                      4.8.4
webpack                         5.75.0

Anything else relevant?

No response

@alan-agius4
Copy link
Collaborator

alan-agius4 commented Jan 27, 2023

Karma ES6 support
Karma supports ES6 as long as the browser supports. The problem you are experiencing appears to be a bug on our end which will be addressed via #24620

module.parser.javascript.importMeta
Setting this option to false breaks other features such as support for web-workers. Unfortunately Webpack is unable to parse these when this is option is disabled. This still seems to be a problem in Webpack that you cannot use import.meta without compromising / breaking other features.

module.parser.javascript.url
We discussed this a couple of month ago. Ultimately, the team decided that we should not keep this enabled as users would this Webpack specific features (asset modules) and make it harder for them to eventually transition away especially since in many cases this was used as a way to fingerprint resources


The Angular CLI also offers the possibility to use an Esbuild instead of a Webpack based builder which supports ESM fully. This is still experimental and only support ng build. See: https://blog.angular.io/angular-v15-is-now-available-df7be7f2f4c8

If you wish to enable/disable one of these above mentioned Webpack specific features, a custom Webpack configuration would be mandatory.

@dhdaines
Copy link
Author

Thank you for the really detailed response! This problem basically ate my entire day, so I really appreciate the explanation.

But in particular if using esbuild will solve the problem, I will gladly use esbuild, and suffer the 60% speedup in compile time.

If a custom webpack config is what's necessary, and esbuild is the future anyway, then this is an acceptable solution.

@dhdaines
Copy link
Author

Another suggestion - since (if I'm not mistaken) Angular does allow webpack to bundle workers accessed via import.meta.url, it would be a good idea to extend this special case to WASM files, since they are not really "assets" but actually integral parts of the applicadtion's code.

@dhdaines dhdaines changed the title Angular should *not* disable Webpack's import.meta.url parsing by default Angular should *not* disable Webpack's import.meta.url parsing (for WebAssembly files, at least) Jan 27, 2023
@alan-agius4
Copy link
Collaborator

While Webpack can bundle web workers when using import.meta.url even though url parsing is disabled. It does not offer the same possibility for WASM files.

@alan-agius4
Copy link
Collaborator

Closing as per above.

@alan-agius4 alan-agius4 closed this as not planned Won't fix, can't repro, duplicate, stale Feb 3, 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 Mar 6, 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

2 participants