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

[Feature Request] Support building for both UMD/ESM #21899

Open
fs-eire opened this issue May 7, 2024 · 4 comments
Open

[Feature Request] Support building for both UMD/ESM #21899

fs-eire opened this issue May 7, 2024 · 4 comments

Comments

@fs-eire
Copy link
Contributor

fs-eire commented May 7, 2024

When building wasm, I have to choose one between UMD and ESM for the generated JavaScript file, by either specifying the extension (.js vs .mjs) or using -sEXPORT_ES6=1. I want to build both of them but seems no way to do that.

Building it twice is not a working workaround because some number in the generated ASM_CONSTS table is different in 2 builds and the generated 2 JS files cannot use with one .wasm file.

@sbc100
Copy link
Collaborator

sbc100 commented May 7, 2024

How hard do you think it would be to make a module that works in both of these environments? Is it worth adding yet anther setting or should we just try to make the ES6 output UMD compatible?

Out of interest what is the platform you are targeting that requires UMD compat?

@fs-eire
Copy link
Contributor Author

fs-eire commented May 7, 2024

How hard do you think it would be to make a module that works in both of these environments? Is it worth adding yet anther setting or should we just try to make the ES6 output UMD compatible?

Out of interest what is the platform you are targeting that requires UMD compat?

I don't think the idea that one module supporting both UMD and ESM can work, because reference to import (eg. import.meta.url) will cause an syntax error if not in ESM.

The reason why I want to distribute a UMD bundle is because of bundler compatibility. There are 2 reasons:

  • A ESM module can import a CJS module and bundler can do this correctly; but it is very hard to import ESM in a CJS module.
  • Currently some bundlers (Webpack, parcel, ..) will rewrite import.meta.url into static strings like "file:///path/to/build/time/file.js". This will make the Emscripten generated code not working.

As a library author, the best option for me is to offer 2 exports - one for UMD and one for ESM. This is why I created this issue.

@fs-eire
Copy link
Contributor Author

fs-eire commented May 7, 2024

BTW it would be great if Emscripten can support generate multiple targets at one build (not only UMD/ESM). In my use case, I acutally need 4 targets:

  • output.js (umd, ENVIRONMENT=web,webview,worker)
  • output.mjs (esm, ENVIRONMENT=web,webview,worker)
  • output.node.js (umd, ENVIRONMENT=node)
  • output.node.mjs (esm, ENVIRONMENT=node)

I am currently using Regex to replace the code snippet in generated files in order to exclude Node.js outputs for web. This is very hacky and unstable because with the upgrade of emscripten the old regex may no longer work.

You may be interested in why I don't use default. Because default supports both web and node, right? The reason is the bundler again:

  • Bundler is not happy with await import("module") even it is guarded by condition isNode.
  • Tree shaking is not working with the variable of IS_ENVIRONMENT_NODE

@fs-eire
Copy link
Contributor Author

fs-eire commented May 7, 2024

I would share a viewpoint from a library developer: some requirement above is not a problem of Emscripten, they are more like the problem of bundler. However, we cannot control or predict how users use bundler. If bundler has a bug or an unexpected behavior, we can track the bugfix but at the same time we need to workaround to offer user the out-of-box experience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants