Skip to content

Commit

Permalink
update to esprima-fb
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanong committed Nov 22, 2014
1 parent 09a065d commit b5cb477
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 26 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ this module currently only supports transpilation between ES6 module and CommonJ

```js
var recast = require('recast')
var esprima = require('esprima')
var esprima = require('esprima-fb')
var Module = require('es6-module-crosspiler')

// parse the code with recast
Expand Down
18 changes: 17 additions & 1 deletion lib/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ var b = types.builders

var Module = require('./module')

/**
* Return a list of `require()`s.
*/

memo(Module.prototype, 'requires', function () {
var requires = []
types.visit(this.ast.program, {
Expand All @@ -26,7 +30,10 @@ memo(Module.prototype, 'requires', function () {
return requires
})

// look for module.exports or exports.xxxx
/**
* Look for `module.exports = ` or `exports[x] = `
*/

memo(Module.prototype, 'hasCommonExports', function () {
var hasCommonExports = false
types.visit(this.ast.program, {
Expand All @@ -43,6 +50,11 @@ memo(Module.prototype, 'hasCommonExports', function () {
return hasCommonExports
})

/**
* Skip function traversals if a `require()` function is defined
* somewhere, because then we're not trying to use a CommonJS require.
*/

function skipFunctionTraversal(path) {
// `require` is defined somewhere
if (path.scope.lookup('require')) return true
Expand All @@ -53,6 +65,10 @@ function skipFunctionTraversal(path) {
return false
}

/**
* Check whether a node is a `require()` expression.
*/

function isRequireExpression(path) {
// only global `require`
if (path.scope.lookup('require')) return false
Expand Down
14 changes: 9 additions & 5 deletions lib/exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Module.prototype.buildExports = function () {

if (node.default) {
var id
if (n.FunctionExpression.check(declaration) && declaration.id) {
if (n.FunctionDeclaration.check(declaration) && declaration.id) {
id = node._varname = declaration.id.name
} else {
id = node._varname = this.sourceToVariableName('default')
Expand All @@ -35,7 +35,7 @@ Module.prototype.buildExports = function () {
return
}

if (node.specifiers) {
if (node.specifiers.length) {
return node.specifiers.forEach(function (specifier) {
var id = specifier.id.name
exports.push([id, id])
Expand Down Expand Up @@ -74,14 +74,18 @@ Module.prototype.buildExports = function () {
this.ast.program.body.unshift(b.expressionStatement(obj))
}

/**
* Remove all the `export` statements after
* converting them to CommonJS.
*/

Module.prototype.removeExports = function () {
types.visit(this.ast.program, {
visitExportDeclaration: function (path) {
var declaration = path.node.declaration
if (path.node.default) {
// remove `export default`s
if (n.FunctionExpression.check(declaration) && declaration.id) {
declaration.type = 'FunctionDeclaration'
if (n.FunctionDeclaration.check(declaration) && declaration.id) {
path.replace(declaration)
} else {
path.replace(b.variableDeclaration('var', [
Expand All @@ -91,7 +95,7 @@ Module.prototype.removeExports = function () {
)
]))
}
} else if (path.node.specifiers) {
} else if (path.node.specifiers.length) {
// remove `export { x, y }`s
path.replace()
} else {
Expand Down
46 changes: 29 additions & 17 deletions lib/imports.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
var astUtils = require('ast-util')
var memo = require('memorizer')
var recast = require('recast')
var assert = require('assert')

var types = recast.types
var n = types.namedTypes
Expand Down Expand Up @@ -36,7 +37,7 @@ Module.prototype.renameImports = function () {
}

/**
* Build require() statements
* Build `require()` statements
*/

Module.prototype.buildImports =
Expand All @@ -51,30 +52,36 @@ Module.prototype.buildRequires = function () {
// import 'x' -> require('x')
// don't need to check whether default is exported
// or what type of module the dependency is here
if (node.kind === undefined)
return declarations.push(b.expressionStatement(buildRequire(value)))
if (!node.specifiers.length)
return declarations.push(b.expressionStatement(buildRequire(value)))

// import X from 'y' -> var X = require('y')
// this is a special case when the dependency is CJS
// to do: also check if it's renamed
var dep = this.lookup(value) || {}
if (node.kind === 'default' && dep.type === 'commonjs') {
var name = node.specifiers[0].id.name
return declarations.push(buildRequireDeclaration(name, value))
}
node.specifiers.forEach(function (specifier) {
// import X from 'y' -> var X = require('y')
// this is a special case when the dependency is CJS
// to do: also check if it's renamed
if (specifier.type === 'ImportDefaultSpecifier' && dep.type === 'commonjs') {
var name = specifier.id.name
return declarations.push(buildRequireDeclaration(name, value))
}

// named exports, creates a unique variable name
// then exports that as the require
// import { x, y } from 'z' -> var __z = require('z')
// then the `x` and `y`s are done later
var name = node._varname = this.sourceToVariableName(value)
return declarations.push(buildRequireDeclaration(name, value))
// named exports, creates a unique variable name
// then exports that as the require
// import { x, y } from 'z' -> var __z = require('z')
// then the `x` and `y`s are done later
var name = node._varname = this.sourceToVariableName(value)
return declarations.push(buildRequireDeclaration(name, value))
}, this)
}, this)

// add it to the top
this.ast.program.body = declarations.concat(this.ast.program.body)
}

/**
* var `variable` = require(`value`)
*/

function buildRequireDeclaration(variable, value) {
return b.variableDeclaration('var', [
b.variableDeclarator(
Expand All @@ -100,7 +107,7 @@ Module.prototype.buildReferences = function () {
if (!varname) return

node.specifiers.forEach(function (specifier) {
var id = node.kind === 'default'
var id = specifier.type === 'ImportDefaultSpecifier'
? 'default'
: specifier.id.name
var name = specifier.name
Expand All @@ -113,6 +120,7 @@ Module.prototype.buildReferences = function () {
})
})

// rewrite lookups
types.visit(this.ast.program, {
visitIdentifier: function (path) {
// make sure it's a variable reference
Expand All @@ -135,6 +143,10 @@ Module.prototype.buildReferences = function () {
})
}

/**
* Remove all `import` statements after converting them to `require()`s
*/

Module.prototype.removeImports = function () {
var body = this.ast.program.body
for (var i = 0; i < body.length; i++) {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
"license": "MIT",
"repository": "polyfills/es6-module-crosspiler",
"dependencies": {
"ast-util": "0",
"debug": "*",
"esprima-fb": "*",
"memorizer": "1",
"ast-util": "0",
"recast": "0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fs = require('fs')
path = require('path')
recast = require('recast')
assert = require('assert')
esprima = require('esprima')
esprima = require('esprima-fb')

Module = require('..')

Expand Down

0 comments on commit b5cb477

Please sign in to comment.