diff --git a/README.md b/README.md index 31cfa16..491e43d 100644 --- a/README.md +++ b/README.md @@ -559,7 +559,10 @@ amdclean.clean({ 'start': ';(function() {\n', // This string is appended to the file 'end': '\n}());' - } + }, + // Configuration info for modules + // Note: Further info can be found here - http://requirejs.org/docs/api.html#config-moduleconfig + 'config': {} }) ``` @@ -723,6 +726,10 @@ __I don't like the way AMDclean normalizes the names of my modules with undersco - You sure can. You can either use the `prefixMode` and change it to camelCase, or you can override all of the logic with your own logic by using the `prefixTransform` option hook. +__Require.js supports passing module information, to one or more modules, with the `config` option. Does AMDclean support this?__ + +- Yes! Make sure to set the AMDclean `config` option with whatever module information you would like available to you in your modules. Check the Require.js website for more details: http://requirejs.org/docs/api.html#config-moduleconfig + __I can't seem to get AMDclean 2.0 to work. What gives?__ diff --git a/build/amdclean.js b/build/amdclean.js index 741cbf0..cc12261 100644 --- a/build/amdclean.js +++ b/build/amdclean.js @@ -1,4 +1,4 @@ -/*! amdclean - v2.2.8 - 2014-10-02 +/*! amdclean - v2.3.0 - 2014-10-08 * http://gregfranko.com/amdclean * Copyright (c) 2014 Greg Franko */ @@ -96,7 +96,10 @@ _defaultOptions_ = { 'end': '\n}());' }, // Determines if certain aggressive file size optimization techniques will be used to transform the soure code - 'aggressiveOptimizations': false + 'aggressiveOptimizations': false, + // Configuration info for modules + // Note: Further info can be found here - http://requirejs.org/docs/api.html#config-moduleconfig + 'config': {} }; // errorMsgs.js // ============ @@ -379,7 +382,7 @@ convertToIIFE = function convertToIIFE(obj) { // Returns a function expression that is executed immediately // e.g. var example = function(){}() convertToIIFEDeclaration = function convertToIIFEDeclaration(obj) { - var moduleName = obj.moduleName, callbackFuncParams = obj.callbackFuncParams, isOptimized = obj.isOptimized, callback = obj.callbackFunc, node = obj.node, name = callback.name, type = callback.type, range = node.range || defaultValues.defaultRange, loc = node.loc || defaultValues.defaultLOC, callbackFunc = function () { + var amdclean = this, options = amdclean.options, moduleId = obj.moduleId, moduleName = obj.moduleName, hasModuleParam = obj.hasModuleParam, hasExportsParam = obj.hasExportsParam, callbackFuncParams = obj.callbackFuncParams, isOptimized = obj.isOptimized, callback = obj.callbackFunc, node = obj.node, name = callback.name, type = callback.type, range = node.range || defaultValues.defaultRange, loc = node.loc || defaultValues.defaultLOC, callbackFunc = function () { var cbFunc = obj.callbackFunc; if (type === 'Identifier' && name !== 'undefined') { cbFunc = { @@ -454,7 +457,40 @@ convertToIIFEDeclaration = function convertToIIFEDeclaration(obj) { }; } return cbFunc; - }(), dependencyNames = obj.dependencyNames, cb = function () { + }(), dependencyNames = function () { + var depNames = obj.dependencyNames, objExpression = { + 'type': 'ObjectExpression', + 'properties': [], + 'range': range, + 'loc': loc + }, configMemberExpression = { + 'type': 'MemberExpression', + 'computed': false, + 'object': { + 'type': 'Identifier', + 'name': 'module' + }, + 'property': { + 'type': 'Identifier', + 'name': moduleId + } + }, moduleDepIndex; + if (options.config && options.config[moduleId]) { + if (hasExportsParam && hasModuleParam) { + return [ + objExpression, + objExpression, + configMemberExpression + ]; + } else if (hasModuleParam) { + moduleDepIndex = _.findIndex(depNames, function (currentDep) { + return currentDep.name === '{}'; + }); + depNames[moduleDepIndex] = configMemberExpression; + } + } + return depNames; + }(), cb = function () { if (callbackFunc.type === 'Literal' || callbackFunc.type === 'Identifier' && callbackFunc.name === 'undefined' || isOptimized === true) { return callbackFunc; } else { @@ -641,6 +677,9 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { }(), originalCallbackFuncParams, hasExportsParam = function () { var cbParams = callbackFunc.params || []; return _.where(cbParams, { 'name': 'exports' }).length; + }(), hasModuleParam = function () { + var cbParams = callbackFunc.params || []; + return _.where(cbParams, { 'name': 'module' }).length; }(), normalizeDependencyNames = {}, dependencyNames = function () { var deps = [], currentName; _.each(dependencies, function (currentDependency) { @@ -827,9 +866,11 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { }); if (isDefine) { return convertToIIFEDeclaration.call(amdclean, { + 'moduleId': moduleId, 'moduleName': moduleName, 'dependencyNames': dependencyNames, 'callbackFuncParams': callbackFuncParams, + 'hasModuleParam': hasModuleParam, 'hasExportsParam': hasExportsParam, 'callbackFunc': callbackFunc, 'isOptimized': isOptimized, @@ -1237,7 +1278,7 @@ generateCode = function generateCode(ast) { // ======== // Removes any AMD and/or CommonJS trace from the provided source code clean = function clean() { - var amdclean = this, options = amdclean.options, ignoreModules = options.ignoreModules, originalAst = {}, ast = {}, generatedCode, declarations = [], hoistedVariables = {}, hoistedCallbackParameters = {}, defaultRange = defaultValues.defaultRange, defaultLOC = defaultValues.defaultLOC; + var amdclean = this, options = amdclean.options, ignoreModules = options.ignoreModules, originalAst = {}, ast = {}, configAst = {}, generatedCode, declarations = [], hoistedVariables = {}, hoistedCallbackParameters = {}, defaultRange = defaultValues.defaultRange, defaultLOC = defaultValues.defaultLOC; // Creates and stores an AST representation of the code originalAst = createAst.call(amdclean); // Loops through the AST, finds all module ids, and stores them in the current instance storedModules property @@ -1422,6 +1463,58 @@ clean = function clean() { }); } }); + // Adds a local module variable if a user wants local module information available to them + if (_.isObject(options.config) && !_.isEmpty(options.config)) { + configAst = function () { + var props = []; + _.each(options.config, function (val, key) { + var currentModuleConfig = options.config[key]; + props.push({ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': key + }, + 'value': { + 'type': 'ObjectExpression', + 'properties': [{ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': 'config' + }, + 'value': { + 'type': 'FunctionExpression', + 'id': null, + 'params': [], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [{ + 'type': 'ReturnStatement', + 'argument': createAst.call(amdclean, 'var x =' + JSON.stringify(currentModuleConfig)).body[0].declarations[0].init + }] + } + }, + 'kind': 'init' + }] + } + }); + }); + return { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': 'module' + }, + 'init': { + 'type': 'ObjectExpression', + 'properties': props + } + }; + }(); + declarations.push(configAst); + } // If there are declarations, the declarations are preprended to the beginning of the code block if (declarations.length) { ast.body.unshift({ @@ -1570,7 +1663,7 @@ clean = function clean() { // The object that is publicly accessible publicAPI = { // Current project version number - 'VERSION': '2.2.8', + 'VERSION': '2.3.0', 'clean': function (options, overloadedOptions) { // Creates a new AMDclean instance var amdclean = new AMDclean(options, overloadedOptions), cleanedCode = amdclean.clean(); diff --git a/build/amdclean.min.js b/build/amdclean.min.js index 3a1b47b..9d05ac4 100644 --- a/build/amdclean.min.js +++ b/build/amdclean.min.js @@ -1,4 +1,4 @@ -/*! amdclean - v2.2.8 - 2014-10-02 +/*! amdclean - v2.3.0 - 2014-10-08 * http://gregfranko.com/amdclean * Copyright (c) 2014 Greg Franko */ @@ -26,4 +26,4 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -!function(){var esprima,estraverse,escodegen,_,errorMsgs,defaultValues,utils,convertToIIFE,convertToIIFEDeclaration,normalizeModuleName,convertToFunctionExpression,convertToObjectDeclaration,createAst,convertDefinesAndRequires,traverseAndUpdateAst,getNormalizedModuleName,findAndStoreAllModuleIds,generateCode,clean,_defaultOptions_;_defaultOptions_={code:"",filePath:"",globalModules:[],esprima:{comment:!0,loc:!0,range:!0,tokens:!0},escodegen:{comment:!0,format:{indent:{style:" ",adjustMultilineComment:!0}}},commentCleanName:"amdclean",ignoreModules:[],removeModules:[],removeAllRequires:!1,removeUseStricts:!0,transformAMDChecks:!0,createAnonymousAMDModule:!1,shimOverrides:{},prefixMode:"standard",prefixTransform:function(e){return e},wrap:{start:";(function() {\n",end:"\n}());"},aggressiveOptimizations:!1},errorMsgs={emptyCode:"There is no code to generate the AST with",emptyAst:function(e){return"An AST is not being passed to the "+e+"() method"},invalidObject:function(e){return"An object is not being passed as the first parameter to the "+e+"() method"},lodash:"Make sure you have included lodash (https://github.com/lodash/lodash).",esprima:"Make sure you have included esprima (https://github.com/ariya/esprima).",estraverse:"Make sure you have included estraverse (https://github.com/Constellation/estraverse).",escodegen:"Make sure you have included escodegen (https://github.com/Constellation/escodegen)."},defaultValues={dependencyBlacklist:{require:"remove",exports:!0,module:"remove"},defaultLOC:{start:{line:0,column:0}},defaultRange:[0,0]},utils=function(){var Utils={isDefine:function(e){var n=e.expression||{},t=n.callee;return _.isObject(e)&&"ExpressionStatement"===e.type&&n&&"CallExpression"===n.type&&"Identifier"===t.type&&"define"===t.name},isRequire:function(e){var n=e.expression||{},t=n.callee;return e&&"ExpressionStatement"===e.type&&n&&"CallExpression"===n.type&&"Identifier"===t.type&&"require"===t.name},isModuleExports:function(e){return e?"AssignmentExpression"===e.type&&e.left&&"MemberExpression"===e.left.type&&e.left.object&&"Identifier"===e.left.object.type&&"module"===e.left.object.name&&e.left.property&&"Identifier"===e.left.property.type&&"exports"===e.left.property.name:!1},isRequireExpression:function(e){return e&&"CallExpression"===e.type&&e.callee&&"require"===e.callee.name},isObjectExpression:function(e){return e&&e&&"ObjectExpression"===e.type},isFunctionExpression:function(e){return e&&e&&"FunctionExpression"===e.type},isFunctionCallExpression:function(e){return e&&e&&"CallExpression"===e.type&&e.callee&&"FunctionExpression"===e.callee.type},isUseStrict:function(e){return e&&e&&"use strict"===e.value&&"Literal"===e.type},isIfStatement:function(e){return e&&"IfStatement"===e.type&&e.test},isAMDConditional:function(e){if(!Utils.isIfStatement(e))return!1;var n={left:{operator:"typeof",argument:{type:"Identifier",name:"define"}},right:{type:"Literal",value:"function"}},t={left:n.right,right:n.left};try{return _.find(e.test,n)||_.find([e.test],n)||_.find(e.test,t)||_.find([e.test],t)||_.find(e.test.left||{},n)||_.find([e.test.left||{}],n)||_.find(e.test.left||{},t)||_.find([e.test.left||{}],t)}catch(r){return!1}},returnExpressionIdentifier:function(e){return{type:"ExpressionStatement",expression:{type:"Identifier",name:e,range:defaultValues.defaultRange,loc:defaultValues.defaultLOC},range:defaultValues.defaultRange,loc:defaultValues.defaultLOC}},readFile:function(e){if("undefined"!=typeof exports){var n=require("fs");return n.readFileSync(e,"utf8")}return""},isRelativeFilePath:function(e){var n=e.split("/");return-1!==n.length&&("."===n[0]||".."===n[0])},convertToCamelCase:function(e,n){return n=n||"_",e.replace(new RegExp(n+"(.)","g"),function(e,n){return n.toUpperCase()})},prefixReservedWords:function(name){var reservedWord=!1;try{name.length&&eval("var "+name+" = 1;")}catch(e){reservedWord=!0}return reservedWord===!0?"_"+name:name},normalizeDependencyName:function(e,n){if(!e||!n||!Utils.isRelativeFilePath(n))return n;var t=function(e){var n,t=e.split("/");return n=_.reduce(t,function(e,n){switch(n){case".":break;case"..":e.pop();break;default:e.push(n)}return e},[]),n.join("/")},r=function(e){var n=e.split("/");return n.pop(),n.join("/")};return t([r(e),n].join("/"))}};return Utils}(),convertToIIFE=function(e){var n=e.callbackFuncParams,t=e.callbackFunc,r=e.dependencyNames,a=e.node,o=a.range||defaultValues.defaultRange,s=a.loc||defaultValues.defaultLOC;return{type:"ExpressionStatement",expression:{type:"CallExpression",callee:{type:"FunctionExpression",id:null,params:n,defaults:[],body:t.body,rest:t.rest,generator:t.generator,expression:t.expression,range:o,loc:s},arguments:r,range:o,loc:s},range:o,loc:s}},convertToIIFEDeclaration=function(e){var n=e.moduleName,t=e.callbackFuncParams,r=e.isOptimized,a=e.callbackFunc,o=e.node,s=a.name,i=a.type,l=o.range||defaultValues.defaultRange,u=o.loc||defaultValues.defaultLOC,c=function(){var n=e.callbackFunc;return"Identifier"===i&&"undefined"!==s&&(n={type:"FunctionExpression",id:null,params:[],defaults:[],body:{type:"BlockStatement",body:[{type:"ReturnStatement",argument:{type:"ConditionalExpression",test:{type:"BinaryExpression",operator:"===",left:{type:"UnaryExpression",operator:"typeof",argument:{type:"Identifier",name:s,range:l,loc:u},prefix:!0,range:l,loc:u},right:{type:"Literal",value:"function",raw:"'function'",range:l,loc:u},range:l,loc:u},consequent:{type:"CallExpression",callee:{type:"Identifier",name:s,range:l,loc:u},arguments:t,range:l,loc:u},alternate:{type:"Identifier",name:s,range:l,loc:u},range:l,loc:u},range:l,loc:u}],range:l,loc:u},rest:null,generator:!1,expression:!1,range:l,loc:u}),n}(),d=e.dependencyNames,p=function(){return"Literal"===c.type||"Identifier"===c.type&&"undefined"===c.name||r===!0?c:{type:"CallExpression",callee:{type:"FunctionExpression",id:{type:"Identifier",name:"",range:l,loc:u},params:t,defaults:[],body:c.body,rest:c.rest,generator:c.generator,expression:c.expression,range:l,loc:u},arguments:d,range:l,loc:u}}(),m={type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:n,range:l,loc:u},right:p,range:l,loc:u},range:l,loc:u};return estraverse.replace(c,{enter:function(e){return utils.isModuleExports(e)?{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:"exports"},right:e.right}:e}}),m},normalizeModuleName=function(e){var n,t,r,a=this,o=a.options,s=o.prefixMode,i=o.prefixTransform,l=defaultValues.dependencyBlacklist;return e=e||"","{}"===e?"remove"===l[e]?"":e:(t=utils.prefixReservedWords(e.replace(/\./g,"").replace(/[^A-Za-z0-9_$]/g,"_").replace(/^_+/,"")),r="camelCase"===s?utils.convertToCamelCase(t):t,-1===o.ignoreModules.indexOf(r)&&a.variablesStore[r]&&(a.storedModules[r]=!1,r=function u(e){return a.variablesStore[e]?u("_"+e+"_"):e}(r),a.storedModules[r]=!0),_.isFunction(i)&&(n=i(r,e),_.isString(n)&&n.length)?n:r)},convertToFunctionExpression=function(e){var n,t,r,a=this,o=a.options,s=o.ignoreModules,i=e.node,l=e.isDefine,u=e.isRequire,c=!1,d=e.moduleName,p=e.moduleId,m=e.dependencies,f=m.length,g=o.aggressiveOptimizations,y=[],h=[],v=defaultValues.defaultRange,b=defaultValues.defaultLOC,x=e.range||v,E=e.loc||b,M=e.shouldOptimize,A=defaultValues.dependencyBlacklist,I=!1,O=function(){var n,t,r,s,i=e.moduleReturnValue;if(i&&"FunctionExpression"===i.type&&i.body&&_.isArray(i.body.body)&&i.body.body.length){if(n=_.filter(i.body.body,function(e){return o.removeUseStricts===!0?!utils.isUseStrict(e.expression):e}),t=_.where(n,{type:"ReturnStatement"}),y=_.where(n,{left:{type:"Identifier",name:"exports"}}),h=_.where(n,{left:{type:"MemberExpression",object:{type:"Identifier",name:"module"},property:{type:"Identifier",name:"exports"}}}),t.length){if(r=t[0],s=r.argument,I=function(){var e=!1;return _.each(i.params,function(n){var t=n.name;a.storedModules[t]||A[t]||(e=!0)}),e}(),I||!M||!utils.isFunctionExpression(r)&&n.length>1||s&&"Identifier"===s.type)return i;i=s,c=!0,i.params&&(f=i.params.length)}}else i&&"FunctionExpression"===i.type&&i.body&&_.isArray(i.body.body)&&0===i.body.body.length&&(i={type:"Identifier",name:"undefined",range:x,loc:E},f=0);return i}(),w=function(){var e=[];return O&&O.body&&_.isArray(O.body.body)&&(e=_.where(O.body.body,{type:"ReturnStatement"}),e.length)?!0:!1}(),R=function(){var e=O.params||[];return _.where(e,{name:"exports"}).length}(),j={},C=function(){var e,n=[];return _.each(m,function(t){e=normalizeModuleName.call(a,utils.normalizeDependencyName(p,t),p),j[e]=!0,n.push({type:"Identifier",name:e,range:v,loc:b})}),n}(),N=function z(e){e="_"+e+"_";var n=function(){var n=!1;return j[e]?n=!0:estraverse.traverse(O,{enter:function(t){"VariableDeclarator"===t.type&&t.id&&"Identifier"===t.id.type&&t.id.name===e&&(n=!0)}}),n}();return n?z(e):e},S=function(){var e=[];return R&&estraverse.traverse(O,{enter:function(n){var t,r;"VariableDeclarator"===n.type&&utils.isRequireExpression(n.init)&&n.id&&n.id.name&&n.init&&n.init.arguments&&n.init.arguments[0]&&n.init.arguments[0].value&&(t=n.id.name,r=normalizeModuleName.call(a,utils.normalizeDependencyName(p,n.init.arguments[0].value,p)),_.contains(s,r)||t!==r||e.push({originalName:r,newName:N(r),range:n.range||v,loc:n.loc||b}))}}),e}(),F=function(){var e=[];return _.each(S,function(n){e.push({type:"Identifier",name:n.newName?n.newName:n,range:n.range,loc:n.loc})}),e}(),V=function(){var e,t=[],r=_.union(O.params&&O.params.length?O.params:!M&&C&&C.length?C:[],F),o={};return _.each(r,function(n,r){e=n?n.name:C[r].name,M||"{}"===e?"{}"===e||R&&"remove"===defaultValues.dependencyBlacklist[e]||(t.push({type:"Identifier",name:e,range:v,loc:b}),c||g!==!0||a.storedModules[e]||!C[r]||(a.callbackParameterMap[C[r].name]?(o=_.where(a.callbackParameterMap[C[r].name],{name:e}),o.length?(o=o[0],o.count+=1):a.callbackParameterMap[C[r].name].push({name:e,count:1})):a.callbackParameterMap[C[r].name]=[{name:e,count:1}])):t.push({type:"Identifier",name:e,range:v,loc:b})}),n=t,_.filter(t||[],function(e){return g===!0&&M?!a.storedModules[e.name]:!0})}(),k=!w&&R,D=y.length||h.length;return C=_.filter(C||[],function(e,t){var r=n[t],o=e.name;return g===!0&&M?!r||a.storedModules[r.name]&&r.name===o?!a.storedModules[o]:!a.storedModules[r.name]:!0}),C=_.map(C||[],function(e){return A[e.name]&&(e.name="{}"),e}),t=C.length,r=V.length,t>r&&C.splice(r,t-r),k&&D&&O.body.body.push({type:"ReturnStatement",argument:{type:"Identifier",name:"exports",range:v,loc:b},range:v,loc:b}),estraverse.replace(O,{enter:function(e){var n,t;return utils.isRequireExpression(e)?e.arguments&&e.arguments[0]&&e.arguments[0].value?(n=normalizeModuleName.call(a,utils.normalizeDependencyName(p,e.arguments[0].value,p)),_.contains(s,n)?e:(_.where(S,{originalName:n}).length&&(t=_.where(S,{originalName:n})[0].newName),{type:"Identifier",name:t?t:n,range:e.range||v,loc:e.loc||b})):e:void 0}}),l?convertToIIFEDeclaration.call(a,{moduleName:d,dependencyNames:C,callbackFuncParams:V,hasExportsParam:R,callbackFunc:O,isOptimized:c,node:i}):u?convertToIIFE.call(a,{dependencyNames:C,callbackFuncParams:V,callbackFunc:O,node:i}):void 0},convertToObjectDeclaration=function(e,n){var t=e.node,r=defaultValues.defaultRange,a=defaultValues.defaultLOC,o=t.range||r,s=t.loc||a,i=e.moduleName,l=function(){var t,r,a,i,l,u;return"functionCallExpression"===n&&(t=e.moduleReturnValue,r=t.callee,a=r.params,a&&a.length&&_.isArray(a)&&_.where(a,{name:"global"})&&_.isObject(r.body)&&_.isArray(r.body.body)&&(i=_.where(r.body.body,{type:"ReturnStatement"})[0],_.isObject(i)&&_.isObject(i.argument)&&"FunctionExpression"===i.argument.type&&(u=i.argument,_.isObject(u.body)&&_.isArray(u.body.body)&&(l=_.where(u.body.body,{type:"ReturnStatement"})[0],_.isObject(l.argument)&&_.isObject(l.argument.right)&&_.isObject(l.argument.right.property)&&l.argument.right.property.name&&(t={type:"MemberExpression",computed:!1,object:{type:"Identifier",name:"window",range:o,loc:s},property:{type:"Identifier",name:l.argument.right.property.name,range:o,loc:s},range:o,loc:s}))))),t=t||e.moduleReturnValue}(),u={type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:i,range:o,loc:s},right:l,range:o,loc:s},range:o,loc:s};return u},createAst=function(e){var n=this,t=n.options,r=t.filePath,a=e||t.code||(r?utils.readFile(r):""),o=t.esprima;if(a){if(!_.isPlainObject(esprima)||!_.isFunction(esprima.parse))throw new Error(errorMsgs.esprima);return esprima.parse(a,o)}throw new Error(errorMsgs.emptyCode)},convertDefinesAndRequires=function(e,n){var t,r,a,o,s,i,l,u,c,d,p=this,m=p.options,f=utils.isDefine(e),g=utils.isRequire(e),y=!1,h="",v=defaultValues.defaultRange,b=defaultValues.defaultLOC,x=e.range||v,E=e.loc||b,M=defaultValues.dependencyBlacklist;if(l=f||g?e.expression.loc.start.line:e&&e.loc&&e.loc.start?e.loc.start.line:null,u=p.matchingCommentLineNumbers[l]||p.matchingCommentLineNumbers[l-1],utils.isAMDConditional(e)&&(estraverse.traverse(e,{enter:function(e){var n;utils.isDefine(e)&&e.expression&&e.expression.arguments&&e.expression.arguments.length&&"Literal"===e.expression.arguments[0].type&&e.expression.arguments[0].value&&(n=normalizeModuleName.call(p,e.expression.arguments[0].value),m.transformAMDChecks!==!0?p.conditionalModulesToIgnore[n]=!0:p.conditionalModulesToNotOptimize[n]=!0,m.createAnonymousAMDModule===!0&&(p.storedModules[n]=!1,e.expression.arguments.shift()))}}),!u&&m.transformAMDChecks===!0))return e.test={type:"Literal",value:!0,raw:"true",range:x,loc:E},e;if(!f&&!g)return"FunctionExpression"===e.type&&_.isArray(e.params)&&_.where(e.params,{type:"Identifier",name:"exports"}).length&&_.isObject(e.body)&&_.isArray(e.body.body)&&!_.where(e.body.body,{type:"ReturnStatement"}).length&&(c=function(){return n&&n.arguments&&n&&n.arguments&&n.arguments.length?_.where(n.arguments,{type:"FunctionExpression"}).length:!1}(),c&&e.body.body.unshift({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:"exports",range:v,loc:b},right:{type:"LogicalExpression",operator:"||",left:{type:"Identifier",name:"exports",range:v,loc:b},right:{type:"ObjectExpression",properties:[],range:v,loc:b},range:v,loc:b},range:v,loc:b},range:v,loc:b}),e.body.body.push({type:"ReturnStatement",argument:{type:"Identifier",name:"exports",range:v,loc:b},range:v,loc:b})),e;if(r=Array.prototype.slice.call(e.expression.arguments,0),o=g?r[1]:r[r.length-1],s=e.expression.arguments[0].value,t=normalizeModuleName.call(p,s),d=!p.conditionalModulesToNotOptimize[t],a=function(){var e,n=g?r[0]:r[r.length-2],t=[];return n=_.isPlainObject(n)?n.elements||[]:[],e=_.where(n,{value:"exports"}).length,_.isArray(n)&&n.length&&_.each(n,function(n){M[n.value]&&!d?t.push(n.value):"remove"!==M[n.value]?t.push(M[n.value]?"{}":n.value):e||t.push("{}")}),t}(),i={node:e,moduleName:t,moduleId:s,dependencies:a,moduleReturnValue:o,isDefine:f,isRequire:g,range:x,loc:E,shouldOptimize:d},f){if(u||!t||p.conditionalModulesToIgnore[t]===!0)return p.options.ignoreModules.push(t),e;if(_.contains(m.removeModules,t))return{type:"EmptyStatement"};if(_.isObject(m.shimOverrides)&&m.shimOverrides[s]?(i.moduleReturnValue=createAst.call(p,m.shimOverrides[s]),_.isArray(i.moduleReturnValue.body)&&_.isObject(i.moduleReturnValue.body[0])?_.isObject(i.moduleReturnValue.body[0].expression)&&(i.moduleReturnValue=i.moduleReturnValue.body[0].expression,h="objectExpression"):i.moduleReturnValue=o):i.moduleReturnValue&&"Identifier"===i.moduleReturnValue.type&&(h="functionExpression"),_.contains(m.ignoreModules,t))return e;if(utils.isFunctionExpression(o)||"functionExpression"===h)return convertToFunctionExpression.call(p,i);if(utils.isObjectExpression(o)||"objectExpression"===h)return convertToObjectDeclaration.call(p,i);if(utils.isFunctionCallExpression(o))return convertToObjectDeclaration.call(p,i,"functionCallExpression")}else if(g)return u?e:(y=_.isArray(e.expression.arguments)&&e.expression.arguments.length?e.expression.arguments[1]&&e.expression.arguments[1].body&&e.expression.arguments[1].body.body&&e.expression.arguments[1].body.body.length:!1,m.removeAllRequires!==!0&&y?convertToFunctionExpression.call(p,i):{type:"EmptyStatement",range:x,loc:E})},traverseAndUpdateAst=function(e){var n=this,t=n.options,r=e.ast;if(!_.isPlainObject(e))throw new Error(errorMsgs.invalidObject("traverseAndUpdateAst"));if(!r)throw new Error(errorMsgs.emptyAst("traverseAndUpdateAst"));if(!_.isPlainObject(estraverse)||!_.isFunction(estraverse.replace))throw new Error(errorMsgs.estraverse);return estraverse.replace(r,{enter:function(e,r){var a;return"Program"===e.type?(a=function(){var r=[];return n.comments=e.comments,_.each(e.comments,function(e){var n=e.value.trim();n===t.commentCleanName&&r.push(e)}),r}(),_.each(a,function(e){currentLineNumber=e.loc.start.line,n.matchingCommentLineNumbers[currentLineNumber]=!0}),e):convertDefinesAndRequires.call(n,e,r)},leave:function(e){return e}}),r},getNormalizedModuleName=function(e){if(utils.isDefine(e)){var n=this,t=e.expression.arguments[0].value,r=normalizeModuleName.call(n,t);return r}},findAndStoreAllModuleIds=function(e){var n=this;if(!e)throw new Error(errorMsgs.emptyAst("findAndStoreAllModuleIds"));if(!_.isPlainObject(estraverse)||!_.isFunction(estraverse.traverse))throw new Error(errorMsgs.estraverse);estraverse.traverse(e,{enter:function(e,t){var r=getNormalizedModuleName.call(n,e,t);r&&!n.storedModules[r]&&(n.storedModules[r]=!0),"ReturnStatement"===e.type&&e.argument&&e.argument.callee&&"define"===e.argument.callee.name&&(e.type="ExpressionStatement",e.expression=e.argument,delete e.argument),"VariableDeclarator"===e.type&&(n.variablesStore[e.id.name]=!0)}})},generateCode=function(e){var n=this,t=n.options,r=t.esprima||{},a=t.escodegen||{};if(!_.isPlainObject(escodegen)||!_.isFunction(escodegen.generate))throw new Error(errorMsgs.escodegen);if(r.comment===!0&&a.comment===!0)try{e=escodegen.attachComments(e,e.comments,e.tokens)}catch(o){}return escodegen.generate(e,a)},clean=function(){var e,n=this,t=n.options,r=t.ignoreModules,a={},o={},s=[],i={},l={},u=defaultValues.defaultRange,c=defaultValues.defaultLOC;return a=createAst.call(n),findAndStoreAllModuleIds.call(n,a),o=traverseAndUpdateAst.call(n,{ast:a}),o&&_.isArray(o.body)&&estraverse.replace(o,{enter:function(e,a){var o,s,i,l=e&&e.left&&e.left.name?e.left.name:"",d=e.right,p=[],m={},f=_.filter(n.callbackParameterMap[l],function(e){return e&&e.count>1}),g=[];if(void 0===e||"EmptyStatement"===e.type)_.each(a.body,function(e,n){(void 0===e||"EmptyStatement"===e.type)&&a.body.splice(n,1)});else{if(utils.isRequireExpression(e))return e.arguments&&e.arguments[0]&&e.arguments[0].value?(o=normalizeModuleName.call(n,e.arguments[0].value),-1===r.indexOf(o)?{type:"Identifier",name:o,range:e.range||u,loc:e.loc||c}:e):e;if(t.aggressiveOptimizations===!0&&"AssignmentExpression"===e.type&&l&&(i=_.map(d&&d.callee&&d.callee.params?d.callee.params:[],function(e){return e.name}),s=_.map(d.arguments,function(e){return e.name}),_.each(s,function(e){_.each(n.callbackParameterMap[e],function(e){var n=e.name,t=e.count;_.each(i,function(e,r){t>1&&n===e&&g.push(r)})})}),_.each(g,function(e){d.arguments.splice(e,e+1),d.callee.params.splice(e,e+1)}),n.callbackParameterMap[l]))return e.right=function(){return t.aggressiveOptimizations===!0&&f.length?(p=_.map(f,function(e,n){return{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:e.name,range:u,loc:c},right:n1&&(e=n.name,t[e]=!0)})}),t}(),i=_.merge(_.cloneDeep(_.reduce(n.storedModules,function(e,n,t){return n!==!1&&(e[t]=!0),e},{})),l),_.each(i,function(e,n){_.contains(t.ignoreModules,n)||s.push({type:"VariableDeclarator",id:{type:"Identifier",name:n,range:u,loc:c},init:null,range:u,loc:c})}),s.length&&o.body.unshift({type:"VariableDeclaration",declarations:s,kind:"var",range:u,loc:c}),e=generateCode.call(n,o),_.isObject(t.wrap)&&(_.isString(t.wrap.start)&&t.wrap.start.length&&(e=t.wrap.start+e),_.isString(t.wrap.end)&&t.wrap.end.length&&(e+=t.wrap.end)),e},function(e){!function(e,n){"function"==typeof define&&define.amd?(n.amd=!0,define(["esprima","estraverse","escodegen","underscore"],function(t,r,a,o){return n({esprima:t,estraverse:r,escodegen:a,underscore:o},e)})):"undefined"!=typeof exports?(n.commonjs=!0,module.exports=n(null,e)):e.amdclean=n(null,e)}(this,function n(t,r){esprima=function(){return n.amd&&t&&t.esprima&&t.esprima.parse?t.esprima:n.commonjs?require("esprima"):r&&r.esprima&&r.esprima.parse?r.esprima:void 0}(),estraverse=function(){return n.amd&&t&&t.estraverse&&t.estraverse.traverse?t.estraverse:n.commonjs?require("estraverse"):r&&r.estraverse&&r.estraverse.traverse?r.estraverse:void 0}(),escodegen=function(){return n.amd&&t&&t.escodegen&&t.escodegen.generate?t.escodegen:n.commonjs?require("escodegen"):r&&r.escodegen&&r.escodegen.generate?r.escodegen:void 0}(),_=function(){return n.amd&&t&&(t.underscore||t.lodash||t._)?t.underscore||t.lodash||t._:n.commonjs?require("lodash"):r&&r._?r._:void 0}();var a=function(e,n){if(!esprima)throw new Error(errorMsgs.esprima);if(!estraverse)throw new Error(errorMsgs.estraverse);if(!escodegen)throw new Error(errorMsgs.escodegen);if(!_)throw new Error(errorMsgs.lodash);var t=_.cloneDeep(this.defaultOptions||{}),r=e||n||{};!_.isPlainObject(e)&&_.isString(e)&&(r=_.merge({code:e},_.isObject(n)?n:{})),this.storedModules={},this.variablesStore={},this.originalAst={},this.callbackParameterMap={},this.conditionalModulesToIgnore={},this.conditionalModulesToNotOptimize={},this.matchingCommentLineNumbers={},this.comments=[],this.options=_.merge(t,r)},o={VERSION:"2.2.8",clean:function(e,n){var t=new a(e,n),r=t.clean();return r}};return a.prototype={clean:clean,defaultOptions:e},o})}(_defaultOptions_)}(); \ No newline at end of file +!function(){var esprima,estraverse,escodegen,_,errorMsgs,defaultValues,utils,convertToIIFE,convertToIIFEDeclaration,normalizeModuleName,convertToFunctionExpression,convertToObjectDeclaration,createAst,convertDefinesAndRequires,traverseAndUpdateAst,getNormalizedModuleName,findAndStoreAllModuleIds,generateCode,clean,_defaultOptions_;_defaultOptions_={code:"",filePath:"",globalModules:[],esprima:{comment:!0,loc:!0,range:!0,tokens:!0},escodegen:{comment:!0,format:{indent:{style:" ",adjustMultilineComment:!0}}},commentCleanName:"amdclean",ignoreModules:[],removeModules:[],removeAllRequires:!1,removeUseStricts:!0,transformAMDChecks:!0,createAnonymousAMDModule:!1,shimOverrides:{},prefixMode:"standard",prefixTransform:function(e){return e},wrap:{start:";(function() {\n",end:"\n}());"},aggressiveOptimizations:!1,config:{}},errorMsgs={emptyCode:"There is no code to generate the AST with",emptyAst:function(e){return"An AST is not being passed to the "+e+"() method"},invalidObject:function(e){return"An object is not being passed as the first parameter to the "+e+"() method"},lodash:"Make sure you have included lodash (https://github.com/lodash/lodash).",esprima:"Make sure you have included esprima (https://github.com/ariya/esprima).",estraverse:"Make sure you have included estraverse (https://github.com/Constellation/estraverse).",escodegen:"Make sure you have included escodegen (https://github.com/Constellation/escodegen)."},defaultValues={dependencyBlacklist:{require:"remove",exports:!0,module:"remove"},defaultLOC:{start:{line:0,column:0}},defaultRange:[0,0]},utils=function(){var Utils={isDefine:function(e){var t=e.expression||{},n=t.callee;return _.isObject(e)&&"ExpressionStatement"===e.type&&t&&"CallExpression"===t.type&&"Identifier"===n.type&&"define"===n.name},isRequire:function(e){var t=e.expression||{},n=t.callee;return e&&"ExpressionStatement"===e.type&&t&&"CallExpression"===t.type&&"Identifier"===n.type&&"require"===n.name},isModuleExports:function(e){return e?"AssignmentExpression"===e.type&&e.left&&"MemberExpression"===e.left.type&&e.left.object&&"Identifier"===e.left.object.type&&"module"===e.left.object.name&&e.left.property&&"Identifier"===e.left.property.type&&"exports"===e.left.property.name:!1},isRequireExpression:function(e){return e&&"CallExpression"===e.type&&e.callee&&"require"===e.callee.name},isObjectExpression:function(e){return e&&e&&"ObjectExpression"===e.type},isFunctionExpression:function(e){return e&&e&&"FunctionExpression"===e.type},isFunctionCallExpression:function(e){return e&&e&&"CallExpression"===e.type&&e.callee&&"FunctionExpression"===e.callee.type},isUseStrict:function(e){return e&&e&&"use strict"===e.value&&"Literal"===e.type},isIfStatement:function(e){return e&&"IfStatement"===e.type&&e.test},isAMDConditional:function(e){if(!Utils.isIfStatement(e))return!1;var t={left:{operator:"typeof",argument:{type:"Identifier",name:"define"}},right:{type:"Literal",value:"function"}},n={left:t.right,right:t.left};try{return _.find(e.test,t)||_.find([e.test],t)||_.find(e.test,n)||_.find([e.test],n)||_.find(e.test.left||{},t)||_.find([e.test.left||{}],t)||_.find(e.test.left||{},n)||_.find([e.test.left||{}],n)}catch(r){return!1}},returnExpressionIdentifier:function(e){return{type:"ExpressionStatement",expression:{type:"Identifier",name:e,range:defaultValues.defaultRange,loc:defaultValues.defaultLOC},range:defaultValues.defaultRange,loc:defaultValues.defaultLOC}},readFile:function(e){if("undefined"!=typeof exports){var t=require("fs");return t.readFileSync(e,"utf8")}return""},isRelativeFilePath:function(e){var t=e.split("/");return-1!==t.length&&("."===t[0]||".."===t[0])},convertToCamelCase:function(e,t){return t=t||"_",e.replace(new RegExp(t+"(.)","g"),function(e,t){return t.toUpperCase()})},prefixReservedWords:function(name){var reservedWord=!1;try{name.length&&eval("var "+name+" = 1;")}catch(e){reservedWord=!0}return reservedWord===!0?"_"+name:name},normalizeDependencyName:function(e,t){if(!e||!t||!Utils.isRelativeFilePath(t))return t;var n=function(e){var t,n=e.split("/");return t=_.reduce(n,function(e,t){switch(t){case".":break;case"..":e.pop();break;default:e.push(t)}return e},[]),t.join("/")},r=function(e){var t=e.split("/");return t.pop(),t.join("/")};return n([r(e),t].join("/"))}};return Utils}(),convertToIIFE=function(e){var t=e.callbackFuncParams,n=e.callbackFunc,r=e.dependencyNames,a=e.node,o=a.range||defaultValues.defaultRange,i=a.loc||defaultValues.defaultLOC;return{type:"ExpressionStatement",expression:{type:"CallExpression",callee:{type:"FunctionExpression",id:null,params:t,defaults:[],body:n.body,rest:n.rest,generator:n.generator,expression:n.expression,range:o,loc:i},arguments:r,range:o,loc:i},range:o,loc:i}},convertToIIFEDeclaration=function(e){var t=this,n=t.options,r=e.moduleId,a=e.moduleName,o=e.hasModuleParam,i=e.hasExportsParam,s=e.callbackFuncParams,l=e.isOptimized,u=e.callbackFunc,c=e.node,d=u.name,p=u.type,m=c.range||defaultValues.defaultRange,f=c.loc||defaultValues.defaultLOC,g=function(){var t=e.callbackFunc;return"Identifier"===p&&"undefined"!==d&&(t={type:"FunctionExpression",id:null,params:[],defaults:[],body:{type:"BlockStatement",body:[{type:"ReturnStatement",argument:{type:"ConditionalExpression",test:{type:"BinaryExpression",operator:"===",left:{type:"UnaryExpression",operator:"typeof",argument:{type:"Identifier",name:d,range:m,loc:f},prefix:!0,range:m,loc:f},right:{type:"Literal",value:"function",raw:"'function'",range:m,loc:f},range:m,loc:f},consequent:{type:"CallExpression",callee:{type:"Identifier",name:d,range:m,loc:f},arguments:s,range:m,loc:f},alternate:{type:"Identifier",name:d,range:m,loc:f},range:m,loc:f},range:m,loc:f}],range:m,loc:f},rest:null,generator:!1,expression:!1,range:m,loc:f}),t}(),y=function(){var t,a=e.dependencyNames,s={type:"ObjectExpression",properties:[],range:m,loc:f},l={type:"MemberExpression",computed:!1,object:{type:"Identifier",name:"module"},property:{type:"Identifier",name:r}};if(n.config&&n.config[r]){if(i&&o)return[s,s,l];o&&(t=_.findIndex(a,function(e){return"{}"===e.name}),a[t]=l)}return a}(),h=function(){return"Literal"===g.type||"Identifier"===g.type&&"undefined"===g.name||l===!0?g:{type:"CallExpression",callee:{type:"FunctionExpression",id:{type:"Identifier",name:"",range:m,loc:f},params:s,defaults:[],body:g.body,rest:g.rest,generator:g.generator,expression:g.expression,range:m,loc:f},arguments:y,range:m,loc:f}}(),v={type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:a,range:m,loc:f},right:h,range:m,loc:f},range:m,loc:f};return estraverse.replace(g,{enter:function(e){return utils.isModuleExports(e)?{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:"exports"},right:e.right}:e}}),v},normalizeModuleName=function(e){var t,n,r,a=this,o=a.options,i=o.prefixMode,s=o.prefixTransform,l=defaultValues.dependencyBlacklist;return e=e||"","{}"===e?"remove"===l[e]?"":e:(n=utils.prefixReservedWords(e.replace(/\./g,"").replace(/[^A-Za-z0-9_$]/g,"_").replace(/^_+/,"")),r="camelCase"===i?utils.convertToCamelCase(n):n,-1===o.ignoreModules.indexOf(r)&&a.variablesStore[r]&&(a.storedModules[r]=!1,r=function u(e){return a.variablesStore[e]?u("_"+e+"_"):e}(r),a.storedModules[r]=!0),_.isFunction(s)&&(t=s(r,e),_.isString(t)&&t.length)?t:r)},convertToFunctionExpression=function(e){var t,n,r,a=this,o=a.options,i=o.ignoreModules,s=e.node,l=e.isDefine,u=e.isRequire,c=!1,d=e.moduleName,p=e.moduleId,m=e.dependencies,f=m.length,g=o.aggressiveOptimizations,y=[],h=[],v=defaultValues.defaultRange,b=defaultValues.defaultLOC,x=e.range||v,E=e.loc||b,M=e.shouldOptimize,I=defaultValues.dependencyBlacklist,A=!1,O=function(){var t,n,r,i,s=e.moduleReturnValue;if(s&&"FunctionExpression"===s.type&&s.body&&_.isArray(s.body.body)&&s.body.body.length){if(t=_.filter(s.body.body,function(e){return o.removeUseStricts===!0?!utils.isUseStrict(e.expression):e}),n=_.where(t,{type:"ReturnStatement"}),y=_.where(t,{left:{type:"Identifier",name:"exports"}}),h=_.where(t,{left:{type:"MemberExpression",object:{type:"Identifier",name:"module"},property:{type:"Identifier",name:"exports"}}}),n.length){if(r=n[0],i=r.argument,A=function(){var e=!1;return _.each(s.params,function(t){var n=t.name;a.storedModules[n]||I[n]||(e=!0)}),e}(),A||!M||!utils.isFunctionExpression(r)&&t.length>1||i&&"Identifier"===i.type)return s;s=i,c=!0,s.params&&(f=s.params.length)}}else s&&"FunctionExpression"===s.type&&s.body&&_.isArray(s.body.body)&&0===s.body.body.length&&(s={type:"Identifier",name:"undefined",range:x,loc:E},f=0);return s}(),w=function(){var e=[];return O&&O.body&&_.isArray(O.body.body)&&(e=_.where(O.body.body,{type:"ReturnStatement"}),e.length)?!0:!1}(),j=function(){var e=O.params||[];return _.where(e,{name:"exports"}).length}(),R=function(){var e=O.params||[];return _.where(e,{name:"module"}).length}(),S={},N=function(){var e,t=[];return _.each(m,function(n){e=normalizeModuleName.call(a,utils.normalizeDependencyName(p,n),p),S[e]=!0,t.push({type:"Identifier",name:e,range:v,loc:b})}),t}(),C=function z(e){e="_"+e+"_";var t=function(){var t=!1;return S[e]?t=!0:estraverse.traverse(O,{enter:function(n){"VariableDeclarator"===n.type&&n.id&&"Identifier"===n.id.type&&n.id.name===e&&(t=!0)}}),t}();return t?z(e):e},F=function(){var e=[];return j&&estraverse.traverse(O,{enter:function(t){var n,r;"VariableDeclarator"===t.type&&utils.isRequireExpression(t.init)&&t.id&&t.id.name&&t.init&&t.init.arguments&&t.init.arguments[0]&&t.init.arguments[0].value&&(n=t.id.name,r=normalizeModuleName.call(a,utils.normalizeDependencyName(p,t.init.arguments[0].value,p)),_.contains(i,r)||n!==r||e.push({originalName:r,newName:C(r),range:t.range||v,loc:t.loc||b}))}}),e}(),V=function(){var e=[];return _.each(F,function(t){e.push({type:"Identifier",name:t.newName?t.newName:t,range:t.range,loc:t.loc})}),e}(),k=function(){var e,n=[],r=_.union(O.params&&O.params.length?O.params:!M&&N&&N.length?N:[],V),o={};return _.each(r,function(t,r){e=t?t.name:N[r].name,M||"{}"===e?"{}"===e||j&&"remove"===defaultValues.dependencyBlacklist[e]||(n.push({type:"Identifier",name:e,range:v,loc:b}),c||g!==!0||a.storedModules[e]||!N[r]||(a.callbackParameterMap[N[r].name]?(o=_.where(a.callbackParameterMap[N[r].name],{name:e}),o.length?(o=o[0],o.count+=1):a.callbackParameterMap[N[r].name].push({name:e,count:1})):a.callbackParameterMap[N[r].name]=[{name:e,count:1}])):n.push({type:"Identifier",name:e,range:v,loc:b})}),t=n,_.filter(n||[],function(e){return g===!0&&M?!a.storedModules[e.name]:!0})}(),D=!w&&j,P=y.length||h.length;return N=_.filter(N||[],function(e,n){var r=t[n],o=e.name;return g===!0&&M?!r||a.storedModules[r.name]&&r.name===o?!a.storedModules[o]:!a.storedModules[r.name]:!0}),N=_.map(N||[],function(e){return I[e.name]&&(e.name="{}"),e}),n=N.length,r=k.length,n>r&&N.splice(r,n-r),D&&P&&O.body.body.push({type:"ReturnStatement",argument:{type:"Identifier",name:"exports",range:v,loc:b},range:v,loc:b}),estraverse.replace(O,{enter:function(e){var t,n;return utils.isRequireExpression(e)?e.arguments&&e.arguments[0]&&e.arguments[0].value?(t=normalizeModuleName.call(a,utils.normalizeDependencyName(p,e.arguments[0].value,p)),_.contains(i,t)?e:(_.where(F,{originalName:t}).length&&(n=_.where(F,{originalName:t})[0].newName),{type:"Identifier",name:n?n:t,range:e.range||v,loc:e.loc||b})):e:void 0}}),l?convertToIIFEDeclaration.call(a,{moduleId:p,moduleName:d,dependencyNames:N,callbackFuncParams:k,hasModuleParam:R,hasExportsParam:j,callbackFunc:O,isOptimized:c,node:s}):u?convertToIIFE.call(a,{dependencyNames:N,callbackFuncParams:k,callbackFunc:O,node:s}):void 0},convertToObjectDeclaration=function(e,t){var n=e.node,r=defaultValues.defaultRange,a=defaultValues.defaultLOC,o=n.range||r,i=n.loc||a,s=e.moduleName,l=function(){var n,r,a,s,l,u;return"functionCallExpression"===t&&(n=e.moduleReturnValue,r=n.callee,a=r.params,a&&a.length&&_.isArray(a)&&_.where(a,{name:"global"})&&_.isObject(r.body)&&_.isArray(r.body.body)&&(s=_.where(r.body.body,{type:"ReturnStatement"})[0],_.isObject(s)&&_.isObject(s.argument)&&"FunctionExpression"===s.argument.type&&(u=s.argument,_.isObject(u.body)&&_.isArray(u.body.body)&&(l=_.where(u.body.body,{type:"ReturnStatement"})[0],_.isObject(l.argument)&&_.isObject(l.argument.right)&&_.isObject(l.argument.right.property)&&l.argument.right.property.name&&(n={type:"MemberExpression",computed:!1,object:{type:"Identifier",name:"window",range:o,loc:i},property:{type:"Identifier",name:l.argument.right.property.name,range:o,loc:i},range:o,loc:i}))))),n=n||e.moduleReturnValue}(),u={type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:s,range:o,loc:i},right:l,range:o,loc:i},range:o,loc:i};return u},createAst=function(e){var t=this,n=t.options,r=n.filePath,a=e||n.code||(r?utils.readFile(r):""),o=n.esprima;if(a){if(!_.isPlainObject(esprima)||!_.isFunction(esprima.parse))throw new Error(errorMsgs.esprima);return esprima.parse(a,o)}throw new Error(errorMsgs.emptyCode)},convertDefinesAndRequires=function(e,t){var n,r,a,o,i,s,l,u,c,d,p=this,m=p.options,f=utils.isDefine(e),g=utils.isRequire(e),y=!1,h="",v=defaultValues.defaultRange,b=defaultValues.defaultLOC,x=e.range||v,E=e.loc||b,M=defaultValues.dependencyBlacklist;if(l=f||g?e.expression.loc.start.line:e&&e.loc&&e.loc.start?e.loc.start.line:null,u=p.matchingCommentLineNumbers[l]||p.matchingCommentLineNumbers[l-1],utils.isAMDConditional(e)&&(estraverse.traverse(e,{enter:function(e){var t;utils.isDefine(e)&&e.expression&&e.expression.arguments&&e.expression.arguments.length&&"Literal"===e.expression.arguments[0].type&&e.expression.arguments[0].value&&(t=normalizeModuleName.call(p,e.expression.arguments[0].value),m.transformAMDChecks!==!0?p.conditionalModulesToIgnore[t]=!0:p.conditionalModulesToNotOptimize[t]=!0,m.createAnonymousAMDModule===!0&&(p.storedModules[t]=!1,e.expression.arguments.shift()))}}),!u&&m.transformAMDChecks===!0))return e.test={type:"Literal",value:!0,raw:"true",range:x,loc:E},e;if(!f&&!g)return"FunctionExpression"===e.type&&_.isArray(e.params)&&_.where(e.params,{type:"Identifier",name:"exports"}).length&&_.isObject(e.body)&&_.isArray(e.body.body)&&!_.where(e.body.body,{type:"ReturnStatement"}).length&&(c=function(){return t&&t.arguments&&t&&t.arguments&&t.arguments.length?_.where(t.arguments,{type:"FunctionExpression"}).length:!1}(),c&&e.body.body.unshift({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:"exports",range:v,loc:b},right:{type:"LogicalExpression",operator:"||",left:{type:"Identifier",name:"exports",range:v,loc:b},right:{type:"ObjectExpression",properties:[],range:v,loc:b},range:v,loc:b},range:v,loc:b},range:v,loc:b}),e.body.body.push({type:"ReturnStatement",argument:{type:"Identifier",name:"exports",range:v,loc:b},range:v,loc:b})),e;if(r=Array.prototype.slice.call(e.expression.arguments,0),o=g?r[1]:r[r.length-1],i=e.expression.arguments[0].value,n=normalizeModuleName.call(p,i),d=!p.conditionalModulesToNotOptimize[n],a=function(){var e,t=g?r[0]:r[r.length-2],n=[];return t=_.isPlainObject(t)?t.elements||[]:[],e=_.where(t,{value:"exports"}).length,_.isArray(t)&&t.length&&_.each(t,function(t){M[t.value]&&!d?n.push(t.value):"remove"!==M[t.value]?n.push(M[t.value]?"{}":t.value):e||n.push("{}")}),n}(),s={node:e,moduleName:n,moduleId:i,dependencies:a,moduleReturnValue:o,isDefine:f,isRequire:g,range:x,loc:E,shouldOptimize:d},f){if(u||!n||p.conditionalModulesToIgnore[n]===!0)return p.options.ignoreModules.push(n),e;if(_.contains(m.removeModules,n))return{type:"EmptyStatement"};if(_.isObject(m.shimOverrides)&&m.shimOverrides[i]?(s.moduleReturnValue=createAst.call(p,m.shimOverrides[i]),_.isArray(s.moduleReturnValue.body)&&_.isObject(s.moduleReturnValue.body[0])?_.isObject(s.moduleReturnValue.body[0].expression)&&(s.moduleReturnValue=s.moduleReturnValue.body[0].expression,h="objectExpression"):s.moduleReturnValue=o):s.moduleReturnValue&&"Identifier"===s.moduleReturnValue.type&&(h="functionExpression"),_.contains(m.ignoreModules,n))return e;if(utils.isFunctionExpression(o)||"functionExpression"===h)return convertToFunctionExpression.call(p,s);if(utils.isObjectExpression(o)||"objectExpression"===h)return convertToObjectDeclaration.call(p,s);if(utils.isFunctionCallExpression(o))return convertToObjectDeclaration.call(p,s,"functionCallExpression")}else if(g)return u?e:(y=_.isArray(e.expression.arguments)&&e.expression.arguments.length?e.expression.arguments[1]&&e.expression.arguments[1].body&&e.expression.arguments[1].body.body&&e.expression.arguments[1].body.body.length:!1,m.removeAllRequires!==!0&&y?convertToFunctionExpression.call(p,s):{type:"EmptyStatement",range:x,loc:E})},traverseAndUpdateAst=function(e){var t=this,n=t.options,r=e.ast;if(!_.isPlainObject(e))throw new Error(errorMsgs.invalidObject("traverseAndUpdateAst"));if(!r)throw new Error(errorMsgs.emptyAst("traverseAndUpdateAst"));if(!_.isPlainObject(estraverse)||!_.isFunction(estraverse.replace))throw new Error(errorMsgs.estraverse);return estraverse.replace(r,{enter:function(e,r){var a;return"Program"===e.type?(a=function(){var r=[];return t.comments=e.comments,_.each(e.comments,function(e){var t=e.value.trim();t===n.commentCleanName&&r.push(e)}),r}(),_.each(a,function(e){currentLineNumber=e.loc.start.line,t.matchingCommentLineNumbers[currentLineNumber]=!0}),e):convertDefinesAndRequires.call(t,e,r)},leave:function(e){return e}}),r},getNormalizedModuleName=function(e){if(utils.isDefine(e)){var t=this,n=e.expression.arguments[0].value,r=normalizeModuleName.call(t,n);return r}},findAndStoreAllModuleIds=function(e){var t=this;if(!e)throw new Error(errorMsgs.emptyAst("findAndStoreAllModuleIds"));if(!_.isPlainObject(estraverse)||!_.isFunction(estraverse.traverse))throw new Error(errorMsgs.estraverse);estraverse.traverse(e,{enter:function(e,n){var r=getNormalizedModuleName.call(t,e,n);r&&!t.storedModules[r]&&(t.storedModules[r]=!0),"ReturnStatement"===e.type&&e.argument&&e.argument.callee&&"define"===e.argument.callee.name&&(e.type="ExpressionStatement",e.expression=e.argument,delete e.argument),"VariableDeclarator"===e.type&&(t.variablesStore[e.id.name]=!0)}})},generateCode=function(e){var t=this,n=t.options,r=n.esprima||{},a=n.escodegen||{};if(!_.isPlainObject(escodegen)||!_.isFunction(escodegen.generate))throw new Error(errorMsgs.escodegen);if(r.comment===!0&&a.comment===!0)try{e=escodegen.attachComments(e,e.comments,e.tokens)}catch(o){}return escodegen.generate(e,a)},clean=function(){var e,t=this,n=t.options,r=n.ignoreModules,a={},o={},i={},s=[],l={},u={},c=defaultValues.defaultRange,d=defaultValues.defaultLOC;return a=createAst.call(t),findAndStoreAllModuleIds.call(t,a),o=traverseAndUpdateAst.call(t,{ast:a}),o&&_.isArray(o.body)&&estraverse.replace(o,{enter:function(e,a){var o,i,s,l=e&&e.left&&e.left.name?e.left.name:"",u=e.right,p=[],m={},f=_.filter(t.callbackParameterMap[l],function(e){return e&&e.count>1}),g=[];if(void 0===e||"EmptyStatement"===e.type)_.each(a.body,function(e,t){(void 0===e||"EmptyStatement"===e.type)&&a.body.splice(t,1)});else{if(utils.isRequireExpression(e))return e.arguments&&e.arguments[0]&&e.arguments[0].value?(o=normalizeModuleName.call(t,e.arguments[0].value),-1===r.indexOf(o)?{type:"Identifier",name:o,range:e.range||c,loc:e.loc||d}:e):e;if(n.aggressiveOptimizations===!0&&"AssignmentExpression"===e.type&&l&&(s=_.map(u&&u.callee&&u.callee.params?u.callee.params:[],function(e){return e.name}),i=_.map(u.arguments,function(e){return e.name}),_.each(i,function(e){_.each(t.callbackParameterMap[e],function(e){var t=e.name,n=e.count;_.each(s,function(e,r){n>1&&t===e&&g.push(r)})})}),_.each(g,function(e){u.arguments.splice(e,e+1),u.callee.params.splice(e,e+1)}),t.callbackParameterMap[l]))return e.right=function(){return n.aggressiveOptimizations===!0&&f.length?(p=_.map(f,function(e,t){return{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:e.name,range:c,loc:d},right:t1&&(e=t.name,n[e]=!0)})}),n}(),l=_.merge(_.cloneDeep(_.reduce(t.storedModules,function(e,t,n){return t!==!1&&(e[n]=!0),e},{})),u),_.each(l,function(e,t){_.contains(n.ignoreModules,t)||s.push({type:"VariableDeclarator",id:{type:"Identifier",name:t,range:c,loc:d},init:null,range:c,loc:d})}),_.isObject(n.config)&&!_.isEmpty(n.config)&&(i=function(){var e=[];return _.each(n.config,function(r,a){var o=n.config[a];e.push({type:"Property",key:{type:"Literal",value:a},value:{type:"ObjectExpression",properties:[{type:"Property",key:{type:"Literal",value:"config"},value:{type:"FunctionExpression",id:null,params:[],defaults:[],body:{type:"BlockStatement",body:[{type:"ReturnStatement",argument:createAst.call(t,"var x ="+JSON.stringify(o)).body[0].declarations[0].init}]}},kind:"init"}]}})}),{type:"VariableDeclarator",id:{type:"Identifier",name:"module"},init:{type:"ObjectExpression",properties:e}}}(),s.push(i)),s.length&&o.body.unshift({type:"VariableDeclaration",declarations:s,kind:"var",range:c,loc:d}),e=generateCode.call(t,o),_.isObject(n.wrap)&&(_.isString(n.wrap.start)&&n.wrap.start.length&&(e=n.wrap.start+e),_.isString(n.wrap.end)&&n.wrap.end.length&&(e+=n.wrap.end)),e},function(e){!function(e,t){"function"==typeof define&&define.amd?(t.amd=!0,define(["esprima","estraverse","escodegen","underscore"],function(n,r,a,o){return t({esprima:n,estraverse:r,escodegen:a,underscore:o},e)})):"undefined"!=typeof exports?(t.commonjs=!0,module.exports=t(null,e)):e.amdclean=t(null,e)}(this,function t(n,r){esprima=function(){return t.amd&&n&&n.esprima&&n.esprima.parse?n.esprima:t.commonjs?require("esprima"):r&&r.esprima&&r.esprima.parse?r.esprima:void 0}(),estraverse=function(){return t.amd&&n&&n.estraverse&&n.estraverse.traverse?n.estraverse:t.commonjs?require("estraverse"):r&&r.estraverse&&r.estraverse.traverse?r.estraverse:void 0}(),escodegen=function(){return t.amd&&n&&n.escodegen&&n.escodegen.generate?n.escodegen:t.commonjs?require("escodegen"):r&&r.escodegen&&r.escodegen.generate?r.escodegen:void 0}(),_=function(){return t.amd&&n&&(n.underscore||n.lodash||n._)?n.underscore||n.lodash||n._:t.commonjs?require("lodash"):r&&r._?r._:void 0}();var a=function(e,t){if(!esprima)throw new Error(errorMsgs.esprima);if(!estraverse)throw new Error(errorMsgs.estraverse);if(!escodegen)throw new Error(errorMsgs.escodegen);if(!_)throw new Error(errorMsgs.lodash);var n=_.cloneDeep(this.defaultOptions||{}),r=e||t||{};!_.isPlainObject(e)&&_.isString(e)&&(r=_.merge({code:e},_.isObject(t)?t:{})),this.storedModules={},this.variablesStore={},this.originalAst={},this.callbackParameterMap={},this.conditionalModulesToIgnore={},this.conditionalModulesToNotOptimize={},this.matchingCommentLineNumbers={},this.comments=[],this.options=_.merge(n,r)},o={VERSION:"2.3.0",clean:function(e,t){var n=new a(e,t),r=n.clean();return r}};return a.prototype={clean:clean,defaultOptions:e},o})}(_defaultOptions_)}(); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 52bcd42..9e85047 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -38,7 +38,11 @@ var gulp = require('gulp'), headerText = '/*! amdclean - v' + packageJson.version + ' - ' + currentDate + '\n* http://gregfranko.com/amdclean' + '\n* Copyright (c) ' + currentYear + ' Greg Franko */\n', - error = false; + error = false, + cachedBuiltLibText = fs.readFileSync('./src/amdclean.js', 'utf8'); + revertFile = function() { + fs.writeFileSync('./src/amdclean.js', cachedBuiltLibText); + }; gulp.task('build', function(cb) { requirejs.optimize({ @@ -69,12 +73,14 @@ gulp.task('build', function(cb) { }); } catch (e) { error = true; + revertFile(); return '' + e; } }()), fullCode = headerText + licenseText + cleanedCode; if (error) { + revertFile(); console.log('Looks like there was an error building, stopping the build... ' + cleanedCode); return; } @@ -85,6 +91,7 @@ gulp.task('build', function(cb) { cb(); } }, function(err) { + revertFile(); console.log('Looks like there was an error building, stopping the build... '); return cb(err); // return error }); diff --git a/package.json b/package.json index 8ecd06f..af83e57 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "amdclean", - "version": "2.2.8", + "version": "2.3.0", "description": "A build tool that converts AMD code to standard JavaScript", "main": "./src/amdclean", "repository": { @@ -41,4 +41,4 @@ "node": ">= 0.8" }, "license": "MIT" -} +} \ No newline at end of file diff --git a/src/amdclean.js b/src/amdclean.js index 741cbf0..cc12261 100644 --- a/src/amdclean.js +++ b/src/amdclean.js @@ -1,4 +1,4 @@ -/*! amdclean - v2.2.8 - 2014-10-02 +/*! amdclean - v2.3.0 - 2014-10-08 * http://gregfranko.com/amdclean * Copyright (c) 2014 Greg Franko */ @@ -96,7 +96,10 @@ _defaultOptions_ = { 'end': '\n}());' }, // Determines if certain aggressive file size optimization techniques will be used to transform the soure code - 'aggressiveOptimizations': false + 'aggressiveOptimizations': false, + // Configuration info for modules + // Note: Further info can be found here - http://requirejs.org/docs/api.html#config-moduleconfig + 'config': {} }; // errorMsgs.js // ============ @@ -379,7 +382,7 @@ convertToIIFE = function convertToIIFE(obj) { // Returns a function expression that is executed immediately // e.g. var example = function(){}() convertToIIFEDeclaration = function convertToIIFEDeclaration(obj) { - var moduleName = obj.moduleName, callbackFuncParams = obj.callbackFuncParams, isOptimized = obj.isOptimized, callback = obj.callbackFunc, node = obj.node, name = callback.name, type = callback.type, range = node.range || defaultValues.defaultRange, loc = node.loc || defaultValues.defaultLOC, callbackFunc = function () { + var amdclean = this, options = amdclean.options, moduleId = obj.moduleId, moduleName = obj.moduleName, hasModuleParam = obj.hasModuleParam, hasExportsParam = obj.hasExportsParam, callbackFuncParams = obj.callbackFuncParams, isOptimized = obj.isOptimized, callback = obj.callbackFunc, node = obj.node, name = callback.name, type = callback.type, range = node.range || defaultValues.defaultRange, loc = node.loc || defaultValues.defaultLOC, callbackFunc = function () { var cbFunc = obj.callbackFunc; if (type === 'Identifier' && name !== 'undefined') { cbFunc = { @@ -454,7 +457,40 @@ convertToIIFEDeclaration = function convertToIIFEDeclaration(obj) { }; } return cbFunc; - }(), dependencyNames = obj.dependencyNames, cb = function () { + }(), dependencyNames = function () { + var depNames = obj.dependencyNames, objExpression = { + 'type': 'ObjectExpression', + 'properties': [], + 'range': range, + 'loc': loc + }, configMemberExpression = { + 'type': 'MemberExpression', + 'computed': false, + 'object': { + 'type': 'Identifier', + 'name': 'module' + }, + 'property': { + 'type': 'Identifier', + 'name': moduleId + } + }, moduleDepIndex; + if (options.config && options.config[moduleId]) { + if (hasExportsParam && hasModuleParam) { + return [ + objExpression, + objExpression, + configMemberExpression + ]; + } else if (hasModuleParam) { + moduleDepIndex = _.findIndex(depNames, function (currentDep) { + return currentDep.name === '{}'; + }); + depNames[moduleDepIndex] = configMemberExpression; + } + } + return depNames; + }(), cb = function () { if (callbackFunc.type === 'Literal' || callbackFunc.type === 'Identifier' && callbackFunc.name === 'undefined' || isOptimized === true) { return callbackFunc; } else { @@ -641,6 +677,9 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { }(), originalCallbackFuncParams, hasExportsParam = function () { var cbParams = callbackFunc.params || []; return _.where(cbParams, { 'name': 'exports' }).length; + }(), hasModuleParam = function () { + var cbParams = callbackFunc.params || []; + return _.where(cbParams, { 'name': 'module' }).length; }(), normalizeDependencyNames = {}, dependencyNames = function () { var deps = [], currentName; _.each(dependencies, function (currentDependency) { @@ -827,9 +866,11 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { }); if (isDefine) { return convertToIIFEDeclaration.call(amdclean, { + 'moduleId': moduleId, 'moduleName': moduleName, 'dependencyNames': dependencyNames, 'callbackFuncParams': callbackFuncParams, + 'hasModuleParam': hasModuleParam, 'hasExportsParam': hasExportsParam, 'callbackFunc': callbackFunc, 'isOptimized': isOptimized, @@ -1237,7 +1278,7 @@ generateCode = function generateCode(ast) { // ======== // Removes any AMD and/or CommonJS trace from the provided source code clean = function clean() { - var amdclean = this, options = amdclean.options, ignoreModules = options.ignoreModules, originalAst = {}, ast = {}, generatedCode, declarations = [], hoistedVariables = {}, hoistedCallbackParameters = {}, defaultRange = defaultValues.defaultRange, defaultLOC = defaultValues.defaultLOC; + var amdclean = this, options = amdclean.options, ignoreModules = options.ignoreModules, originalAst = {}, ast = {}, configAst = {}, generatedCode, declarations = [], hoistedVariables = {}, hoistedCallbackParameters = {}, defaultRange = defaultValues.defaultRange, defaultLOC = defaultValues.defaultLOC; // Creates and stores an AST representation of the code originalAst = createAst.call(amdclean); // Loops through the AST, finds all module ids, and stores them in the current instance storedModules property @@ -1422,6 +1463,58 @@ clean = function clean() { }); } }); + // Adds a local module variable if a user wants local module information available to them + if (_.isObject(options.config) && !_.isEmpty(options.config)) { + configAst = function () { + var props = []; + _.each(options.config, function (val, key) { + var currentModuleConfig = options.config[key]; + props.push({ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': key + }, + 'value': { + 'type': 'ObjectExpression', + 'properties': [{ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': 'config' + }, + 'value': { + 'type': 'FunctionExpression', + 'id': null, + 'params': [], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [{ + 'type': 'ReturnStatement', + 'argument': createAst.call(amdclean, 'var x =' + JSON.stringify(currentModuleConfig)).body[0].declarations[0].init + }] + } + }, + 'kind': 'init' + }] + } + }); + }); + return { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': 'module' + }, + 'init': { + 'type': 'ObjectExpression', + 'properties': props + } + }; + }(); + declarations.push(configAst); + } // If there are declarations, the declarations are preprended to the beginning of the code block if (declarations.length) { ast.body.unshift({ @@ -1570,7 +1663,7 @@ clean = function clean() { // The object that is publicly accessible publicAPI = { // Current project version number - 'VERSION': '2.2.8', + 'VERSION': '2.3.0', 'clean': function (options, overloadedOptions) { // Creates a new AMDclean instance var amdclean = new AMDclean(options, overloadedOptions), cleanedCode = amdclean.clean(); diff --git a/src/modules/clean.js b/src/modules/clean.js index d86139b..7037b5d 100644 --- a/src/modules/clean.js +++ b/src/modules/clean.js @@ -28,6 +28,7 @@ define([ ignoreModules = options.ignoreModules, originalAst = {}, ast = {}, + configAst = {}, generatedCode, declarations = [], hoistedVariables = {}, @@ -258,6 +259,63 @@ define([ } }); + // Adds a local module variable if a user wants local module information available to them + if (_.isObject(options.config) && !_.isEmpty(options.config)) { + configAst = (function() { + var props = []; + + _.each(options.config, function(val, key) { + var currentModuleConfig = options.config[key]; + + props.push({ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': key + }, + 'value': { + 'type': 'ObjectExpression', + 'properties': [{ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': 'config' + }, + 'value': { + 'type': 'FunctionExpression', + 'id': null, + 'params': [], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [{ + 'type': 'ReturnStatement', + 'argument': createAst.call(amdclean, 'var x =' + JSON.stringify(currentModuleConfig)).body[0].declarations[0].init + }] + } + }, + 'kind': 'init' + }] + } + }); + }); + + return { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': 'module' + }, + 'init': { + 'type': 'ObjectExpression', + 'properties': props + } + }; + }()); + + declarations.push(configAst); + } + // If there are declarations, the declarations are preprended to the beginning of the code block if (declarations.length) { ast.body.unshift({ diff --git a/src/modules/convertToFunctionExpression.js b/src/modules/convertToFunctionExpression.js index 14bb55c..04cff7f 100644 --- a/src/modules/convertToFunctionExpression.js +++ b/src/modules/convertToFunctionExpression.js @@ -148,6 +148,13 @@ define([ 'name': 'exports' }).length; }()), + hasModuleParam = (function() { + var cbParams = callbackFunc.params || []; + + return _.where(cbParams, { + 'name': 'module' + }).length; + }()), normalizeDependencyNames = {}, dependencyNames = (function() { var deps = [], @@ -386,9 +393,11 @@ define([ if (isDefine) { return convertToIIFEDeclaration.call(amdclean, { + 'moduleId': moduleId, 'moduleName': moduleName, 'dependencyNames': dependencyNames, 'callbackFuncParams': callbackFuncParams, + 'hasModuleParam': hasModuleParam, 'hasExportsParam': hasExportsParam, 'callbackFunc': callbackFunc, 'isOptimized': isOptimized, diff --git a/src/modules/convertToIIFEDeclaration.js b/src/modules/convertToIIFEDeclaration.js index 3e60c5e..8fb4b77 100644 --- a/src/modules/convertToIIFEDeclaration.js +++ b/src/modules/convertToIIFEDeclaration.js @@ -11,7 +11,12 @@ define([ defaultValues ) { return function convertToIIFEDeclaration(obj) { - var moduleName = obj.moduleName, + var amdclean = this, + options = amdclean.options, + moduleId = obj.moduleId, + moduleName = obj.moduleName, + hasModuleParam = obj.hasModuleParam, + hasExportsParam = obj.hasExportsParam, callbackFuncParams = obj.callbackFuncParams, isOptimized = obj.isOptimized, callback = obj.callbackFunc, @@ -97,7 +102,41 @@ define([ } return cbFunc; }()), - dependencyNames = obj.dependencyNames, + dependencyNames = (function() { + var depNames = obj.dependencyNames, + objExpression = { + 'type': 'ObjectExpression', + 'properties': [], + 'range': range, + 'loc': loc + }, + configMemberExpression = { + 'type': 'MemberExpression', + 'computed': false, + 'object': { + 'type': 'Identifier', + 'name': 'module' + }, + 'property': { + 'type': 'Identifier', + 'name': moduleId + } + }, + moduleDepIndex; + + if (options.config && options.config[moduleId]) { + if (hasExportsParam && hasModuleParam) { + return [objExpression, objExpression, configMemberExpression]; + } else if (hasModuleParam) { + moduleDepIndex = _.findIndex(depNames, function(currentDep) { + return currentDep.name === '{}'; + }); + depNames[moduleDepIndex] = configMemberExpression; + } + } + + return depNames; + }()), cb = (function() { if (callbackFunc.type === 'Literal' || (callbackFunc.type === 'Identifier' && callbackFunc.name === 'undefined') || isOptimized === true) { return callbackFunc; diff --git a/src/modules/defaultOptions.js b/src/modules/defaultOptions.js index f46910f..22bc010 100644 --- a/src/modules/defaultOptions.js +++ b/src/modules/defaultOptions.js @@ -65,5 +65,8 @@ define({ 'end': '\n}());' }, // Determines if certain aggressive file size optimization techniques will be used to transform the soure code - 'aggressiveOptimizations': false + 'aggressiveOptimizations': false, + // Configuration info for modules + // Note: Further info can be found here - http://requirejs.org/docs/api.html#config-moduleconfig + 'config': {} }); \ No newline at end of file diff --git a/src/modules/index.js b/src/modules/index.js index 968ad12..7116623 100644 --- a/src/modules/index.js +++ b/src/modules/index.js @@ -147,7 +147,7 @@ require([ // The object that is publicly accessible publicAPI = { // Current project version number - 'VERSION': '2.2.8', + 'VERSION': '2.3.0', 'clean': function(options, overloadedOptions) { // Creates a new AMDclean instance var amdclean = new AMDclean(options, overloadedOptions), diff --git a/test/specs/convert.js b/test/specs/convert.js index b81a41a..6f8b263 100644 --- a/test/specs/convert.js +++ b/test/specs/convert.js @@ -1,6 +1,6 @@ require('jasmine-only'); describe('amdclean specs', function() { - var amdclean = require('../../build/amdclean'), + var amdclean = require('../../src/amdclean'), requirejs = require('requirejs'), _ = require('lodash'), fs = require('fs'), @@ -752,13 +752,13 @@ describe('amdclean specs', function() { it('should correctly convert libraries that do define.amd checks in their AMD conditional', function() { var AMDcode = " if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {" + - "root._ = _;" + - "define(function() {" + - "return _;" + - "});" + + "root._ = _;" + + "define(function() {" + + "return _;" + + "});" + "}", - cleanedCode = amdclean.clean(AMDcode, defaultOptions), - standardJavaScript = "if(true){root._=_;define(function(){return _;});}"; + cleanedCode = amdclean.clean(AMDcode, defaultOptions), + standardJavaScript = "if(true){root._=_;define(function(){return _;});}"; expect(cleanedCode).toBe(standardJavaScript); }); @@ -813,4 +813,63 @@ describe('amdclean specs', function() { }); + describe('Require.js Compatibility', function() { + it('should support the Require.js config option with the simplified CJS format', function() { + var AMDcode = 'if (typeof define === "function" && define.amd) {' + + 'define("moment", function (require, exports, module) {' + + 'return moment;' + + '});' + + '}', + options = _.merge(_.cloneDeep(defaultOptions), { + 'config': { + 'moment': { + 'noGlobal': true + } + } + }), + cleanedCode = amdclean.clean(AMDcode, options), + standardJavaScript = "var moment,module={'moment':{'config':function(){return{'noGlobal':true};}}};if(true){moment=function (require,exports,module){return moment;}({},{},module.moment);}"; + + expect(cleanedCode).toBe(standardJavaScript); + }); + + it('should support the Require.js config option when the special module ID, "module", is passed', function() { + var AMDcode = 'if (typeof define === "function" && define.amd) {' + + 'define("moment", ["module"], function (module) {' + + 'return moment;' + + '});' + + '}', + options = _.merge(_.cloneDeep(defaultOptions), { + 'config': { + 'moment': { + 'noGlobal': true + } + } + }), + cleanedCode = amdclean.clean(AMDcode, options), + standardJavaScript = "var moment,module={'moment':{'config':function(){return{'noGlobal':true};}}};if(true){moment=function (module){return moment;}(module.moment);}"; + + expect(cleanedCode).toBe(standardJavaScript); + }); + + it('should support the Require.js config option when the special module ID, "module", is passed with more than one argument', function() { + var AMDcode = 'if (typeof define === "function" && define.amd) {' + + 'define("moment", ["test", "module"], function (test, module) {' + + 'return moment;' + + '});' + + '}', + options = _.merge(_.cloneDeep(defaultOptions), { + 'config': { + 'moment': { + 'noGlobal': true + } + } + }), + cleanedCode = amdclean.clean(AMDcode, options), + standardJavaScript = "var moment,module={'moment':{'config':function(){return{'noGlobal':true};}}};if(true){moment=function (test,module){return moment;}(test,module.moment);}"; + + expect(cleanedCode).toBe(standardJavaScript); + }); + }); + }); \ No newline at end of file