Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
* dev:
  Re: #35, #32 - Releasing AMDClean v1.3.0
  Fixed typo
  #33 - Added ability for relative module resolution.
  • Loading branch information
gfranko committed Mar 4, 2014
2 parents 5a0d3f6 + 6004e6a commit 1f2f1ef
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 15 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.2.1",
"version": "1.3.0",
"description": "A build tool that converts AMD code to standard JavaScript",
"main": "./src/amdclean",
"repository": {
Expand Down
84 changes: 75 additions & 9 deletions src/amdclean.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! amdclean - v1.2.1 - 2014-02-17
/*! amdclean - v1.3.0 - 2014-03-03
* 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.2.1',
'VERSION': '1.3.0',
// Default Options
'defaultOptions': {
// The source code you would like to be 'cleaned'
Expand Down Expand Up @@ -559,16 +559,61 @@
}());
return updatedNode;
},
// isRelativeFilePath
// ------------------
// Returns a boolean that determines if the file path provided is a relative file path
// e.g. ../exampleModule -> true
isRelativeFilePath: function(path) {
var segments = path.split('/');

return segments.length !== -1 && (segments[0] === '.' || segments[0] === '..');
},
// normalizeDependencyName
// -----------------------
// Returns a normalized dependency name that handles relative file paths
'normalizeDependencyName': function(moduleId, dep) {
if(!moduleId || !dep || !publicAPI.isRelativeFilePath(dep)) {
return dep;
}

var normalizePath = function(path) {
var segments = path.split('/'),
normalizedSegments;

normalizedSegments = _.reduce(segments, function(memo, segment) {
switch(segment) {
case '.':
break;
case '..':
memo.pop();
break;
default:
memo.push(segment);
}

return memo;
}, []);
return normalizedSegments.join('/');
},
baseName = function(path) {
var segments = path.split('/');

segments.pop();
return segments.join('/');
};
return normalizePath([baseName(moduleId), dep].join('/'));
},
// convertToFunctionExpression
// ---------------------------
// Returns either an IIFE or variable declaration.
// Internally calls either convertToIIFE() or convertToIIFEDeclaration().
// Internally calls either convertToIIFE() or convertToIIFEDeclaration()
'convertToFunctionExpression': function(obj) {
var isDefine = obj.isDefine,
isRequire = obj.isRequire,
isOptimized = false,
node = obj.node,
moduleName = obj.moduleName,
moduleId = obj.moduleId,
dependencies = obj.dependencies,
depLength = dependencies.length,
options = publicAPI.options,
Expand All @@ -577,7 +622,7 @@
iterator = -1,
currentName;
while(++iterator < depLength) {
currentName = dependencies[iterator];
currentName = publicAPI.normalizeDependencyName(moduleId, dependencies[iterator]);
if(options.globalObject === true && options.globalObjectName && currentName !== '{}') {
deps.push({
'type': 'MemberExpression',
Expand Down Expand Up @@ -717,6 +762,7 @@
args,
dependencies,
moduleReturnValue,
moduleId,
params,
isDefine = publicAPI.isDefine(node),
isRequire = publicAPI.isRequire(node),
Expand Down Expand Up @@ -778,10 +824,12 @@
return depNames;
}());
moduleReturnValue = isRequire ? args[1] : args[args.length - 1];
moduleName = publicAPI.normalizeModuleName(node.expression['arguments'][0].value);
moduleId = node.expression['arguments'][0].value;
moduleName = publicAPI.normalizeModuleName(moduleId);
params = {
node: node,
moduleName: moduleName,
moduleId: moduleId,
dependencies: dependencies,
moduleReturnValue: moduleReturnValue,
isDefine: isDefine,
Expand Down Expand Up @@ -968,6 +1016,7 @@
if(ast && _.isArray(ast.body)) {
estraverse.replace(ast, {
enter: function(node, parent) {
var normalizedModuleName;
if(node === undefined || node.type === 'EmptyStatement') {
_.each(parent.body, function(currentNode, iterator) {
if(currentNode === undefined || currentNode.type === 'EmptyStatement') {
Expand All @@ -976,10 +1025,27 @@
});
} else if(publicAPI.isRequireExpression(node)) {
if(node['arguments'] && node['arguments'][0] && node['arguments'][0].value) {
return {
'type': 'Identifier',
'name': publicAPI.normalizeModuleName(node['arguments'][0].value)
};
normalizedModuleName = publicAPI.normalizeModuleName(node['arguments'][0].value);
if(options.globalObject === true && (options.globalObjectName && _.isString(options.globalObjectName) && options.globalObjectName.length)) {
return {
'type': 'MemberExpression',
'computed': true,
'object': {
'type': 'Identifier',
'name': options.globalObjectName
},
'property': {
'type': 'Literal',
'value': normalizedModuleName,
'raw': normalizedModuleName
}
};
} else {
return {
'type': 'Identifier',
'name': normalizedModuleName
};
}
} else {
return node;
}
Expand Down
40 changes: 36 additions & 4 deletions test/specs/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,30 @@ describe('amdclean specs', function() {
expect(cleanedCode).toBe(standardJavaScript);
});

it('should correctly normalize relative file paths dependencies', function() {
var AMDcode = "define('./modules/example', ['./example1', './example2', '../example3'], function(one, two, three) {var test = true;});",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var modules_example=function (one,two,three){var test=true;}(modules_example1,modules_example2,example3);";

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

it('should correctly normalize relative file paths dependencies with the globalObject option', function() {
var AMDcode = "define('./modules/example', ['./example1', './example2', '../example3'], function(one, two, three) {var test = true;});",
cleanedCode = amdclean.clean({ globalObject: true, rememberGlobalObject: false, code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var amdclean={};amdclean['modules_example']=function (one,two,three){var test=true;}(amdclean['modules_example1'],amdclean['modules_example2'],amdclean['example3']);";

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

it('should correctly normalize multi-level relative file paths dependencies', function() {
var AMDcode = "define('./foo/prototype/subModule/myModule', ['example1','example2', '/anotherModule/example3', '../../example4','../anotherModule/example5'], function(one, two, three, four, five) { var test = true;});",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var foo_prototype_subModule_myModule=function (one,two,three,four,five){var test=true;}(example1,example2,anotherModule_example3,foo_example4,foo_prototype_anotherModule_example5);";

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

it('should correctly normalize multi-level relative file paths', function() {
var AMDcode = "define('./foo/prototype/commonMethodName.js', ['example1', 'example2'], function(one, two) { var test = true;});",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
Expand Down Expand Up @@ -119,8 +143,8 @@ describe('amdclean specs', function() {

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, globalObjectName: 'yeabuddy', code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var yeabuddy={};yeabuddy['foo']=function (require,exports,bar){exports.bar=bar;return exports;}({},{},yeabuddy['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']);";

expect(cleanedCode).toBe(standardJavaScript);
});
Expand Down Expand Up @@ -337,8 +361,8 @@ describe('amdclean specs', function() {

it('should convert object return values to a global object', function() {
var AMDcode = "define('third', { exampleProp: 'This is an example' });",
cleanedCode = amdclean.clean({ globalObject: true, code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "amdclean['third']={exampleProp:'This is an example'};";
cleanedCode = amdclean.clean({ globalObject: true, rememberGlobalObject: false, code: AMDcode, escodegen: { format: { compact: true } } }),
standardJavaScript = "var amdclean={};amdclean['third']={exampleProp:'This is an example'};";

expect(cleanedCode).toBe(standardJavaScript);
});
Expand All @@ -355,6 +379,14 @@ describe('amdclean specs', function() {
expect(cleanedCode).toBe(standardJavaScript);
});

it('should convert CommonJS require() calls correctly with the globalObject option', function() {
var AMDcode = "var example = require('anotherModule');",
cleanedCode = amdclean.clean({ code: AMDcode, globalObject: true, rememberGlobalObject: false, escodegen: { format: { compact: true } } }),
standardJavaScript = "var amdclean={};var example=amdclean['anotherModule'];";

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

it('should convert CommonJS require() calls with file paths', function() {
var AMDcode = "var example = require('./anotherModule');",
cleanedCode = amdclean.clean({ code: AMDcode, escodegen: { format: { compact: true } } }),
Expand Down

0 comments on commit 1f2f1ef

Please sign in to comment.