Skip to content

Commit bb676bd

Browse files
authored
add destructure named imports option (#278)
1 parent 20f649d commit bb676bd

10 files changed

+63
-2
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ npx react-codemod sort-comp <path>
147147

148148
[As of Babel 7.9.0](https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154-https-githubcom-babel-babel-pull-11154), when using `runtime: automatic` in `@babel/preset-react` or `@babel/plugin-transform-react-jsx`, you will not need to explicitly import React for compiling jsx. This codemod removes the redundant import statements. It also converts (`import React from 'react'`) to named imports (`import * as React from 'react'`).
149149

150+
The wizard will ask for 1 option -
151+
152+
* **Destructure named imports?**: Destructures named imports (import * as React from 'react') as well as default imports. Does not do this by default.
153+
150154
```sh
151155
npx react-codemod update-react-imports <path>
152156
```

bin/cli.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ function runTransform({ files, flags, parser, transformer, answers }) {
9999
}
100100
}
101101

102+
if (transformer === 'update-react-imports') {
103+
if (answers.destructureNamedImports) {
104+
args.push('--destructureNamedImports=true');
105+
}
106+
}
107+
102108
if (flags.jscodeshift) {
103109
args = args.concat(flags.jscodeshift);
104110
}
@@ -362,6 +368,18 @@ function run() {
362368
},
363369
message: 'Destructure props?',
364370
default: false
371+
},
372+
{
373+
type: 'confirm',
374+
name: 'destructureNamedImports',
375+
when: answers => {
376+
return (
377+
cli.input[0] === 'update-react-imports' ||
378+
answers.transformer === 'update-react-imports'
379+
);
380+
},
381+
message: 'Destructure named imports?',
382+
default: false
365383
}
366384
])
367385
.then(answers => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as React from "react";
2+
3+
React.createElement('div', {});
4+
5+
Promise.resolve(React);
6+
7+
<div>Hi</div>

transforms/__testfixtures__/update-react-imports/destructure-named-imports-react-not-removed.output.js

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import * as React from "react";
2+
import { createElement } from "react";
3+
4+
React.createElement('div', {});
5+
6+
<div>Hi</div>;

transforms/__testfixtures__/update-react-imports/destructure-named-imports-variable-used.output.js

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import * as React from "react";
2+
3+
React.useState(false);
4+
5+
<div />
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { useState } from "react";
2+
3+
useState(false);
4+
5+
<div />

transforms/__tests__/update-react-imports-test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ const tests = [
3535
'react-already-used-named-export',
3636
];
3737

38+
const destructureNamedImportTests = [
39+
'destructure-named-imports',
40+
'destructure-named-imports-variable-used',
41+
'destructure-named-imports-react-not-removed',
42+
];
43+
3844
jest.mock('../update-react-imports', () => {
3945
return Object.assign(require.requireActual('../update-react-imports'), {
4046
parser: 'flow',
@@ -77,3 +83,12 @@ describe('typescript', () => {
7783
);
7884
});
7985
});
86+
87+
destructureNamedImportTests.forEach((test) => {
88+
defineTest(
89+
__dirname,
90+
'update-react-imports',
91+
{destructureNamedImports: true},
92+
`update-react-imports/${test}`
93+
);
94+
});

transforms/update-react-imports.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = function(file, api, options) {
1010
const j = api.jscodeshift;
1111
const printOptions = options.printOptions || {};
1212
const root = j(file.source);
13+
const destructureNamedImports = options.destructureNamedImports;
1314

1415
// https://github.com/facebook/jscodeshift/blob/master/recipes/retain-first-comment.md
1516
function getFirstNode() {
@@ -96,8 +97,8 @@ module.exports = function(file, api, options) {
9697
// local: imported
9798
const reactIdentifiers = {};
9899
const reactTypeIdentifiers = {};
99-
let canDestructureReactVariable;
100-
if (isReactImportUsed && isDefaultImport) {
100+
let canDestructureReactVariable = false;
101+
if (isReactImportUsed && (isDefaultImport || destructureNamedImports)) {
101102
// Checks to see if the react variable is used itself (rather than used to access its properties)
102103
canDestructureReactVariable =
103104
root

0 commit comments

Comments
 (0)