WIP: Addition of custom collection functions for importDeclarations/Specifiers
Adds utility methods for import specifiers (similar to the ones provided for JSXElements).
Why?
Import manipulation is probably the most common operation you will do in a codemod, but there are quite a few edge cases to consider when doing so.
For example,
- Insert imports / specifiers without duplication
- Renaming import paths
- Checking for imports (good for early exit conditions)
GLOBALS
insertImportDeclaration
insertImportSpecifiers
findImportDeclarations
findImportSpecifier
findDefaultSpecifier
hasImportSpecifier
hasDefaultImportSpecifier
FILTERS
TBD
The latest updates on your projects. Learn more about Vercel for Git ↗︎
| Name | Status | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| jscodeshift | ✅ Ready (Inspect) | Visit Preview | 💬 Add feedback | Jul 24, 2024 8:22am |
This is really useful! I've written code like this so many times. Nice work.
Can this handle Flow/TypeScript type imports too?
Thanks @Daniel15!
I've also written code like this a lot 😂 and I find it's normally the first util people make, but given the way jscodeshift's API is designed (via dependency injection, rather than typical imports) it can be quite cumbersome to import and use utils unless you have access to the register method.
I have a util library here, which I've based most of this work on, and as you can probably guess the API is less than ideal because it's forcing me to pass the core API and AST into every method: https://github.com/hypermod-io/hypermod-community/blob/main/packages/utils/src/imports.ts
I'll add some test cases for flow/typescript, but it should work because these utils operate on the ImportSpecifier which TS/Flow type imports are represented by AFAIK.
I'm going to merge this as-is. We can add tests for type imports as a followup.
Flow uses a slightly different format for type imports, which we should test too:
import type {Foo} from 'whatever';
Thanks @Daniel15 I'll come back to this asap. I have more ready to push up :)
@mohab-sameh would be good to have these documented on the new site if you have time for it!
@danieldelcore sure thing! thanks for notifying me.
I'll push a new version of jscodeshift this week, depending on when you're planning on submitting more PRs this week.
@danieldelcore Can you please look at the test failure? Not sure why it didn't appear on this diff.
Did I merge this too early? We should ensure that PRs that aren't ready to merge are labelled as set as "drafts"
Edit: Sorry I messed this up a bit :) Please submit a new PR in draft status.
Run yarn test
yarn run v1.22.22
$ jest --bail
PASS src/collections/__tests__/Node-test.js
PASS src/__tests__/Collection-test.js
PASS src/__tests__/argsParser-test.js
FAIL src/__tests__/template-test.js
● Templates › interpolates expression nodes with source code
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › interpolates statement nodes with source code
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › can be used with a different parser
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › handles out-of-order traversal
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › correctly parses expressions without any interpolation
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › asyncExpression correctly parses expressions with await -- babel
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › explode arrays › explodes arrays in function definitions
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › explode arrays › explodes arrays in variable declarations
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › explode arrays › explodes arrays in array expressions
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › explode arrays › explodes arrays in object expressions
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
● Templates › explode arrays › explodes arrays in call expressions
ReferenceError: filterMethods is not defined
112 |
113 | exports.register = once(register);
> 114 | exports.filters = filterMethods;
| ^
115 |
at Object.filterMethods (src/collections/ImportDeclaration.js:114:19)
at Object.require (src/collections/index.js:13:22)
at Object.require (src/core.js:12:21)
at Object.require (src/__tests__/template-test.js:23:19)
Test Suites: 1 failed, 3 passed, 4 of 16 total
Tests: 15 failed, 80 passed, 95 total
Snapshots: 0 total
Time: 4.19 s
Ran all test suites.
error Command failed with exit code 1.
Oh, no worries; yeah, it was a bit early, but I'm happy to reopen :).