es6-module-transpiler
Advanced tools
Comparing version 0.8.0 to 0.8.1
@@ -100,2 +100,9 @@ /* jshint node:true, undef:true, unused:true */ | ||
if (this._convertResult) { | ||
throw new Error( | ||
'container has already converted contained modules ' + | ||
'and cannot add new module: ' + mod.path | ||
); | ||
} | ||
// We have not seen this module before, so let's give it a unique name. | ||
@@ -142,3 +149,6 @@ var modules = this.getModules(); | ||
Container.prototype.write = function(target) { | ||
var files = this.convert(); | ||
if (!this._convertResult) { | ||
this._convertResult = this.convert(); | ||
} | ||
var files = this._convertResult; | ||
var writer = new Writer(target); | ||
@@ -145,0 +155,0 @@ writer.write(files); |
@@ -67,2 +67,12 @@ /* jshint node:true, undef:true, unused:true */ | ||
); | ||
} else if (n.ImportNamespaceSpecifier.check(identifierPath.parent.node)) { | ||
return new DeclarationInfo( | ||
identifierPath.parent.parent.node, | ||
identifierPath.node | ||
); | ||
} else if (n.ImportDefaultSpecifier.check(identifierPath.parent.node)) { | ||
return new DeclarationInfo( | ||
identifierPath.parent.parent.node, | ||
identifierPath.node | ||
); | ||
} else { | ||
@@ -69,0 +79,0 @@ return null; |
@@ -272,3 +272,2 @@ /* jshint node:true, undef:true, unused:true */ | ||
var declarationInfo = DeclarationInfo.forIdentifierPath(identifierPath); | ||
assert.ok( | ||
@@ -275,0 +274,0 @@ declarationInfo, |
@@ -41,2 +41,5 @@ /* jshint node:true, undef:true, unused:true */ | ||
} else { | ||
if (!Path.extname(importedPath)) { | ||
importedPath += Path.extname(resolvedPath); | ||
} | ||
return new Module(resolvedPath, importedPath, container); | ||
@@ -43,0 +46,0 @@ } |
@@ -80,4 +80,27 @@ /* jshint node:true, undef:true, unused:true */ | ||
* @override | ||
* | ||
* ```js | ||
* export default <FunctionDeclaration|ClassDeclaration> | ||
* // or | ||
* export default <declaration|expression>; | ||
* ``` | ||
*/ | ||
BundleFormatter.prototype.defaultExport = function(mod, declaration) { | ||
if (n.FunctionDeclaration.check(declaration) || | ||
n.ClassDeclaration.check(declaration)) { | ||
// export default function foo () {} | ||
// -> becomes: | ||
// function foo () {} | ||
// var <moduleName>default = foo; | ||
return [ | ||
declaration, | ||
b.variableDeclaration( | ||
'var', | ||
[b.variableDeclarator( | ||
this.reference(mod, 'default'), | ||
declaration.id | ||
)] | ||
) | ||
]; | ||
} | ||
return b.variableDeclaration( | ||
@@ -84,0 +107,0 @@ 'var', |
@@ -210,4 +210,29 @@ /* jshint node:true, undef:true, unused:true */ | ||
* @override | ||
* | ||
* ```js | ||
* export default <FunctionDeclaration|ClassDeclaration> | ||
* // or | ||
* export default <declaration|expression>; | ||
* ``` | ||
*/ | ||
CommonJSFormatter.prototype.defaultExport = function(mod, declaration) { | ||
if (n.FunctionDeclaration.check(declaration) || | ||
n.ClassDeclaration.check(declaration)) { | ||
// export default function foo () {} | ||
// -> becomes: | ||
// function foo () {} | ||
// export.default = foo; | ||
return [ | ||
declaration, | ||
b.expressionStatement(b.assignmentExpression( | ||
'=', | ||
b.memberExpression( | ||
b.identifier('exports'), | ||
b.literal('default'), | ||
true | ||
), | ||
declaration.id | ||
)) | ||
]; | ||
} | ||
return b.expressionStatement(b.assignmentExpression( | ||
@@ -214,0 +239,0 @@ '=', |
@@ -46,16 +46,3 @@ /* jshint node:true, undef:true, unused:true */ | ||
ImportDeclarationList.prototype.declarationForNode = function(node) { | ||
switch (node.kind) { | ||
case 'default': | ||
return new DefaultImportDeclaration(this.module, node); | ||
case 'named': | ||
return new NamedImportDeclaration(this.module, node); | ||
case undefined: | ||
return new BareImportDeclaration(this.module, node); | ||
default: | ||
assert.ok(false, 'unexpected import kind at ' + sourcePosition(this.module, node) + ': ' + node.kind); | ||
break; | ||
} | ||
return new ImportDeclaration(this.module, node); | ||
}; | ||
@@ -66,2 +53,10 @@ | ||
* | ||
* ```js | ||
* import foo from 'math'; | ||
* import { sin, cos } from 'math'; | ||
* import * as bar from 'math'; | ||
* import foo, { sin, cos } from 'math'; | ||
* import foo, * as bar from 'math'; | ||
* ``` | ||
* | ||
* @constructor | ||
@@ -84,66 +79,20 @@ * @abstract | ||
/** | ||
* Represents a default import of the form | ||
* | ||
* ```js | ||
* import List from 'list'; | ||
* ``` | ||
* | ||
* @constructor | ||
* @extends ImportDeclaration | ||
* @param {Module} mod | ||
* @param {AST.ImportDeclaration} node | ||
*/ | ||
function DefaultImportDeclaration(mod, node) { | ||
assert.equal(node.kind, 'default'); | ||
assert.ok( | ||
node.specifiers.length === 1 && node.specifiers[0], | ||
'expected exactly one specifier for a default import, got ' + | ||
node.specifiers.length | ||
); | ||
ImportDeclaration.call(this, mod, node); | ||
} | ||
extend(DefaultImportDeclaration, ImportDeclaration); | ||
/** | ||
* Contains a list of specifier name information for this import. | ||
* | ||
* @type {ImportSpecifier[]} | ||
* @name DefaultImportDeclaration#specifiers | ||
* @name ImportDeclaration#specifiers | ||
*/ | ||
memo(DefaultImportDeclaration.prototype, 'specifiers', /** @this DefaultImportDeclaration */function() { | ||
var specifier = new ImportSpecifier(this, this.node.specifiers[0]); | ||
specifier.from = 'default'; | ||
assert.equal(specifier.from, 'default'); | ||
return [specifier]; | ||
}); | ||
/** | ||
* Represents a named import of the form | ||
* | ||
* ```js | ||
* import { sin, cos } from 'math'; | ||
* ``` | ||
* | ||
* @constructor | ||
* @extends ImportDeclaration | ||
* @param {Module} mod | ||
* @param {AST.ImportDeclaration} node | ||
*/ | ||
function NamedImportDeclaration(mod, node) { | ||
assert.equal(node.kind, 'named'); | ||
ImportDeclaration.call(this, mod, node); | ||
} | ||
extend(NamedImportDeclaration, ImportDeclaration); | ||
/** | ||
* Contains a list of specifier name information for this import. | ||
* | ||
* @type {ImportSpecifier[]} | ||
* @name NamedImportDeclaration#specifiers | ||
*/ | ||
memo(NamedImportDeclaration.prototype, 'specifiers', /** @this NamedImportDeclaration */function() { | ||
memo(ImportDeclaration.prototype, 'specifiers', /** @this ImportDeclaration */function() { | ||
var self = this; | ||
return this.node.specifiers.map(function(specifier) { | ||
return new ImportSpecifier(self, specifier); | ||
return this.node.specifiers.map(function(s) { | ||
var specifier = new ImportSpecifier(self, s); | ||
if (n.ImportDefaultSpecifier.check(s)) { | ||
specifier.from = 'default'; | ||
} else if (n.ImportNamespaceSpecifier.check(s)) { | ||
// TODO: implement import * as ... | ||
specifier.from = '*'; | ||
} else { | ||
specifier = new ImportSpecifier(self, s); | ||
} | ||
return specifier; | ||
}); | ||
@@ -153,33 +102,2 @@ }); | ||
/** | ||
* Represents an import with no bindings created in the local scope. These | ||
* imports are of the form `import 'path/to/module'` and are generally included | ||
* only for their side effects. | ||
* | ||
* @constructor | ||
* @extends ImportDeclaration | ||
* @param {Module} mod | ||
* @param {AST.ImportDeclaration} node | ||
*/ | ||
function BareImportDeclaration(mod, node) { | ||
assert.ok( | ||
node.kind === undefined && node.specifiers.length === 0, | ||
'expected a bare import at ' + sourcePosition(mod, node) + | ||
', got one with kind=' + node.kind + ' and ' + | ||
node.specifiers.length + ' specifier(s)' | ||
); | ||
ImportDeclaration.call(this, mod, node); | ||
} | ||
extend(BareImportDeclaration, ImportDeclaration); | ||
/** | ||
* Returns an empty set of specifiers. | ||
* | ||
* @type {ImportSpecifier[]} | ||
* @name BareImportDeclaration#specifiers | ||
*/ | ||
memo(BareImportDeclaration.prototype, 'specifiers', /** @this BareImportDeclaration */function() { | ||
return []; | ||
}); | ||
/** | ||
* Represents an import specifier. The "a" and "b as c" are both import | ||
@@ -186,0 +104,0 @@ * specifiers in the following import statement. |
@@ -7,3 +7,3 @@ /* jshint node:true, undef:true, unused:true */ | ||
var esprima = require('esprima'); | ||
var esprima = require('esprima-fb'); | ||
var recast = require('recast'); | ||
@@ -10,0 +10,0 @@ var types = recast.types; |
@@ -11,2 +11,3 @@ /* jshint node:true, undef:true, unused:true */ | ||
var utils = require('./utils'); | ||
var extend = utils.extend; | ||
var sourcePosition = utils.sourcePosition; | ||
@@ -21,2 +22,3 @@ var Replacement = require('./replacement'); | ||
* @param {Formatter} formatter | ||
* @extends types.PathVisitor | ||
*/ | ||
@@ -32,3 +34,3 @@ function Rewriter(formatter) { | ||
} | ||
utils.extend(Rewriter, types.PathVisitor); | ||
extend(Rewriter, types.PathVisitor); | ||
@@ -78,4 +80,8 @@ /** | ||
var mod = modules[i]; | ||
this.currentModule = mod; | ||
types.visit(mod.ast.program, this); | ||
if (mod.exports.declarations.length > 0 || mod.imports.declarations.length > 0) { | ||
this.currentModule = mod; | ||
types.visit(mod.ast.program, this); | ||
} else { | ||
types.visit(mod.ast.program, new DeclarationLinterVisitor(mod)); | ||
} | ||
} | ||
@@ -175,3 +181,3 @@ this.currentModule = null; | ||
Rewriter.prototype.visitExportDeclaration = function(nodePath) { | ||
this.assertStatementIsTopLevel(this.currentModule, nodePath); | ||
assertStatementIsTopLevel(this.currentModule, nodePath); | ||
@@ -221,3 +227,3 @@ var replacement; | ||
Rewriter.prototype.visitImportDeclaration = function(nodePath) { | ||
this.assertStatementIsTopLevel(this.currentModule, nodePath); | ||
assertStatementIsTopLevel(this.currentModule, nodePath); | ||
var replacement = this.formatter.processImportDeclaration(this.currentModule, nodePath); | ||
@@ -276,3 +282,5 @@ if (replacement) { | ||
var declarationPath = declarationPaths[0]; | ||
if (n.ImportSpecifier.check(declarationPath.parent.node)) { | ||
if (n.ImportSpecifier.check(declarationPath.parent.node) || | ||
n.ImportDefaultSpecifier.check(declarationPath.parent.node) || | ||
n.ImportNamespaceSpecifier.check(declarationPath.parent.node)) { | ||
throw new SyntaxError( | ||
@@ -287,21 +295,4 @@ 'Cannot reassign imported binding `' + name + | ||
/** | ||
* We need to ensure that all imports/exports are only at the top level. Esprima | ||
* should perhaps take care of this for us, but it does not. | ||
* | ||
* @param {Module} mod | ||
* @param {NodePath} nodePath | ||
* @private | ||
*/ | ||
Rewriter.prototype.assertStatementIsTopLevel = function(mod, nodePath) { | ||
if (!nodePath.scope.isGlobal) { | ||
throw new SyntaxError( | ||
'Unexpected non-top level ' + nodePath.node.type + | ||
' found at ' + sourcePosition(mod, nodePath.node) | ||
); | ||
} | ||
}; | ||
/** | ||
* @private | ||
*/ | ||
Rewriter.prototype.getExportReferenceForReference = function(mod, referencePath) { | ||
@@ -335,2 +326,51 @@ if (n.ExportSpecifier.check(referencePath.parent.node) && !referencePath.parent.node.default) { | ||
/** | ||
* Traverses ASTs only checking for invalid import/export declaration semantics. | ||
* | ||
* @constructor | ||
* @extends types.PathVisitor | ||
* @param {Module} mod | ||
* @private | ||
*/ | ||
function DeclarationLinterVisitor(mod) { | ||
this.module = mod; | ||
types.PathVisitor.call(this); | ||
} | ||
extend(DeclarationLinterVisitor, types.PathVisitor); | ||
/** | ||
* Checks that the import declaration is at the top level. | ||
* | ||
* @param {NodePath} nodePath | ||
*/ | ||
DeclarationLinterVisitor.prototype.visitImportDeclaration = function(nodePath) { | ||
assertStatementIsTopLevel(this.module, nodePath); | ||
}; | ||
/** | ||
* Checks that the export declaration is at the top level. | ||
* | ||
* @param {NodePath} nodePath | ||
*/ | ||
DeclarationLinterVisitor.prototype.visitExportDeclaration = function(nodePath) { | ||
assertStatementIsTopLevel(this.module, nodePath); | ||
}; | ||
/** | ||
* We need to ensure that all imports/exports are only at the top level. Esprima | ||
* should perhaps take care of this for us, but it does not. | ||
* | ||
* @param {Module} mod | ||
* @param {NodePath} nodePath | ||
* @private | ||
*/ | ||
function assertStatementIsTopLevel(mod, nodePath) { | ||
if (!nodePath.scope.isGlobal) { | ||
throw new SyntaxError( | ||
'Unexpected non-top level ' + nodePath.node.type + | ||
' found at ' + sourcePosition(mod, nodePath.node) | ||
); | ||
} | ||
} | ||
module.exports = Rewriter; |
/* jshint node:true, undef:true, unused:true */ | ||
var recast = require('recast'); | ||
var esprima = require('esprima'); | ||
var esprima = require('esprima-fb'); | ||
var fs = require('fs'); | ||
@@ -77,1 +78,14 @@ var proto = '__proto__'; | ||
exports.IFFE = IFFE; | ||
function mkdirpSync(path) { | ||
var parts = path.split('/'); | ||
var dir = ''; | ||
parts.forEach(function(part) { | ||
dir += '/' + part; | ||
if (!fs.existsSync(dir)) { | ||
fs.mkdirSync(dir); | ||
} | ||
}); | ||
} | ||
exports.mkdirpSync = mkdirpSync; |
@@ -7,3 +7,3 @@ /* jshint node:true, undef:true, unused:true */ | ||
var Path = require('path'); | ||
var mkdirp = require('mkdirp'); | ||
var mkdirpSync = require('./utils').mkdirpSync; | ||
@@ -60,3 +60,3 @@ function Writer(target) { | ||
mkdirp.sync(Path.dirname(filename)); | ||
mkdirpSync(Path.dirname(filename)); | ||
@@ -69,9 +69,9 @@ if (rendered.map) { | ||
JSON.stringify(rendered.map), | ||
{ encoding: 'utf8' } | ||
'utf8' | ||
); | ||
} | ||
fs.writeFileSync(filename, code, { encoding: 'utf8' }); | ||
fs.writeFileSync(filename, code, 'utf8'); | ||
}; | ||
module.exports = Writer; |
{ | ||
"name": "es6-module-transpiler", | ||
"version": "0.8.0", | ||
"version": "0.8.1", | ||
"description": "es6-module-transpiler is an experimental compiler that allows you to write your JavaScript using a subset of the current ES6 module syntax, and compile it into various formats.", | ||
@@ -36,3 +36,4 @@ "homepage": "http://square.github.com/es6-module-transpiler", | ||
"test-commonjs": "node test/runner.js -f commonjs", | ||
"test-unit": "mocha -R spec test/unit" | ||
"test-unit": "mocha -R spec test/unit", | ||
"build-standalone": "browserify -s ModuleTranspiler -e lib/index.js -o es6-module-transpiler.js" | ||
}, | ||
@@ -42,12 +43,18 @@ "author": "Square, Inc.", | ||
"dependencies": { | ||
"ast-util": "^0.1.2", | ||
"esprima": "git://github.com/esnext/esprima#harmony-esnext", | ||
"mkdirp": "^0.5.0", | ||
"ast-util": "^0.5.1", | ||
"esprima-fb": "^7001.1.0-dev-harmony-fb", | ||
"posix-getopt": "^1.0.0", | ||
"recast": "^0.6.6" | ||
"recast": "^0.8.0" | ||
}, | ||
"devDependencies": { | ||
"browserify": "^5.12.1", | ||
"example-runner": "^0.1.0", | ||
"mocha": "^1.20.1" | ||
"fake-fs": "^0.4.0", | ||
"mocha": "^1.20.1", | ||
"tmp": "0.0.24" | ||
}, | ||
"browser": { | ||
"fs": "./lib/browser/fs.js", | ||
"./lib/index.js": "./lib/browser/index.js" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Git dependency
Supply chain riskContains a dependency which resolves to a remote git URL. Dependencies fetched from git URLs are not immutable and can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
104736
4
26
3203
0
5
8
+ Addedast-types@0.5.7(transitive)
+ Addedast-util@0.5.2(transitive)
+ Addedesprima-fb@7001.1.0-dev-harmony-fb(transitive)
+ Addedrecast@0.8.8(transitive)
- Removedesprima@git://github.com/esnext/esprima#harmony-esnext
- Removedmkdirp@^0.5.0
- Removedast-types@0.3.380.4.13(transitive)
- Removedast-util@0.1.2(transitive)
- Removedminimist@1.2.8(transitive)
- Removedmkdirp@0.5.6(transitive)
- Removedrecast@0.6.10(transitive)
Updatedast-util@^0.5.1
Updatedrecast@^0.8.0