-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
Use named imports for babel types #13685
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/48210/ |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit d9c6681:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 codemod approach makes the most sense and separating out follow up PRs, nice work!
I'm curious: is the slowdown due to the "emulation" of ES exports via getters? If that's the case, perhaps the issue could be alleviated at the source, i.e. in Here's an idea: lightmare@5842734 |
That makes sense to me.
Changing the exported values may break use cases such to manipulate the |
Not sure what you mean. Exports defined with
Although that wasn't my intent, changing the exports to plain assignment (hence |
This PR is a follow-up to #13593 (review). In this PR we transform
@babel/types
namespace imports (e.g.import * as t from "@babel/types"
to named imports (e.g.import { isIdentifier } from "@babel/types"
). The named imports allow us to perform further optimization when transforming to commonjs modules.Example
For example, before this PR, the named imports
are transformed as
After this PR, the named imports are transformed as
In #13593 we have identified a bottleneck of generator performance, accessing methods from
@babel/types
namespace is very slow. The optimized output now accesses namespace only once (per module).Note that we can not generalize the optimization to any imports because ES imports are live bindings, which means if a module changed its exports on-the-fly, the updated values will be synchronized to the consumers. However, in the transpiled code, we takes a snapshot of these imports once and they won't be updated since then.
This approach is safe for most
@babel/types
usage in our current codebase since we don't modify the types exports, except inbabel-traverse/src/path/index.ts
where@babel/traverse
is modifying the exports of@babel/types
. Such usage is rare and we should consider if we should move on to a new approach.The first commit is produced by a custom codemod.
Comparison to plugin-only approach
My first draft is a plugin transforming namespace
import * as t
to destructuring. Compared to current approach, the first approach has the following constraints:const addComment = t.addComment
becomes invalid after built, though we could avoid naming conflicts by sacrificing code readability.Limitations
This PR does not change the indirect
@babel/types
usage such as@babel/types
from@babel/core
@babel/types
from the callback parameters of a pluginI think they should be updated, too. I will address them in separate PRs.
Further thoughts
Should we come up with a parameterized (🤷) assumption for commonjs transform?