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:
|
hzoo
left a comment
There was a problem hiding this comment.
👍 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/typesnamespace 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/typesnamespace 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/typesusage in our current codebase since we don't modify the types exports, except inbabel-traverse/src/path/index.tswhere@babel/traverseis 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 tto destructuring. Compared to current approach, the first approach has the following constraints:const addComment = t.addCommentbecomes invalid after built, though we could avoid naming conflicts by sacrificing code readability.Limitations
This PR does not change the indirect
@babel/typesusage such as@babel/typesfrom@babel/core@babel/typesfrom 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?