diff --git a/test/fixtures/cjs/called.after.js b/test/fixtures/cjs/called.after.js new file mode 100644 index 0000000..f281a2e --- /dev/null +++ b/test/fixtures/cjs/called.after.js @@ -0,0 +1,18 @@ +// stacked comment +import aFactory from 'var-stacked-comment'; + +const a = aFactory(); +import bFactory from 'var-no-comment'; +const b = bFactory('arg for b'); +import cFactory from 'var-inline-comment'; // with inline comment +const c = cFactory({ some: 'arg' }); +import deFactory from 'var-decomposition'; +const { d, e } = deFactory(); +import jFactory from 'multi-var-j'; +const j = jFactory(); +import hFactory from 'multi-var-h'; +const h = hFactory(); +import gFactory from 'multi-var-g'; +const g = gFactory(); + +var f = 'x', unassigned, i = 'bar'; diff --git a/test/fixtures/cjs/called.before.js b/test/fixtures/cjs/called.before.js new file mode 100644 index 0000000..6604ec3 --- /dev/null +++ b/test/fixtures/cjs/called.before.js @@ -0,0 +1,13 @@ +// stacked comment +var a = require('var-stacked-comment')(); +var b = require('var-no-comment')('arg for b'); +var c = require('var-inline-comment')({ some: 'arg' }); // with inline comment + +var { d, e } = require('var-decomposition')(); + +var f = 'x', + g = require('multi-var-g')(), + h = require('multi-var-h')(), + unassigned, + i = 'bar', + j = require('multi-var-j')(); diff --git a/test/fixtures/cjs-declaration.after.js b/test/fixtures/cjs/declaration.after.js similarity index 100% rename from test/fixtures/cjs-declaration.after.js rename to test/fixtures/cjs/declaration.after.js diff --git a/test/fixtures/cjs-declaration.before.js b/test/fixtures/cjs/declaration.before.js similarity index 100% rename from test/fixtures/cjs-declaration.before.js rename to test/fixtures/cjs/declaration.before.js diff --git a/test/fixtures/cjs-ignore.after.js b/test/fixtures/cjs/ignore.after.js similarity index 100% rename from test/fixtures/cjs-ignore.after.js rename to test/fixtures/cjs/ignore.after.js diff --git a/test/fixtures/cjs-ignore.before.js b/test/fixtures/cjs/ignore.before.js similarity index 100% rename from test/fixtures/cjs-ignore.before.js rename to test/fixtures/cjs/ignore.before.js diff --git a/test/fixtures/cjs-mapper.after.js b/test/fixtures/cjs/mapper.after.js similarity index 100% rename from test/fixtures/cjs-mapper.after.js rename to test/fixtures/cjs/mapper.after.js diff --git a/test/fixtures/cjs-mapper.before.js b/test/fixtures/cjs/mapper.before.js similarity index 100% rename from test/fixtures/cjs-mapper.before.js rename to test/fixtures/cjs/mapper.before.js diff --git a/test/fixtures/cjs-object.after.js b/test/fixtures/cjs/object.after.js similarity index 100% rename from test/fixtures/cjs-object.after.js rename to test/fixtures/cjs/object.after.js diff --git a/test/fixtures/cjs-object.before.js b/test/fixtures/cjs/object.before.js similarity index 100% rename from test/fixtures/cjs-object.before.js rename to test/fixtures/cjs/object.before.js diff --git a/test/fixtures/cjs-standalone.after.js b/test/fixtures/cjs/standalone.after.js similarity index 100% rename from test/fixtures/cjs-standalone.after.js rename to test/fixtures/cjs/standalone.after.js diff --git a/test/fixtures/cjs-standalone.before.js b/test/fixtures/cjs/standalone.before.js similarity index 100% rename from test/fixtures/cjs-standalone.before.js rename to test/fixtures/cjs/standalone.before.js diff --git a/test/transforms/cjs.js b/test/transforms/cjs.js index d05d91e..5f6faf1 100644 --- a/test/transforms/cjs.js +++ b/test/transforms/cjs.js @@ -18,16 +18,17 @@ var cjsTransform = require('../../transforms/cjs'); * */ describe('CJS transform', function() { - it('require("x")', helper.bind(this, 'cjs-standalone')) - it('var ... = require("x")', helper.bind(this, 'cjs-declaration')) - it('var ... = require("y").x', helper.bind(this, 'cjs-object')) - it('var x = { x: require("x"), y: require("y"), ... }', helper.bind(this, 'cjs-mapper')) - it('should ignore requires deepr than top-level', helper.bind(this, 'cjs-ignore')) + it('require("x")', helper.bind(this, 'standalone')) + it('var ... = require("x")', helper.bind(this, 'declaration')) + it('var ... = require("y").x', helper.bind(this, 'object')) + it('var ... = require("y")( ... )', helper.bind(this, 'called')) + it('var x = { x: require("x"), y: require("y"), ... }', helper.bind(this, 'mapper')) + it('should ignore requires deepr than top-level', helper.bind(this, 'ignore')) }); function helper (name) { - var src = fs.readFileSync(path.resolve(__dirname, '../fixtures/' + name + '.before.js')).toString(); - var expectedSrc = fs.readFileSync(path.resolve(__dirname, '../fixtures/' + name + '.after.js')).toString(); + var src = fs.readFileSync(path.resolve(__dirname, '../fixtures/cjs/' + name + '.before.js')).toString(); + var expectedSrc = fs.readFileSync(path.resolve(__dirname, '../fixtures/cjs/' + name + '.after.js')).toString(); var result = cjsTransform({ source: src }, { jscodeshift: jscodeshift }); - assert.equal(result.trim(), expectedSrc.trim()); + assert.equal(result, expectedSrc); } diff --git a/transforms/cjs.js b/transforms/cjs.js index 4186b92..dbb4e32 100644 --- a/transforms/cjs.js +++ b/transforms/cjs.js @@ -46,6 +46,21 @@ module.exports = function transformer(file, api, options) { }) }) + // var x = require("y")( ... ) + root.find(j.VariableDeclarator, { + init: { + type: 'CallExpression', + callee: { + callee: { + name: 'require' + } + } + } + }).filter(function(vdRef) { + var callExpression = vdRef.value.init; + return 'arguments' in callExpression && Array.isArray(callExpression.arguments); + }).forEach(replaceCalledDeclarator.bind(undefined, j)); + return root.toSource(util.getRecastConfig(options)); } @@ -80,3 +95,40 @@ function replaceDeclarator (j, variableDeclarator) { j(variableDeclarator).remove(); } } + +function replaceCalledDeclarator(j, variableDeclarator) { + var id = variableDeclarator.value.id + var factoryName; + if (id.type === 'Identifier') { + factoryName = id.name + 'Factory'; + } else if (id.type === 'ObjectPattern') { + factoryName = id.properties.map(function(property){ return property.key.name }).join('') + 'Factory'; + } + var calledArgs = variableDeclarator.value.init.arguments; + var importSource = variableDeclarator.value.init.callee.arguments[0].value; + var newImport = util.createImportStatement(importSource, factoryName); + var newDeclaration = createCalledDeclaration(j, id, factoryName, calledArgs) + variableDeclarator.parent.insertBefore(newImport, newDeclaration); + + if (variableDeclarator.parent.value.declarations.length === 1) { + if ('comments' in variableDeclarator.parent.value) { + newImport.comments = variableDeclarator.parent.value.comments; + } + j(variableDeclarator.parent).remove(); + } else { + if ('comments' in variableDeclarator.value) { + newImport.comments = variableDeclarator.value.comments; + } + j(variableDeclarator).remove(); + } +} + +function createCalledDeclaration(j, id, callee, args) { + return j.variableDeclaration('const', [j.variableDeclarator( + id, + j.callExpression( + j.identifier(callee), + args + ) + )]); +}