This tool is awesome! We've run into one minor issue on our end and actually have a monkeypatch to fix it.
Given this example:
var fetch = require('fetch');
var Routes = {
route1: {
component: require('Foo')
},
route2: {
component: require('Bar')
},
route3: {
component: require('Baz')
},
route4: {
component: require('Foo')
},
};
module.exports = Routes;
jscodeshift -t $GLOBAL_NODE_MODULES/5to6-codemod/transforms/cjs.js codeModExample.js --extensions=js
will return:
import fetch from 'fetch';
import component from 'Foo';
import component from 'Bar';
import component from 'Baz';
import component from 'Foo';
var Routes = {
route1: {
component
},
route2: {
component
},
route3: {
component
},
route4: {
component
}
};
module.exports = Routes;
Ideally, we would prefer if this resulted in this output:
import fetch from 'fetch';
import Foo from 'Foo';
import Bar from 'Bar';
import Baz from 'Baz';
var Routes = {
route1: {
component: Foo
},
route2: {
component: Bar
},
route3: {
component: Baz
},
route4: {
component: Foo
}
};
module.exports = Routes;
the "fix"
diff --git a/transforms/cjs.js b/transforms/cjs.js
index ab9e41d..406ad3d 100644
--- a/transforms/cjs.js
+++ b/transforms/cjs.js
@@ -73,6 +73,7 @@ module.exports = function transformer(file, api, options) {
}).forEach(replaceDeclarator.bind(undefined, j));
});
+ var moduleNames = {};
// var x = { x: require('...'), y: require('...'), ... }
root.find(j.VariableDeclaration, { declarations: [{ init: { type: 'ObjectExpression' }}] })
.forEach(function (variableDeclaration) {
@@ -83,13 +84,21 @@ module.exports = function transformer(file, api, options) {
.find(j.Property, { value: { callee: { name: 'require' }}})
.forEach(function (property) {
// generate import statement
- var variableName = property.get('key', 'name').value
+ // var variableName = property.get('key', 'name').value
var moduleName = property.get('value', 'arguments', 0, 'value').value
+ var variableName = moduleName.slice(moduleName.lastIndexOf('/')+1, moduleName.length);
var importStatement = util.createImportStatement(moduleName, variableName, undefined, property.node.comments)
-
// modify property
var newProp = api.jscodeshift.property(property.node.kind, property.node.key, property.node.key)
- newProp.shorthand = true
+ newProp.value = variableName;
+
+ if (moduleNames[variableName]) {
+ j(property).replaceWith(newProp);
+ return
+ } else {
+ moduleNames[variableName] = true;
+ }
j(variableDeclaration).insertBefore(importStatement)
j(property).replaceWith(newProp)
I would love to get opinions on this, and can open a PR if it's useful to others.
I don't think my monkey-patch should go down as is, it needs cleanup (I'm looking at you, return
in the if).
There will be an issue if there's duplication of Module names in subdirectories, such as app/components/Header
and app/components/redesign/Header
. This change already stores moduleName and attempts to de-dupe, so the concept could be expanded upon to recursively add the subdirectory name to the moduleName if a module already exists.
We could actually go deeper, and do (only in case of namespace conflicts):
import Header from 'app/components/Header';
import RedesignHeader from 'app/components/redesign/Header';