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
Publish as modules (instead of compiling to cjs) #11701
Comments
I'm working on this, but it won't happen sooner than Babel 8. |
@nicolo-ribaudo Have you already started doing the changes or is this still up for grab ? |
@ak06121991 Well, there’s #12632, which does this for the |
@ak06121991 I'd prefer to work myself on this issue because it deeply affects our build, release and testing process. |
UpdateWe are thinking about releasing Babel 8 as an ESM-only package, for the following reasons:
We currently got feedback from @devongovett that Parcel runs Babel in a Node.js (*) The |
(Parcel currently patches |
As a related topic, has babel considered bundling its internal dependencies? For example,
|
Yes! We already do that for some packages, but not for all of them due to backward compatibility. From the performance side, we even had to introduce a "lazy requires" option in the cjs transform for ourselves, otherwise requiring PS. For the "people cannot access your internal files", that's what |
That's an interesting point about lazy requires. I guess that's not possible with ESM, unless everything is made async. But perhaps bundling would help alleviate it anyway. |
@nicolo-ribaudo what does this mean for the future of |
I'm still exploring solutions, but in the worst case when using import("@babel/register").then(() => require("./entrypoint.js")); instead of require("@babel/register");
require("./entrypoint.js") I'm also exploring moving |
@nicolo-ribaudo thanks for your reply. The situation I'm working with is more of: export NODE_OPTIONS='--require=@babel/register'
node test.js The way nyc works is to injects a |
Thanks for reminding me about that use case. FYI, I'm experimenting with compiling in workers at https://github.com/nicolo-ribaudo/babel-synchronized. For |
@coreyfarrell I drafted a solution at #12814. We could re-use it also for |
@nicolo-ribaudo A few random questions picking up on your previous comments:
By the way, 1st question isn't a gripe, I'm just interested. Personally I think going ESM is all good, especially if there's something like babel-synchronized as a fallback for people stuck in require-land, and it's not terribly slow. |
Yes it is very slow. Parcel has a lot of experience with this. We found it slower in some cases than generating code + source map and re-parsing. 😬 |
This comment is probably no longer accurate, given that ES Modules will be the default, and CommonJS will be the exception: Lines 30 to 32 in 792672e
As such, it should be the CommonJS files that get renamed to use the |
@devongovett Thanks for the info. Disappointing. Was that using JSON as serialization format? I wonder if an alternative (streaming?) serialization format would make any difference? And, when passing back and forth code only (not ASTs), are you saying that the performance isn't so bad? |
It will be impossible to both import synchronously and This will be possible: const babel = await import("@babel/core");
const { code } = babel.transformSync("foo;"); However, if
i.e. this won't work because const babel = await import("@babel/core");
const { code } = babel.transformSync("foo;", {
presets: ["@babel/preset-env"]
}); but you'll have to do this: const babel = await import("@babel/core");
const env = await import("@babel/preset-env");
const { code } = babel.transformSync("foo;", {
presets: [env]
}); Note that I said "it will be impossible to import and transform synchronously" and not just "it will be impossible to import synchronously" because we could easily expose a CJS entry point that only contains the
There is a draft PR to move ESM loaders to a worker: nodejs/node#31229.
Yes, it affects performance a lot. Using Babel in a worker is only an escape hatch for when it's not possible to do otherwise. For example, when compiling this file three times with
Note that you do not need to manually serialize+deserialize ASTs (for example using JSON), because workers use the Structured Clone algorithm to pass data back and forth. @ExE-Boss I'm opening different PRs to gradually migrate; that one is one of my next steps! |
That should be using const {
0: babel,
1: env,
} = await Promise.all([
import("@babel/core"),
import("@babel/preset-env"),
]);
const { code } = babel.transformSync("foo;", {
presets: [env],
}); |
Sorry for slow reply. One question: If you go ESM, how will you replace the "lazy requires" optimization? You'd need to either (1) abandon the laziness and switch to static Or does the non-blocking/parallel nature of the ESM loader remove the performance problem which the lazy requires were introduced to fix in the first place? |
If startup performance will be a problem again, we can:
|
Feature Request
Is your feature request related to a problem?
Would like to be able to consume babel packages directly as modules (as they are written), instead of just cjs. (In my case, may want to import Babel itself into something like snowpack/vite which tries to only support esm). This would be for anything trying to use babel for tooling like the repl/etc so not a common usecase.
Also good that we dogfood what other packages/libraries are doing, even though we aren't really a tool for the browser it would be good to attempt to understand the issues with doing all this anyway.
Describe the solution you'd like
Use package exports. When building we change our config to do
modules: false
in preset-env. Currently we do"main": "lib/index.js",
for most packages.Could output a whole folder like
dist
ormodule
instead oflib
or output.mjs
in the samelib
folder.Describe alternatives you've considered.
Don't think there's an alternative other than consuming the source via github which is difficult because this is a monorepo. We only publish cjs.
The text was updated successfully, but these errors were encountered: