Skip to content
Browse files

fixes #56 #57 Disable global check in lazy modules, print info of unu…

…sed modules, suspicious globals and paths; version 1.9.6
  • Loading branch information...
1 parent cd23eec commit 6afe7412fb2f4aaa7c2910dc8456833261d916e0 @azproduction committed Nov 22, 2012
View
2 CHANGELOG.md
@@ -97,3 +97,5 @@
- Grunt.js integration section
- finally `lmd -v`
- `log` and `warn` are true by default
+ - global check of lazy modules is deisabled
+ - info of unused modules, suspicious globals and off-package modules paths
View
13 bin/lmd_actions/build.js
@@ -1,10 +1,10 @@
require('colors');
var fs = require('fs'),
+ path = require('path'),
cli = require(__dirname + '/../cli_messages.js'),
init = require(__dirname + '/init.js'),
create = require(__dirname + '/create.js'),
- common = require(__dirname + '/../../lib/lmd_common.js'),
lmdPackage = require(__dirname + '/../lmd_builder.js');
var optimist = require('optimist');
@@ -98,7 +98,7 @@ module.exports = function () {
argv.mixins = mixinBuilds;
}
- var lmdFile = cwd + '/.lmd/' + buildName + '.lmd.json';
+ var lmdFile = path.join(cwd, '.lmd', buildName + '.lmd.json');
var buildResult = new lmdPackage(lmdFile, argv),
buildConfig = buildResult.buildConfig;
@@ -110,13 +110,10 @@ module.exports = function () {
}
}
- var configDir = fs.realpathSync(lmdFile);
- configDir = configDir.split(common.PATH_SPLITTER);
- configDir.pop();
- configDir = configDir.join('/') + '/' + (buildConfig.root || "");
+ var configDir = path.join(path.dirname(fs.realpathSync(lmdFile)), buildConfig.root || "");
if (buildConfig.sourcemap) {
- buildResult.sourceMap.pipe(createWritableFile(configDir + buildConfig.sourcemap));
+ buildResult.sourceMap.pipe(createWritableFile(path.join(configDir, buildConfig.sourcemap)));
if (buildConfig.log && buildConfig.output) {
buildResult.sourceMap.on('end', function () {
@@ -126,7 +123,7 @@ module.exports = function () {
}
if (buildConfig.output && buildConfig.output) {
- buildResult.pipe(createWritableFile(configDir + buildConfig.output));
+ buildResult.pipe(createWritableFile(path.join(configDir, buildConfig.output)));
if (buildConfig.log) {
buildResult.log.pipe(process.stdout);
buildResult.on('end', function () {
View
5 bin/lmd_actions/create.js
@@ -1,6 +1,7 @@
require('colors');
var fs = require('fs'),
+ path = require('path'),
cli = require(__dirname + '/../cli_messages.js'),
init = require(__dirname + '/init.js'),
common = require(__dirname + '/../../lib/lmd_common.js');
@@ -33,7 +34,7 @@ function checkFile(cwd, name) {
if (isGoodFileName) {
return 'bad build name `' + name + '`';
}
- var lmdConfig = cwd + '/.lmd/' + name + '.lmd.json';
+ var lmdConfig = path.join(cwd, '.lmd', name + '.lmd.json');
if (fs.existsSync(lmdConfig)) {
if (fs.statSync(lmdConfig).isFile()) {
// already exists
@@ -65,7 +66,7 @@ function template(buildName, parentConfig, options) {
}
function createBuild(cwd, buildName, parentBuild, options) {
- var lmdConfig = cwd + '/.lmd/' + buildName + '.lmd.json',
+ var lmdConfig = path.join(cwd, '.lmd', buildName + '.lmd.json'),
parentConfig = parentBuild ? parentBuild + '.lmd.json' : null;
fs.writeFileSync(lmdConfig, template(buildName, parentConfig, options), 'utf8');
View
36 bin/lmd_actions/info.js
@@ -1,6 +1,7 @@
require('colors');
var fs = require('fs'),
+ path = require('path'),
cli = require(__dirname + '/../cli_messages.js'),
init = require(__dirname + '/init.js'),
create = require(__dirname + '/create.js'),
@@ -200,27 +201,10 @@ function printFlags(config, availableFlags) {
cli.ok('');
}
-function discoverModuleType(moduleName, modulesNames, globalsNames) {
- if (modulesNames.indexOf(moduleName) != -1) {
- return 'in-package';
- }
-
- if (globalsNames.indexOf(moduleName) != -1) {
- return 'global';
- }
-
- if (/\.[a-z]{1,3}$/.test(moduleName)) {
- return 'off-package?';
- }
-
- return 'global?';
-};
-
-function printModulePathsAndDepends(modules, deepModulesInfo, isDeepAnalytics) {
- modules = modules || {};
-
- var modulesNames = Object.keys(modules),
- globalsNames = Object.keys(common.GLOBALS);
+function printModulePathsAndDepends(config, deepModulesInfo, isDeepAnalytics) {
+ var modules = config.modules || {},
+ modulesNames = Object.keys(modules),
+ globalsNames = common.getGlobals(config);
if (!modulesNames.length) {
return;
@@ -241,7 +225,7 @@ function printModulePathsAndDepends(modules, deepModulesInfo, isDeepAnalytics) {
var depends = deepModulesInfo[name].depends;
if (depends.length) {
depends.forEach(function (name) {
- var moduleType = discoverModuleType(name, modulesNames, globalsNames);
+ var moduleType = common.discoverModuleType(name, modulesNames, globalsNames);
switch (moduleType) {
case 'in-package':
cli.ok(' +-' + name.toString().cyan);
@@ -330,14 +314,14 @@ module.exports = function () {
argv.mixins = mixinBuilds;
}
- var lmdFile = cwd + '/.lmd/' + buildName + '.lmd.json';
+ var lmdFile = path.join(cwd, '.lmd', buildName + '.lmd.json');
- var rawConfig = JSON.parse(fs.readFileSync(lmdFile)),
+ var rawConfig = common.readConfig(lmdFile),
flags = Object.keys(flagToOptionNameMap),
extraFlags = ["warn", "log", "pack", "lazy"],
config = assembleLmdConfig(lmdFile, flags, argv),
root = fs.realpathSync(cwd + '/.lmd/' + config.root),
- output = config.output ? (root + '/' + config.output) : 'STDOUT'.yellow,
+ output = config.output ? path.join(root, config.output) : 'STDOUT'.yellow,
sourcemap = config.sourcemap ? fs.realpathSync(root + '/' + config.sourcemap) : false,
www = config.www_root ? fs.realpathSync(cwd + '/.lmd/' + config.www_root + '/') : false;
@@ -357,7 +341,7 @@ module.exports = function () {
var deepModulesInfo = common.collectModulesInfo(config);
printModules(config, deepModulesInfo, sortOrder);
- printModulePathsAndDepends(config.modules, deepModulesInfo, isDeepAnalytics);
+ printModulePathsAndDepends(config, deepModulesInfo, isDeepAnalytics);
printFlags(config, flags.concat(extraFlags));
cli.ok('Paths'.white.bold.underline);
View
3 bin/lmd_actions/list.js
@@ -3,8 +3,7 @@ require('colors');
var fs = require('fs'),
cli = require(__dirname + '/../cli_messages.js'),
init = require(__dirname + '/init.js'),
- create = require(__dirname + '/create.js'),
- common = require(__dirname + '/../../lib/lmd_common.js');
+ create = require(__dirname + '/create.js');
function printHelp(errorMessage) {
var help = [
View
11 bin/lmd_actions/server.js
@@ -1,6 +1,7 @@
require('colors');
var fs = require('fs'),
+ path = require('path'),
cli = require(__dirname + '/../cli_messages.js'),
init = require(__dirname + '/init.js'),
create = require(__dirname + '/create.js'),
@@ -86,12 +87,12 @@ module.exports = function () {
return;
}
- var lmdFile = cwd + '/.lmd/' + buildName + '.lmd.json';
+ var lmdFile = path.join(cwd, '.lmd', buildName + '.lmd.json');
var config = assembleLmdConfig(lmdFile, Object.keys(flagToOptionNameMap)),
- logDir = cwd + '/.lmd/logs/',
- currentLogDir = logDir + buildName + '/',
- wwwDir = cwd + '/.lmd/' + config.www_root + '/';
+ logsDir = path.join(cwd, '.lmd/logs'),
+ currentLogDir = path.join(logsDir, buildName),
+ wwwDir = path.join(cwd, '.lmd', config.www_root);
if (!config.www_root) {
printHelp("Build configured without required parameter `www_root`");
@@ -103,7 +104,7 @@ module.exports = function () {
return;
}
- if (!ensureDirExists(logDir)) {
+ if (!ensureDirExists(logsDir)) {
return;
}
View
5 bin/lmd_actions/update.js
@@ -1,6 +1,7 @@
require('colors');
var fs = require('fs'),
+ path = require('path'),
cli = require(__dirname + '/../cli_messages.js'),
init = require(__dirname + '/init.js'),
create = require(__dirname + '/create.js'),
@@ -36,8 +37,8 @@ function template(json, options) {
}
function updateBuild(cwd, buildName, options) {
- var lmdConfig = cwd + '/.lmd/' + buildName + '.lmd.json',
- json = JSON.parse(fs.readFileSync(lmdConfig, 'utf8'));
+ var lmdConfig = path.join(cwd, '.lmd', buildName + '.lmd.json'),
+ json = common.readConfig(lmdConfig);
fs.writeFileSync(lmdConfig, template(json, options), 'utf8');
}
View
11 bin/lmd_actions/watch.js
@@ -1,6 +1,7 @@
require('colors');
var fs = require('fs'),
+ path = require('path'),
cli = require(__dirname + '/../cli_messages.js'),
init = require(__dirname + '/init.js'),
create = require(__dirname + '/create.js'),
@@ -32,14 +33,6 @@ function printHelp(errorMessage) {
cli.help(help, errorMessage);
}
-var createWritableFile = function (fileName) {
- return fs.createWriteStream(fileName, {
- flags: "w",
- encoding: "utf8",
- mode: 0666
- });
-};
-
module.exports = function () {
var cwd = process.cwd(),
status;
@@ -98,7 +91,7 @@ module.exports = function () {
argv.mixins = mixinBuilds;
}
- var lmdFile = cwd + '/.lmd/' + buildName + '.lmd.json';
+ var lmdFile = path.join(cwd, '.lmd', buildName + '.lmd.json');
var watchResult = new lmdPackage.watch(lmdFile, argv),
watchConfig = watchResult.watchConfig;
View
72 bin/lmd_builder.js
@@ -5,32 +5,18 @@
* @licence MIT
*/
-var JSHINT_CONFIG = {
- debug: true,
- eqnull: true,
- boss: true,
- loopfunc: true,
- evil: true,
- laxbreak: true,
- undef: true,
- nonew: true,
- maxerr: Infinity
-};
-
var fs = require('fs'),
Stream = require('stream'),
+ path = require('path'),
uglifyCompress = require("uglify-js"),
SourceMapGenerator = require('source-map').SourceMapGenerator,
colors = require('colors'),
parser = uglifyCompress.parser,
uglify = uglifyCompress.uglify,
- JsHint = require('jshint').JSHINT,
lmdCoverage = require(__dirname + '/../lib/coverage_apply.js'),
common = require(__dirname + '/../lib/lmd_common.js'),
assembleLmdConfig = common.assembleLmdConfig;
-var JSHINT_GLOBALS = common.GLOBALS;
-var CROSS_PLATFORM_PATH_SPLITTER = common.PATH_SPLITTER;
var LMD_JS_SRC_PATH = common.LMD_JS_SRC_PATH;
var LMD_PLUGINS = common.LMD_PLUGINS;
@@ -149,14 +135,10 @@ LmdBuilder.prototype.defaults = function (options) {
* Common init for LmdBuilder and LmdBuilder.watch
*/
LmdBuilder.prototype.init = function () {
-
var self = this;
- this.configDir = fs.realpathSync(this.configFile);
- this.configDir = this.configDir.split(CROSS_PLATFORM_PATH_SPLITTER);
+ this.configDir = path.dirname(this.configFile);
this.flagToOptionNameMap = LMD_PLUGINS;
- this.configDir.pop();
- this.configDir = this.configDir.join('/');
/**
* Build log
@@ -630,7 +612,7 @@ LmdBuilder.prototype.escape = function (file) {
* @returns {String}
*/
LmdBuilder.prototype.render = function (config, lmd_modules, lmd_main, pack, modules_options) {
- var lmd_js = fs.readFileSync(LMD_JS_SRC_PATH + 'lmd.js', 'utf8'),
+ var lmd_js = fs.readFileSync(path.join(LMD_JS_SRC_PATH, 'lmd.js'), 'utf8'),
result;
// Apply patch if LMD package in cache Mode
@@ -779,7 +761,7 @@ LmdBuilder.prototype.patchLmdSource = function (lmd_js, config) {
plugins.forEach(function (pluginName) {
// require once
if (config[flagName] && !pluginsRequireList[pluginName]) {
- pluginsCode += fs.readFileSync(LMD_JS_SRC_PATH + 'plugin/' + pluginName, 'utf8') + "\n\n";
+ pluginsCode += fs.readFileSync(path.join(LMD_JS_SRC_PATH, 'plugin', pluginName), 'utf8') + "\n\n";
pluginsRequireList[pluginName] = true;
}
});
@@ -805,7 +787,7 @@ LmdBuilder.prototype.patchLmdSource = function (lmd_js, config) {
match = lmd_js.match(includePattern);
if (match && match[1]) {
- patchContent = fs.readFileSync(LMD_JS_SRC_PATH + 'plugin/' + match[1], 'utf8');
+ patchContent = fs.readFileSync(path.join(LMD_JS_SRC_PATH, 'plugin', match[1]), 'utf8');
} else {
break;
}
@@ -900,8 +882,7 @@ LmdBuilder.prototype.fsWatch = function (config) {
},
rebuild = function (stat, filename) {
if (stat && filename) {
- filename = filename.split(CROSS_PLATFORM_PATH_SPLITTER).pop();
- log('info'.green + ': Change detected in ' + filename.toString().green + ' at ' + stat.mtime.toString().blue);
+ log('info'.green + ': Change detected in ' + path.basename(filename).toString().green + ' at ' + stat.mtime.toString().blue);
} else if (stat) {
log('info'.green + ': Change detected at ' + stat.mtime.toString().blue);
} else {
@@ -911,8 +892,8 @@ LmdBuilder.prototype.fsWatch = function (config) {
log(' Rebuilding...\n');
var buildResult = self.build(self.compileConfig(self.configFile, self.options)),
- lmdFile = self.configDir + '/' + config.root + '/' + config.output,
- lmdSourceMapFile = self.configDir + '/' + config.root + '/' + config.sourcemap;
+ lmdFile = path.join(self.configDir, config.root, config.output),
+ lmdSourceMapFile = path.join(self.configDir, config.root, config.sourcemap);
log('info'.green + ': Writing LMD Package to ' + config.output.green + '\n');
fs.writeFileSync(lmdFile, buildResult.source, 'utf8');
@@ -1007,27 +988,6 @@ LmdBuilder.prototype.warn = function (text, isWarn) {
};
/**
- * Using JsHint, it checks for direct global vars access
- *
- * @param {String} moduleName
- * @param {String} moduleCode
- */
-LmdBuilder.prototype.checkForDirectGlobalsAccess = function (moduleName, moduleCode) {
- new JsHint(moduleCode, JSHINT_CONFIG, JSHINT_GLOBALS);
- var globalsObjects = [];
- for (var i = 0, c = JsHint.errors.length, error; i < c; i++) {
- error = JsHint.errors[i];
- if (error.raw === '\'{a}\' is not defined.') {
- if (globalsObjects.indexOf(error.a) === -1) {
- globalsObjects.push(error.a);
- }
- }
- }
-
- return globalsObjects;
-};
-
-/**
* Generates module token
*
* @param {String} modulePath
@@ -1075,10 +1035,10 @@ LmdBuilder.prototype.getModuleOffset = function (source, tokenIndex) {
* @return {Object} {source: cleanSource, sourceMap: sourceMap}
*/
LmdBuilder.prototype.createSourceMap = function (modules, sourceWithTokens, config) {
- var generatedFile = this.configDir + '/' + config.root + '/' + config.output,
- root = this.configDir + '/' + config.root + '/' + config.www_root,
+ var generatedFile = path.join(this.configDir, config.root, config.output),
+ root = path.join(this.configDir, config.root, config.www_root),
www = config.sourcemap_www,
- sourceMapFile = this.configDir + '/' + config.root + '/' + config.sourcemap,
+ sourceMapFile = path.join(this.configDir, config.root, config.sourcemap),
isInline = config.sourcemap_inline,
isWarn = config.warn;
@@ -1280,16 +1240,6 @@ LmdBuilder.prototype.build = function (config) {
moduleInfo.code = coverageResult.code;
}
- // #14 Check direct access of globals in lazy modules
- if (config.warn && module.is_lazy) {
- globalsObjects = this.checkForDirectGlobalsAccess(module.path, moduleInfo.code);
-
- if (globalsObjects.length) {
- this.warn("Lazy module **" + module.path.split('/').slice(-2).join('/') + "** uses some globals directly (" + globalsObjects.join(', ') + "). " +
- "Replace them with require('" + globalsObjects[0] + "') etc", config.warn);
- }
- }
-
if (module.is_lazy || pack) {
moduleInfo.code = this.compress(moduleInfo.code, config.pack_options);
}
View
3 bin/lmd_docs_generator.js
@@ -1,4 +1,5 @@
var fs = require('fs'),
+ path = require('path'),
common = require(__dirname + '/../lib/lmd_common.js');
/**
@@ -49,7 +50,7 @@ for (var flagName in LMD_PLUGINS) {
plugins.forEach(function (pluginName) {
// require once
if (!pluginsRequireList[pluginName]) {
- pluginsCode += fs.readFileSync(LMD_JS_SRC_PATH + 'plugin/' + pluginName, 'utf8') + "\n\n";
+ pluginsCode += fs.readFileSync(path.join(LMD_JS_SRC_PATH, 'plugin', pluginName), 'utf8') + "\n\n";
pluginsRequireList[pluginName] = true;
}
});
View
454 lib/lmd_common.js
@@ -1,52 +1,241 @@
var fs = require('fs'),
- fileExists = fs.existsSync || require('path').existsSync,
+ path = require('path'),
+ fileExists = fs.existsSync || path.existsSync,
uglifyCompress = require("uglify-js"),
parser = uglifyCompress.parser,
uglify = uglifyCompress.uglify;
require('colors');
-var PATH_SPLITTER = /\/|\\/;
var DEFAULT_DEPENDS_MASK = "*.lmd.json";
var MASTER_FIELDS = ['version', 'main', 'global', 'lazy', 'pack', 'pack_options', 'log', 'warn', 'mixins',
'output', 'path', 'root', "sourcemap", "sourcemap_inline", "sourcemap_www", "www_root"];
var INHERITABLE_FIELDS = ['version', 'main', 'global', 'lazy', 'pack', 'pack_options', 'log', 'warn', 'mixins'];
var FILED_ALIASES = {"path": "root"};
-var GLOBALS = {
- Array : 0,
- Boolean : 0,
- Date : 0,
- decodeURI : 0,
- decodeURIComponent : 0,
- encodeURI : 0,
- encodeURIComponent : 0,
- Error : 0,
- 'eval' : 0,
- EvalError : 0,
- Function : 0,
- hasOwnProperty : 0,
- isFinite : 0,
- isNaN : 0,
- JSON : 0,
- Math : 0,
- Number : 0,
- Object : 0,
- parseInt : 0,
- parseFloat : 0,
- RangeError : 0,
- ReferenceError : 0,
- RegExp : 0,
- String : 0,
- SyntaxError : 0,
- TypeError : 0,
- URIError : 0
+exports.GLOBALS = {
+ Array : 1,
+ Boolean : 1,
+ Date : 1,
+ decodeURI : 1,
+ decodeURIComponent : 1,
+ encodeURI : 1,
+ encodeURIComponent : 1,
+ Error : 1,
+ 'eval' : 1,
+ EvalError : 1,
+ Function : 1,
+ hasOwnProperty : 1,
+ isFinite : 1,
+ isNaN : 1,
+ JSON : 1,
+ Math : 1,
+ Number : 1,
+ Object : 1,
+ parseInt : 1,
+ parseFloat : 1,
+ RangeError : 1,
+ ReferenceError : 1,
+ RegExp : 1,
+ String : 1,
+ SyntaxError : 1,
+ TypeError : 1,
+ URIError : 1,
+ ArrayBuffer : 1,
+ ArrayBufferView : 1,
+ Audio : 1,
+ Blob : 1,
+ addEventListener : 1,
+ applicationCache : 1,
+ atob : 1,
+ blur : 1,
+ btoa : 1,
+ clearInterval : 1,
+ clearTimeout : 1,
+ close : 1,
+ closed : 1,
+ DataView : 1,
+ DOMParser : 1,
+ defaultStatus : 1,
+ document : 1,
+ Element : 1,
+ event : 1,
+ FileReader : 1,
+ Float32Array : 1,
+ Float64Array : 1,
+ FormData : 1,
+ focus : 1,
+ frames : 1,
+ getComputedStyle : 1,
+ HTMLElement : 1,
+ HTMLAnchorElement : 1,
+ HTMLBaseElement : 1,
+ HTMLBlockquoteElement: 1,
+ HTMLBodyElement : 1,
+ HTMLBRElement : 1,
+ HTMLButtonElement : 1,
+ HTMLCanvasElement : 1,
+ HTMLDirectoryElement : 1,
+ HTMLDivElement : 1,
+ HTMLDListElement : 1,
+ HTMLFieldSetElement : 1,
+ HTMLFontElement : 1,
+ HTMLFormElement : 1,
+ HTMLFrameElement : 1,
+ HTMLFrameSetElement : 1,
+ HTMLHeadElement : 1,
+ HTMLHeadingElement : 1,
+ HTMLHRElement : 1,
+ HTMLHtmlElement : 1,
+ HTMLIFrameElement : 1,
+ HTMLImageElement : 1,
+ HTMLInputElement : 1,
+ HTMLIsIndexElement : 1,
+ HTMLLabelElement : 1,
+ HTMLLayerElement : 1,
+ HTMLLegendElement : 1,
+ HTMLLIElement : 1,
+ HTMLLinkElement : 1,
+ HTMLMapElement : 1,
+ HTMLMenuElement : 1,
+ HTMLMetaElement : 1,
+ HTMLModElement : 1,
+ HTMLObjectElement : 1,
+ HTMLOListElement : 1,
+ HTMLOptGroupElement : 1,
+ HTMLOptionElement : 1,
+ HTMLParagraphElement : 1,
+ HTMLParamElement : 1,
+ HTMLPreElement : 1,
+ HTMLQuoteElement : 1,
+ HTMLScriptElement : 1,
+ HTMLSelectElement : 1,
+ HTMLStyleElement : 1,
+ HTMLTableCaptionElement: 1,
+ HTMLTableCellElement : 1,
+ HTMLTableColElement : 1,
+ HTMLTableElement : 1,
+ HTMLTableRowElement : 1,
+ HTMLTableSectionElement: 1,
+ HTMLTextAreaElement : 1,
+ HTMLTitleElement : 1,
+ HTMLUListElement : 1,
+ HTMLVideoElement : 1,
+ history : 1,
+ Int16Array : 1,
+ Int32Array : 1,
+ Int8Array : 1,
+ Image : 1,
+ length : 1,
+ localStorage : 1,
+ location : 1,
+ MessageChannel : 1,
+ MessageEvent : 1,
+ MessagePort : 1,
+ moveBy : 1,
+ moveTo : 1,
+ MutationObserver : 1,
+ name : 1,
+ Node : 1,
+ NodeFilter : 1,
+ navigator : 1,
+ onbeforeunload : 1,
+ onblur : 1,
+ onerror : 1,
+ onfocus : 1,
+ onload : 1,
+ onresize : 1,
+ onunload : 1,
+ open : 1,
+ openDatabase : 1,
+ opener : 1,
+ Option : 1,
+ parent : 1,
+ print : 1,
+ removeEventListener : 1,
+ resizeBy : 1,
+ resizeTo : 1,
+ screen : 1,
+ scroll : 1,
+ scrollBy : 1,
+ scrollTo : 1,
+ sessionStorage : 1,
+ setInterval : 1,
+ setTimeout : 1,
+ SharedWorker : 1,
+ status : 1,
+ top : 1,
+ Uint16Array : 1,
+ Uint32Array : 1,
+ Uint8Array : 1,
+ WebSocket : 1,
+ window : 1,
+ Worker : 1,
+ XMLHttpRequest : 1,
+ XMLSerializer : 1,
+ XPathEvaluator : 1,
+ XPathException : 1,
+ XPathExpression : 1,
+ XPathNamespace : 1,
+ XPathNSResolver : 1,
+ XPathResult : 1,
+ escape : 1,
+ unescape: 1,
+ alert : 1,
+ confirm: 1,
+ console: 1,
+ Debug : 1,
+ opera : 1,
+ prompt : 1
};
-var LMD_JS_SRC_PATH = __dirname + '/../src/';
+exports.WORKER_GLOBALS = {
+ importScripts: 1,
+ postMessage : 1,
+ self : 1
+};
+
+exports.NODE_GLOBALS = {
+ __filename : 1,
+ __dirname : 1,
+ Buffer : 1,
+ console : 1,
+ exports : 1,
+ GLOBAL : 1,
+ global : 1,
+ module : 1,
+ process : 1,
+ require : 1,
+ setTimeout : 1,
+ clearTimeout : 1,
+ setInterval : 1,
+ clearInterval: 1
+};
+
+exports.LMD_GLOBALS = {
+ exports: 1,
+ module: 1,
+ require: 1
+};
+
+
+// require() is Caches json files
+var readConfig = function (file/*, filePart, filePart*/) {
+ file = path.join.apply(path, arguments);
+
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
+};
+exports.readConfig = readConfig;
+
+
+var LMD_JS_SRC_PATH = path.join(__dirname, '../src');
+exports.LMD_JS_SRC_PATH = LMD_JS_SRC_PATH;
+
+
+var LMD_PLUGINS = readConfig(LMD_JS_SRC_PATH, 'lmd_plugins.json');
+exports.LMD_PLUGINS = LMD_PLUGINS;
-var LMD_PLUGINS = JSON.parse(fs.readFileSync(LMD_JS_SRC_PATH + 'lmd_plugins.json', 'utf8'))
/**
* Config files deep merge
@@ -66,6 +255,7 @@ var deepDestructableMerge = function (left, right) {
}
return left;
};
+exports.deepDestructableMerge = deepDestructableMerge;
/**
* Merges all config files in module's lineage
@@ -77,27 +267,25 @@ var tryExtend = function (config, configDir) {
if (typeof config.extends !== "string") {
return config;
}
- var parentConfig = tryExtend(JSON.parse(fs.readFileSync(configDir + '/' + config.extends, 'utf8')), configDir);
+
+ var parentConfig = tryExtend(readConfig(configDir, config.extends), configDir);
return deepDestructableMerge(parentConfig, config);
};
+exports.tryExtend = tryExtend;
/**
- * Extracts file path parameters
+ * Returns depends config file of this module
+ *
+ * @param {String} modulePath
+ * @param {String} dependsFileMask
*
- * @param file
+ * @return {String}
*/
-var extract = function (file) {
- file = file.split(PATH_SPLITTER);
- return {
- file: file.pop(),
- path: (file.length ? file.join('/') + '/' : '')
- };
-};
-
var getDependsConfigOf = function (modulePath, dependsFileMask) {
var fileName = modulePath.replace(/^.*\/|\.[a-z0-9]+$/g, '');
- return extract(modulePath).path + dependsFileMask.replace('*', fileName);
+
+ return path.join(path.dirname(modulePath), dependsFileMask.replace('*', fileName));
};
/**
@@ -183,13 +371,12 @@ var assembleLmdConfig = function (configFile, flagsNames, extraOptions, usedConf
var isFirstRun = typeof usedConfigs === "undefined";
usedConfigs = usedConfigs || {};
- var configDir = fs.realpathSync(configFile);
- usedConfigs[configDir] = true; // mark config as used
+ configFile = fs.realpathSync(configFile);
+ usedConfigs[configFile] = true; // mark config as used
+
+ var configDir = path.dirname(configFile);
- configDir = configDir.split(PATH_SPLITTER);
- configDir.pop();
- configDir = configDir.join('/');
- var rawConfig = JSON.parse(fs.readFileSync(configFile, 'utf8')),
+ var rawConfig = readConfig(configFile),
configs = [],
resultConfig = {
modules: {},
@@ -277,6 +464,7 @@ var assembleLmdConfig = function (configFile, flagsNames, extraOptions, usedConf
}
return resultConfig;
};
+exports.assembleLmdConfig = assembleLmdConfig;
function isCoverage(config, moduleName) {
if (!config.stats_coverage) {
@@ -328,14 +516,15 @@ var collectModules = function (config, configDir) {
modulePath,
moduleExports,
moduleRequire,
- descriptor,
+ moduleFileName,
+ moduleFilePath,
moduleDesciptor,
wildcardRegex,
moduleData,
- path = config.root || config.path || '';
+ modulesDirPath = config.root || config.path || '';
- if (path[0] !== '/') { // non-absolute
- path = configDir + '/' + path;
+ if (modulesDirPath[0] !== '/') { // non-absolute
+ modulesDirPath = path.join(configDir, modulesDirPath);
}
// grep paths
@@ -361,9 +550,11 @@ var collectModules = function (config, configDir) {
// its a wildcard
// "*": "*.js" or "*_pewpew": "*.ru.json" or "ololo": "*.js"
if (IS_HAS_WILD_CARD.test(modulePath)) {
- descriptor = extract(modulePath);
- wildcardRegex = new RegExp("^" + descriptor.file.replace(/\*/g, "(\\w+)") + "$");
- fs.readdirSync(path + descriptor.path).forEach(function (fileName) {
+ moduleFileName = path.basename(modulePath);
+ moduleFilePath = path.dirname(modulePath);
+
+ wildcardRegex = new RegExp("^" + moduleFileName.replace(/\*/g, "(\\w+)") + "$");
+ fs.readdirSync(path.join(modulesDirPath, moduleFilePath)).forEach(function (fileName) {
var match = fileName.match(wildcardRegex),
newModuleName;
@@ -378,8 +569,8 @@ var collectModules = function (config, configDir) {
moduleData = {
originalModuleDesciptor: moduleDesciptor,
name: newModuleName,
- path: fs.realpathSync(path + descriptor.path + fileName),
- originalPath: descriptor.path + fileName,
+ path: fs.realpathSync(path.join(modulesDirPath, moduleFilePath, fileName)),
+ originalPath: moduleFilePath + fileName,
lines: 0,
extra_exports: moduleExports,
extra_require: moduleRequire,
@@ -423,7 +614,7 @@ var collectModules = function (config, configDir) {
modules[moduleName] = {
originalModuleDesciptor: moduleDesciptor,
name: moduleName,
- path: fs.realpathSync(path + modulePath),
+ path: fs.realpathSync(path.join(modulesDirPath, modulePath)),
originalPath: modulePath,
lines: 0,
extra_exports: moduleExports,
@@ -441,6 +632,7 @@ var collectModules = function (config, configDir) {
return modules;
};
+exports.collectModules = collectModules;
var reapplyModuleOptions = function (config) {
var globalLazy = config.lazy || false,
@@ -480,6 +672,7 @@ var collectModulesInfo = function (config) {
return result;
};
+exports.collectModulesInfo = collectModulesInfo;
/**
* Wrapper for plain files
@@ -600,6 +793,7 @@ var wrapModule = function (code, moduleOptions, moduleType) {
return code;
};
+exports.wrapModule = wrapModule;
var astLookupExtraRequireName = function (ast, itemIndex) {
if (ast[itemIndex][0] === "array") {
@@ -908,6 +1102,7 @@ var analiseModuleContent = function (moduleOptions) {
return moduleDescriptor;
};
+exports.analiseModuleContent = analiseModuleContent;
var collectFlagsWarnings = function (config, deepModulesInfo) {
var featureWarnings = {},
@@ -935,9 +1130,9 @@ var collectFlagsWarnings = function (config, deepModulesInfo) {
}
for (var featureName in featureWarnings) {
- result.push("Required " + ("\"" + featureName + "\": true").green +
+ result.push("Required " + ("\"" + featureName + "\"").green + ": " + "true".green +
". Some of your modules (" + (featureWarnings[featureName].join(', ')).cyan + ") are uses feature " + ("`" + featureName + "`").green + ", " +
- "but it disable in this build");
+ "but it disable in this build.");
}
if (!is_using_shortcuts && config.shortcuts) {
@@ -966,8 +1161,128 @@ var collectFlagsWarnings = function (config, deepModulesInfo) {
result.push('You are using ' + '`stats_coverage_async`'.green + ' but not using ' + '`async`'.green + '. Disable ' + '`stats_coverage_async`'.green + ' flag.');
}
+ var warnings = {
+ globals: 'Some of your modules are non-standard globals (you can register them as ' + '"name"'.green + ': ' + '"@shortcut"'.green + '):',
+ modules: 'Some of our modules are probably off-package (you can register them as ' + '"name"'.green + ': ' + '"@shortcut"'.green + '):',
+ unused: 'Some of your modules are declared but not used:'
+ };
+
+ var suspiciousNames = getSuspiciousNames(config, deepModulesInfo);
+ Object.keys(warnings).forEach(function (warningName) {
+ if (suspiciousNames[warningName].length) {
+ result.push(warnings[warningName]);
+ suspiciousNames[warningName].forEach(function (name) {
+ result.push(' - ' + name.toString().yellow);
+ });
+ result.push('');
+ }
+ });
+
return result;
};
+exports.collectFlagsWarnings = collectFlagsWarnings;
+
+function getGlobals(config) {
+ var result = {},
+ names = ['GLOBALS'];
+
+ if (config.node) {
+ names.push('NODE_GLOBALS');
+ }
+
+ if (config.worker) {
+ names.push('WORKER_GLOBALS');
+ }
+
+ names.forEach(function (name) {
+ var globalNames = exports[name];
+ for (var name in globalNames) {
+ result[name] = globalNames[name];
+ }
+ });
+
+ return result;
+}
+exports.getGlobals = getGlobals;
+
+function discoverModuleType(moduleName, modulesNames, globalsNames) {
+ if (modulesNames.indexOf(moduleName) != -1) {
+ return 'in-package';
+ }
+
+ if (typeof globalsNames[moduleName] !== "undefined") {
+ return 'global';
+ }
+
+ if (/\.[a-z]{1,}$/.test(moduleName)) {
+ return 'off-package?';
+ }
+
+ return 'global?';
+}
+exports.discoverModuleType = discoverModuleType;
+
+function getSuspiciousNames(config, deepModulesInfo) {
+ var modules = config.modules || {},
+ modulesNames = Object.keys(modules),
+ globalsNames = getGlobals(config),
+ suspiciousNames = {
+ globals: [],
+ modules: [],
+ unused: []
+ },
+ suspiciousNamesIndex = {
+ globals: {},
+ modules: {},
+ unused: {}
+ };
+
+ if (!modulesNames.length) {
+ return suspiciousNames;
+ }
+
+ modulesNames.forEach(function (name) {
+
+ if (!suspiciousNamesIndex.unused.hasOwnProperty(name)) {
+ suspiciousNamesIndex.unused[name] = false;
+ }
+ var depends = deepModulesInfo[name].depends;
+ if (depends.length) {
+ depends.forEach(function (name) {
+ var moduleType = discoverModuleType(name, modulesNames, globalsNames);
+ // skip special LMD names
+ if (typeof exports.LMD_GLOBALS[name] !== "undefined") {
+ return;
+ }
+
+ if (moduleType === 'global?' && !suspiciousNamesIndex.globals[name]) {
+ suspiciousNamesIndex.globals[name] = true;
+ suspiciousNames.globals.push(name);
+ }
+
+ if (moduleType === 'off-package?' && !suspiciousNamesIndex.modules[name]) {
+ suspiciousNamesIndex.modules[name] = true;
+ suspiciousNames.modules.push(name);
+ }
+
+ suspiciousNamesIndex.unused[name] = true;
+ });
+ }
+ });
+
+ // add unused
+ modulesNames.forEach(function (name) {
+ if (config.main === name) {
+ return;
+ }
+ if (!suspiciousNamesIndex.unused[name]) {
+ suspiciousNames.unused.push(name);
+ }
+ });
+
+ return suspiciousNames;
+}
+exports.getSuspiciousNames = getSuspiciousNames;
/**
* Checks module type
@@ -1027,18 +1342,3 @@ var getModuleType = function (code) {
return "plain";
};
-
-exports.tryExtend = tryExtend;
-exports.collectModules = collectModules;
-exports.assembleLmdConfig = assembleLmdConfig;
-exports.deepDestructableMerge = deepDestructableMerge;
-exports.analiseModuleContent = analiseModuleContent;
-exports.collectModulesInfo = collectModulesInfo;
-exports.collectFlagsWarnings = collectFlagsWarnings;
-exports.wrapModule = wrapModule;
-
-exports.PATH_SPLITTER = PATH_SPLITTER;
-exports.GLOBALS = GLOBALS;
-exports.LMD_JS_SRC_PATH = LMD_JS_SRC_PATH;
-exports.LMD_JS_SRC_PATH = LMD_JS_SRC_PATH;
-exports.LMD_PLUGINS = LMD_PLUGINS;
View
11 package.json
@@ -5,7 +5,7 @@
"name": "Mikhail Davydov",
"email": "azazel.private@gmail.com"
},
- "version": "1.9.5",
+ "version": "1.9.6",
"bin": {
"lmd": "./bin/lmd"
},
@@ -17,10 +17,13 @@
"type": "git",
"url": "git@github.com:azproduction/lmd.git"
},
- "keywords": ["lmd", "amd", "module", "builder"],
+ "keywords": [
+ "lmd", "amd", "module", "builder",
+ "optimizer", "cli", "tool",
+ "code_coverage", "analytics"
+ ],
"dependencies": {
"uglify-js": ">= 1.3.4",
- "jshint": ">= 0.7.1",
"jade": ">= 0.26.1",
"express": ">= 2.5.9",
"colors": ">= 0.6.0",
@@ -32,7 +35,7 @@
"colors": ">= 0.6.0"
},
"engines": {
- "node": "0.8.x"
+ "node": ">= 0.8.0"
},
"preferGlobal": true
}
View
15 stats_server/index.js
@@ -5,15 +5,14 @@
* @licence MIT
*/
var fs = require('fs'),
+ path = require('path'),
express = require("express"),
common = require(__dirname + '/../lib/lmd_common.js'),
assembleLmdConfig = common.assembleLmdConfig,
flagToOptionNameMap = common.LMD_PLUGINS;
require('colors');
-var CROSS_PLATFORM_PATH_SPLITTER = common.PATH_SPLITTER;
-
/**
*
* @constructor
@@ -53,15 +52,9 @@ function LmdStatsServer(data) {
}
this.logDir = fs.realpathSync(this.logDir);
-
this.wwwDir = fs.realpathSync(this.wwwDir);
-
this.configFile = fs.realpathSync(this.configFile);
-
- this.configDir = fs.realpathSync(this.configFile);
- this.configDir = this.configDir.split(CROSS_PLATFORM_PATH_SPLITTER);
- this.configDir.pop();
- this.configDir = this.configDir.join('/');
+ this.configDir = path.dirname(this.configFile);
this.config = assembleLmdConfig(this.configFile, Object.keys(flagToOptionNameMap));
@@ -89,8 +82,8 @@ function LmdStatsServer(data) {
console.log('info'.green + ': LMD Config: ' + this.configFile.green);
this.app.listen(this.port, this.address);
- require('./lib/admin.js').attachTo(this.adminApp, this.logDir, this.wwwDir, this.config, this.modules);
- require('./lib/log.js').attachTo(this.app, this.logDir);
+ require(__dirname + '/lib/admin.js').attachTo(this.adminApp, this.logDir, this.wwwDir, this.config, this.modules);
+ require(__dirname + '/lib/log.js').attachTo(this.app, this.logDir);
console.log('info'.green + ': Hit Ctrl+C to stop');
}
View
36 stats_server/lib/admin.js
@@ -23,6 +23,7 @@
*/
var fs = require("fs"),
+ path = require('path'),
util = require("util"),
express = require('express');
@@ -45,7 +46,7 @@ exports.attachTo = function (app, logDir, wwwDir, lmdConfig, lmdModules) {
files.forEach(function (file) {
reports.push({
id : file,
- date : fs.statSync(logDir + '/' + file).ctime + ''
+ date : fs.statSync(path.join(logDir, file)).ctime + ''
});
});
reports.sort(function (first, second) {
@@ -76,12 +77,12 @@ exports.attachTo = function (app, logDir, wwwDir, lmdConfig, lmdModules) {
fileName = lmdModules[moduleName].path;
} else {
// www_path -> path
- fileName = wwwDir + moduleName;
+ fileName = path.join(wwwDir, moduleName);
}
// shortcut -> path
if (fileName.charAt(0) === '@') {
- fileName = wwwDir + fileName.replace('@', '');
+ fileName = path.join(wwwDir, fileName.replace('@', ''));
}
readReport(req.params.report, function (err, report) {
if (err) {
@@ -116,19 +117,19 @@ exports.attachTo = function (app, logDir, wwwDir, lmdConfig, lmdModules) {
fileName = lmdModules[moduleName].path;
} else {
// www_path -> path
- fileName = wwwDir + '/' + moduleName;
+ fileName = path.join(wwwDir, moduleName);
}
// shortcut -> path
if (fileName.charAt(0) === '@') {
- fileName = wwwDir + '/' + fileName.replace('@', '');
+ fileName = path.join(wwwDir, fileName.replace('@', ''));
}
return fs.readFileSync(fileName, 'utf8');
}
- function readReport (report, callback) {
- fs.readFile(logDir + "/" + report, function (err, data) {
+ function readReport(report, callback) {
+ fs.readFile(path.join(logDir, report), function (err, data) {
if (err) {
console.error(err);
callback.call(null, err);
@@ -262,25 +263,4 @@ exports.attachTo = function (app, logDir, wwwDir, lmdConfig, lmdModules) {
});
}
}
-
- function readMultipleReports (reports, callback) {
- var howMany = reports.length;
- var result = [];
- if (howMany == 0) {
- return callback.call(this, "No reports to read");
- }
- reports.forEach(function (report) {
- readReport(report, function (err, data) {
- if (err) {
- callback.call(this, err);
- } else {
- result.push(data);
- howMany -= 1;
- if (howMany < 1) {
- callback.call(this, null, result);
- }
- }
- });
- });
- }
};
View
5 stats_server/lib/log.js
@@ -22,7 +22,8 @@
* SOFTWARE.
*/
-var fs = require("fs");
+var fs = require("fs"),
+ path = require('path');
require('colors');
@@ -37,7 +38,7 @@ exports.attachTo = function (app, logDir) {
}
var fileName = req.params.instanceId.replace(/\/|\\|\./g, '_') + '.json';
- fs.writeFile(logDir + '/' + fileName, req.body.json, "utf-8", function (err) {
+ fs.writeFile(path.join(logDir, fileName), req.body.json, "utf-8", function (err) {
if (err) {
res.send(500);
} else {

0 comments on commit 6afe741

Please sign in to comment.
Something went wrong with that request. Please try again.