Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ide
Forked from jeffpeterson/requiresToImports.js
Last active November 12, 2019 23:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save ide/f3266c3915b0e45dac78 to your computer and use it in GitHub Desktop.
Save ide/f3266c3915b0e45dac78 to your computer and use it in GitHub Desktop.
Converts commonJS requires to es6 imports
// converts commonJS requires to es6 imports
// var foo = require('foo');
// ->
// import foo from 'foo';
//
// jscodeshift -t requiresToImports.js src/**/*.js*
'use strict';
module.exports = function(fileInfo, api) {
var j = api.jscodeshift;
return j(fileInfo.source)
.find(j.VariableDeclaration, {
declarations: [{
type: 'VariableDeclarator',
init: {
type: 'CallExpression',
callee: {
type: 'Identifier',
name: 'require',
},
},
}],
})
.filter(isTopLevel)
.forEach(function(path) {
const dec = path.value.declarations[0];
const id = dec.id;
const source = dec.init.arguments[0];
const comments = path.value.comments;
const loc = path.value.loc;
path.replace(j.importDeclaration([{type: 'ImportDefaultSpecifier', id}], source));
path.value.loc = loc;
path.value.comments = comments;
})
.toSource();
};
function isTopLevel(path) {
return !path.parentPath.parentPath.parentPath.parentPath;
}
@ide
Copy link
Author

ide commented Sep 3, 2015

Note: this eats up some class decorators as of the time of this posting.

@calvinf
Copy link

calvinf commented Nov 17, 2015

Super useful -- it would be nice to have this in cpojer/js-codemod when it's ready.

@zgotsch
Copy link

zgotsch commented Dec 7, 2015

Hi ide, I made some small changes to the script to preserve comments and spacing:

// converts commonJS requires to es6 imports                                                                                                 
//   var foo = require('foo');                                                                                                               
// ->                                                                                                                                        
//   import foo from 'foo';                                                                                                                  
//                                                                                                                                           
// jscodeshift -t requiresToImports.js src/**/*.js*                                                                                          
'use strict';

module.exports = function(fileInfo, api) {
  var j = api.jscodeshift;

  return j(fileInfo.source)
    .find(j.VariableDeclaration, {
      declarations: [{
        type: 'VariableDeclarator',
        init: {
          type: 'CallExpression',
          callee: {
            type: 'Identifier',
            name: 'require',
          },
        },
      }],
    })
    .filter(isTopLevel)
    .forEach(function(path) {
      const dec = path.value.declarations[0];
      const id = dec.id;
      const source = dec.init.arguments[0];
      const comments = path.value.comments;
      const loc = path.value.loc;

      path.replace(j.importDeclaration([{type: 'ImportDefaultSpecifier', id}], source));
      path.value.loc = loc;
      path.value.comments = comments;
    })
    .toSource();
};

function isTopLevel(path) {
  return !path.parentPath.parentPath.parentPath.parentPath;
}

We should see about contributing this to cpojer/js-codemod if we can sort out the decorator issue.

@ide
Copy link
Author

ide commented Dec 12, 2015

@zgotsch thank you! I will update this gist with your version :D

@dmnd
Copy link

dmnd commented Dec 16, 2015

I edited this to transform

var baz = require('foo').bar

into

import {bar as baz} from 'foo';

Here's the updated version:

// converts commonJS requires to es6 imports
//   var foo = require('foo');
// ->
//   import foo from 'foo';
//
// jscodeshift -t requiresToImports.js src/**/*.js*
'use strict';

module.exports = function(fileInfo, api) {
  var j = api.jscodeshift;
  var root = j(fileInfo.source);

  root
    .find(j.VariableDeclaration, {
      declarations: [{
        type: 'VariableDeclarator',
        init: {
          type: 'CallExpression',
          callee: {
            type: 'Identifier',
            name: 'require',
          },
        },
      }],
    })
    .filter(isTopLevel)
    .forEach(function(path) {
      const dec = path.value.declarations[0];
      const id = dec.id;
      const source = dec.init.arguments[0];
      const comments = path.value.comments;
      const loc = path.value.loc;

      path.replace(
        j.importDeclaration(
          [{
            type: 'ImportDefaultSpecifier',
            id
          }],
          source
        )
      );
      path.value.loc = loc;
      path.value.comments = comments;
    });

  root
    .find(j.VariableDeclaration, {
      declarations: [{
        type: 'VariableDeclarator',
        init: {
          type: 'MemberExpression',
          object: {
            type: 'CallExpression',
            callee: {
              type: 'Identifier',
              name: 'require'
            },
          },
        },
      }],
    })
    .filter(isTopLevel)
    .forEach(function(path) {
      const dec = path.value.declarations[0];
      const name = dec.id;
      const source = dec.init.object.arguments[0];
      const id = dec.init.property;
      const comments = path.value.comments;
      const loc = path.value.loc;

      let spec = {
        type: 'ImportSpecifier',
        id,
      }
      if (name.name !== id.name) {
        spec['name'] = name;
      }

      path.replace(j.importDeclaration([spec], source));
      path.value.loc = loc;
      path.value.comments = comments;
    });

  return root.toSource();
};

function isTopLevel(path) {
  return !path.parentPath.parentPath.parentPath.parentPath;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment