Skip to content

Commit

Permalink
Releasing AMDClean 1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
gfranko committed Mar 18, 2014
1 parent 03e61a4 commit 4833240
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 54 deletions.
2 changes: 1 addition & 1 deletion build/amdclean.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "amdclean",
"version": "1.4.1",
"version": "1.5.0",
"description": "A build tool that converts AMD code to standard JavaScript",
"main": "./src/amdclean",
"repository": {
Expand Down
89 changes: 49 additions & 40 deletions src/amdclean.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! amdclean - v1.4.1 - 2014-03-17
/*! amdclean - v1.5.0 - 2014-03-17
* http://gregfranko.com/amdclean
* Copyright (c) 2014 Greg Franko; Licensed MIT*/

Expand Down Expand Up @@ -74,7 +74,7 @@
// The Public API object
publicAPI = {
// Current project version number
'VERSION': '1.4.1',
'VERSION': '1.5.0',
// Default Options
'defaultOptions': {
// The source code you would like to be 'cleaned'
Expand All @@ -99,7 +99,12 @@
},
// All escodegen API options are supported: https://github.com/Constellation/escodegen/wiki/API
'escodegen': {
'comment': true
'comment': true,
'format': {
'indent': {
'adjustMultilineComment': true
}
}
},
// If there is a comment (that contains the following text) on the same line or one line above a specific module, the module will not be removed
'commentCleanName': 'amdclean',
Expand All @@ -111,6 +116,9 @@
'removeAllRequires': false,
// Determines if all of the 'use strict' statements will be removed
'removeUseStricts': true,
// Determines if conditional AMD checks are transformed
// e.g. if(typeof define == 'function') {} -> if(true) {}
'transformAMDChecks': true,
// Allows you to pass an expression that will override shimmed modules return values
// e.g. { 'backbone': 'window.Backbone' }
'shimOverrides': {},
Expand Down Expand Up @@ -157,9 +165,9 @@
// --------------------
// Variable names that are not allowed as dependencies to functions
'dependencyBlacklist': {
'require': true,
'require': 'remove',
'exports': true,
'module': true
'module': 'remove'
},
// defaultLOC
// ----------
Expand Down Expand Up @@ -259,10 +267,10 @@
// Returns if the current AST node is an if statement AMD check
// e.g. if(typeof define === 'function') {}
'isAMDConditional': function(node) {
if(node && node.type !== 'IfStatement' ||
if(publicAPI.options.transformAMDChecks !== true || (node && node.type !== 'IfStatement' ||
!_.isObject(node.test) ||
!_.isObject(node.test.left) ||
_.isNull(node.test.left.value)) {
_.isNull(node.test.left.value))) {
return false;
}
var matchObject = {
Expand Down Expand Up @@ -312,22 +320,26 @@
// normalizeModuleName
// -------------------
// Returns a normalized module name (removes relative file path urls)
'normalizeModuleName': function(name) {
'normalizeModuleName': function(name, moduleId) {
var pre_normalized,
post_normalized,
prefixMode = publicAPI.options.prefixMode,
prefixTransform = publicAPI.options.prefixTransform,
prefixTransformValue;
name = name || '';
if(name === '{}') {
return name;
if(publicAPI.dependencyBlacklist[name] === 'remove') {
return '';
} else {
return name;
}
}
pre_normalized = publicAPI.prefixReservedWords(name.replace(/\./g,'').
replace(/[^A-Za-z0-9_$]/g,'_').
replace(/^_+/,''));
post_normalized = prefixMode === 'camelCase' ? publicAPI.convertToCamelCase(pre_normalized) : pre_normalized;
if(_.isFunction(prefixTransform)) {
prefixTransformValue = prefixTransform(post_normalized);
prefixTransformValue = prefixTransform(post_normalized, moduleId);
if(_.isString(prefixTransformValue) && prefixTransformValue.length) {
return prefixTransformValue;
}
Expand Down Expand Up @@ -505,9 +517,6 @@
// Returns a function expression that is executed immediately
// e.g. var example = function(){}()
'convertToIIFEDeclaration': function(obj) {
// console.log('obj.callbackFunc', obj.callbackFunc);
// console.log('obj.callbackFunc.body.body', obj.callbackFunc.body.body);
// return;
var moduleName = obj.moduleName,
callbackFuncParams = obj.callbackFuncParams,
isOptimized = obj.isOptimized,
Expand All @@ -531,7 +540,7 @@
'range': (cbFunc.range || publicAPI.defaultRange),
'loc': (cbFunc.loc || publicAPI.defaultLOC)
},
'arguments': [],
'arguments': callbackFuncParams,
'range': (cbFunc.range || publicAPI.defaultRange),
'loc': (cbFunc.loc || publicAPI.defaultLOC)
},
Expand Down Expand Up @@ -699,10 +708,9 @@
options = publicAPI.options,
dependencyNames = (function() {
var deps = [],
iterator = -1,
currentName;
while(++iterator < depLength) {
currentName = publicAPI.normalizeDependencyName(moduleId, dependencies[iterator]);
_.each(dependencies, function(currentDependency, iterator) {
currentName = publicAPI.normalizeModuleName(publicAPI.normalizeDependencyName(moduleId, currentDependency), moduleId);
if(options.globalObject === true && options.globalObjectName && currentName !== '{}') {
deps.push({
'type': 'MemberExpression',
Expand All @@ -715,24 +723,24 @@
},
'property': {
'type': 'Literal',
'value': publicAPI.normalizeModuleName(currentName),
'raw': "" + publicAPI.normalizeModuleName(currentName) + "",
'value': currentName,
'raw': "" + currentName + "",
'range': publicAPI.defaultRange,
'loc': publicAPI.defaultLOC
},
'name': publicAPI.normalizeModuleName(currentName),
'name': currentName,
'range': publicAPI.defaultRange,
'loc': publicAPI.defaultLOC
});
} else {
deps.push({
'type': 'Identifier',
'name': publicAPI.normalizeModuleName(currentName),
'name': currentName,
'range': publicAPI.defaultRange,
'loc': publicAPI.defaultLOC
});
}
}
});
return deps;
}()),
callbackFunc = (function() {
Expand Down Expand Up @@ -792,30 +800,27 @@
hasExportsParam = false,
callbackFuncParams = (function() {
var deps = [],
iterator = -1,
currentParam,
currentName,
cbParams = callbackFunc.params || [];
while(++iterator < depLength) {
currentParam = cbParams[iterator];
cbParams = callbackFunc.params || dependencyNames || [];
_.each(cbParams, function(currentParam, iterator) {
if(currentParam) {
currentName = currentParam.name;
} else {
console.log('iterator', iterator);
currentName = dependencyNames[iterator].name;
}
if(currentName === 'exports') {
hasExportsParam = true;
}
if(currentName === '{}') {
currentName = 'module';
if(currentName !== '{}' && publicAPI.dependencyBlacklist[currentName] !== 'remove') {
deps.push({
'type': 'Identifier',
'name': currentName,
'range': publicAPI.defaultRange,
'loc': publicAPI.defaultLOC
});
}
deps.push({
'type': 'Identifier',
'name': currentName,
'range': publicAPI.defaultRange,
'loc': publicAPI.defaultLOC
});
}
});
return deps;
}());

Expand Down Expand Up @@ -912,10 +917,14 @@
}
if(Array.isArray(deps) && deps.length) {
_.each(deps, function(currentDependency) {
if(publicAPI.dependencyBlacklist[currentDependency.value]) {
depNames.push('{}');
} else {
depNames.push(currentDependency.value);
if(publicAPI.dependencyBlacklist[currentDependency.value] !== 'remove') {
if(publicAPI.dependencyBlacklist[currentDependency.value]) {
if(publicAPI.dependencyBlacklist[currentDependency.value] !== 'remove') {
depNames.push('{}');
}
} else {
depNames.push(currentDependency.value);
}
}
});
}
Expand Down
49 changes: 37 additions & 12 deletions test/specs/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,33 +150,33 @@ describe('amdclean specs', function() {
});

it('should support the simplified CJS wrapper', function() {
var AMDcode = "define('foo', ['require', 'exports', './bar'], function(require, exports){exports.bar = require('./bar');});",
var AMDcode = "define('foo', ['require', 'exports', './bar'], function(require, exports, bar){exports.bar = require('./bar');});",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var foo=function (require,exports,bar){exports.bar=bar;return exports;}({},{},bar);";
standardJavaScript = "var foo=function (exports,bar){exports.bar=bar;return exports;}({},bar);";

expect(cleanedCode).toBe(standardJavaScript);
});

it('should support the plain simplified CJS wrapper', function() {
var AMDcode = "define('foo',['require','exports','module','bar'],function(require, exports){exports.bar = require('bar');});",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var foo=function (require,exports,module,bar){exports.bar=bar;return exports;}({},{},{},bar);";
standardJavaScript = "var foo=function (exports){exports.bar=bar;return exports;}({},bar);";

expect(cleanedCode).toBe(standardJavaScript);
});

it('should support global modules', function() {
var AMDcode = "define('foo', ['require', 'exports', './bar'], function(require, exports){exports.bar = require('./bar');});",
cleanedCode = amdclean.clean({ globalModules: ['foo'], code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var foo=function (require,exports,bar){exports.bar=bar;return exports;}({},{},bar);window.foo=foo;";
standardJavaScript = "var foo=function (exports){exports.bar=bar;return exports;}({},bar);window.foo=foo;";

expect(cleanedCode).toBe(standardJavaScript);
});

it('should support storing modules inside of a global object', function() {
var AMDcode = "define('foo', ['require', 'exports', './bar'], function(require, exports){exports.bar = require('./bar');});",
cleanedCode = amdclean.clean({ globalObject: true, rememberGlobalObject: false, globalObjectName: 'yeabuddy', code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var yeabuddy={};yeabuddy['foo']=function (require,exports,bar){exports.bar=yeabuddy['bar'];return exports;}({},{},yeabuddy['bar']);";
standardJavaScript = "var yeabuddy={};yeabuddy['foo']=function (exports){exports.bar=yeabuddy['bar'];return exports;}({},yeabuddy['bar']);";

expect(cleanedCode).toBe(standardJavaScript);
});
Expand All @@ -200,7 +200,7 @@ describe('amdclean specs', function() {
it('should support converting define() methods with identifiers', function() {
var AMDcode = "define('esprima', ['exports'], factory);",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var esprima=function (module){return factory();}({});";
standardJavaScript = "var esprima=function (){return factory();}({});";

expect(cleanedCode).toBe(standardJavaScript);
});
Expand Down Expand Up @@ -229,6 +229,14 @@ describe('amdclean specs', function() {
expect(cleanedCode).toBe(standardJavaScript);
});

it('should not automatically convert conditional AMD checks if the transformAMDChecks option is set to false', function() {
var AMDcode = "if(typeof define === 'function') {}",
cleanedCode = amdclean.clean({ code: AMDcode, transformAMDChecks: false, escodegen: { format: { compact: true } } }),
standardJavaScript = "if(typeof define==='function'){}";

expect(cleanedCode).toBe(standardJavaScript);
});

describe('optimized defines', function() {

it('should optimize basic define() methods that return a function expression', function() {
Expand Down Expand Up @@ -290,7 +298,7 @@ describe('amdclean specs', function() {
it('should not optimize define() methods that have one or more dependencies', function() {
var AMDcode = "define('optimized', ['exampleDependency'], function () { return function ( thing ) { var anotherThing = true; return !isNaN( parseFloat( thing ) ) && isFinite( thing );};});",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var optimized=function (exampleDependency){return function(thing){var anotherThing=true;return!isNaN(parseFloat(thing))&&isFinite(thing);};}(exampleDependency);";
standardJavaScript = "var optimized=function (){return function(thing){var anotherThing=true;return!isNaN(parseFloat(thing))&&isFinite(thing);};}(exampleDependency);";

expect(cleanedCode).toBe(standardJavaScript);
});
Expand All @@ -314,7 +322,7 @@ describe('amdclean specs', function() {
it('should not optimize basic define() methods that return a literal value that have one or more dependencies', function() {
var AMDcode = "define('optimized', ['someDependency'], function() { return 'Convert AMD code to standard JavaScript';});",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var optimized=function (someDependency){return'Convert AMD code to standard JavaScript';}(someDependency);";
standardJavaScript = "var optimized=function (){return'Convert AMD code to standard JavaScript';}(someDependency);";

expect(cleanedCode).toBe(standardJavaScript);
});
Expand Down Expand Up @@ -368,7 +376,7 @@ describe('amdclean specs', function() {
compact: true
}
},
prefixTransform: function(moduleName) {
prefixTransform: function(moduleName, moduleId) {
return moduleName.substring(moduleName.lastIndexOf('_') + 1, moduleName.length);
}
}),
Expand Down Expand Up @@ -518,7 +526,7 @@ describe('amdclean specs', function() {
it('should not remove require() calls with a non-empty callback function', function() {
var AMDcode = "require(['testModule'], function() {var test=true;});",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "(function(testModule){var test=true;}(testModule));";
standardJavaScript = "(function(){var test=true;}(testModule));";

expect(cleanedCode).toBe(standardJavaScript);
});
Expand All @@ -543,7 +551,7 @@ describe('amdclean specs', function() {
var AMDcode = "(function (root, factory) {" +
"'use strict';" +
"if (typeof define === 'function') {" +
"define(['exports'], factory);" +
"define('esprima', ['exports'], factory);" +
"} else if (typeof exports !== 'undefined') {" +
"factory(exports);" +
"} else {" +
Expand All @@ -553,7 +561,24 @@ describe('amdclean specs', function() {
"var test = true;" +
"}));",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "(function(root,factory){'use strict';if(true){var =function (module){return factory();}({});}else if(typeof exports!=='undefined'){factory(exports);}else{factory(root.esprima={});}}(this,function(exports){exports=exports||{};var test=true;return exports;}));";
standardJavaScript = "(function(root,factory){'use strict';if(true){var esprima=function (){return factory();}({});}else if(typeof exports!=='undefined'){factory(exports);}else{factory(root.esprima={});}}(this,function(exports){exports=exports||{};var test=true;return exports;}));";

expect(cleanedCode).toBe(standardJavaScript);
});

it('should correctly convert libraries that use factory function parameters', function() {
var AMDcode = "(function (factory) {" +
"if (typeof exports === 'object') {" +
"module.exports = factory(require('backbone'), require('underscore'));" +
"} else if (typeof define === 'function' && define.amd) {" +
"define('backbonevalidation', ['backbone', 'underscore'], factory);" +
"}" +
"}(function (Backbone, _) {" +
"//= backbone-validation.js\n" +
"return Backbone.Validation;" +
"}));",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "(function(factory){if(typeof exports==='object'){module.exports=factory(backbone,underscore);}else if(true){var backbonevalidation=function (backbone,underscore){return factory(backbone,underscore);}(backbone,underscore);}}(function(Backbone,_){//= backbone-validation.js\nreturn Backbone.Validation;}));";

expect(cleanedCode).toBe(standardJavaScript);
});
Expand Down

0 comments on commit 4833240

Please sign in to comment.