Comparing version
@@ -42,6 +42,10 @@ #!/usr/bin/env node | ||
.default("json", false) | ||
.string("alias") | ||
.describe("alias", "Set a alias name for a module. ex. http=http-browserify") | ||
.boolean("debug") | ||
.describe("debug", "Prints debug info to output files") | ||
.default("debug", false) | ||
.demand(1) | ||
@@ -74,2 +78,6 @@ .argv; | ||
if(argv.debug) { | ||
options.debug = true; | ||
} | ||
if(argv.filenames) { | ||
@@ -166,4 +174,9 @@ options.includeFilenames = true; | ||
} | ||
if(stats.errors) { | ||
stats.errors.forEach(function(error) { | ||
console.log("\033[1m\033[31mERROR: " + error + "\033[39m\033[22m"); | ||
}); | ||
} | ||
} | ||
}); | ||
} |
@@ -25,2 +25,3 @@ /* | ||
warnings: [], | ||
errors: [], | ||
modules: {}, | ||
@@ -61,7 +62,67 @@ modulesById: {}, | ||
function addModule(depTree, context, module, options, reason, callback) { | ||
if(context) | ||
resolve(context, module, options.resolve, resolved); | ||
else | ||
resolved(null, module); | ||
function execLoaders(request, loaders, filenames, contents, options, callback) { | ||
if(loaders.length === 0) | ||
callback(null, contents[0]); | ||
else { | ||
var loaderFunctions = []; | ||
try { | ||
loaders.forEach(function(name) { | ||
var loader = require(name); | ||
loaderFunctions.push(loader); | ||
}); | ||
} catch(e) { | ||
callback(e); | ||
return; | ||
} | ||
function nextLoader() { | ||
var args = Array.prototype.slice.apply(arguments); | ||
var err = args.shift(); | ||
if(err) { | ||
callback(err); | ||
return; | ||
} | ||
if(loaderFunctions.length > 0) { | ||
try { | ||
var async = false; | ||
var context = { | ||
request: request, | ||
filenames: filenames, | ||
exec: function(code, filename) { | ||
var Module = require("module"); | ||
var m = new Module("exec in " + request, module); | ||
m._compile(code, filename); | ||
return m.exports; | ||
}, | ||
async: function() { | ||
async = true; | ||
return nextLoader; | ||
}, | ||
callback: function() { | ||
async = true; | ||
nextLoader.apply(null, arguments); | ||
}, | ||
web: true, | ||
debug: options.debug, | ||
values: undefined, | ||
options: options | ||
}; | ||
var retVal = loaderFunctions.pop().apply(context, args); | ||
if(!async) | ||
nextLoader(retVal === undefined ? new Error("loader did not return a value") : null, retVal); | ||
} catch(e) { | ||
callback(err); | ||
return; | ||
} | ||
} else { | ||
callback(null, args[0]); | ||
} | ||
} | ||
contents.unshift(null); | ||
nextLoader.apply(null, contents); | ||
} | ||
} | ||
function addModule(depTree, context, modu, options, reason, callback) { | ||
resolve(context || path.dirname(modu), modu, options.resolve, resolved); | ||
function resolved(err, filename) { | ||
@@ -76,3 +137,3 @@ if(err) { | ||
} else { | ||
var module = depTree.modules[filename] = { | ||
var modu = depTree.modules[filename] = { | ||
id: depTree.nextModuleId++, | ||
@@ -82,4 +143,7 @@ filename: filename, | ||
}; | ||
depTree.modulesById[module.id] = module; | ||
fs.readFile(filename, "utf-8", function(err, source) { | ||
depTree.modulesById[modu.id] = modu; | ||
var filenameWithLoaders = filename; | ||
var loaders = filename.split(/!/g); | ||
filename = loaders.pop(); | ||
fs.readFile(filename, "utf-8", function(err, content) { | ||
if(err) { | ||
@@ -89,100 +153,108 @@ callback(err); | ||
} | ||
var deps; | ||
try { | ||
deps = parse(source, options.parse); | ||
} catch(e) { | ||
callback("File \"" + filename + "\" parsing failed: " + e); | ||
return; | ||
} | ||
module.requires = deps.requires || []; | ||
module.asyncs = deps.asyncs || []; | ||
module.contexts = deps.contexts || []; | ||
module.source = source; | ||
execLoaders(filenameWithLoaders, loaders, [filename], [content], options, processJs); | ||
function processJs(err, source) { | ||
if(err) { | ||
callback(err); | ||
return; | ||
} | ||
var deps; | ||
try { | ||
deps = parse(source, options.parse); | ||
} catch(e) { | ||
callback("File \"" + filenameWithLoaders + "\" parsing failed: " + e); | ||
return; | ||
} | ||
modu.requires = deps.requires || []; | ||
modu.asyncs = deps.asyncs || []; | ||
modu.contexts = deps.contexts || []; | ||
modu.source = source; | ||
var requires = {}, directRequire = {}; | ||
var contexts = [], directContexts = {}; | ||
function add(r) { | ||
requires[r.name] = requires[r.name] || []; | ||
requires[r.name].push(r); | ||
} | ||
function addContext(m) { | ||
return function(c) { | ||
contexts.push({context: c, module: m}); | ||
var requires = {}, directRequire = {}; | ||
var contexts = [], directContexts = {}; | ||
function add(r) { | ||
requires[r.name] = requires[r.name] || []; | ||
requires[r.name].push(r); | ||
} | ||
} | ||
if(module.requires) { | ||
module.requires.forEach(add); | ||
module.requires.forEach(function(r) { | ||
directRequire[r.name] = true; | ||
}); | ||
} | ||
if(module.contexts) { | ||
module.contexts.forEach(addContext(module)); | ||
module.contexts.forEach(function(c) { | ||
directContexts[c.name] = true; | ||
}); | ||
} | ||
if(module.asyncs) | ||
module.asyncs.forEach(function addAsync(c) { | ||
if(c.requires) | ||
c.requires.forEach(add); | ||
if(c.asyncs) | ||
c.asyncs.forEach(addAsync); | ||
if(c.contexts) | ||
c.contexts.forEach(addContext(c)); | ||
}); | ||
requiresNames = Object.keys(requires); | ||
var count = requiresNames.length + contexts.length + 1; | ||
var errors = []; | ||
if(requiresNames.length) | ||
requiresNames.forEach(function(moduleName) { | ||
var reason = { | ||
type: directRequire[moduleName] ? "require" : "async require", | ||
count: requires[moduleName].length, | ||
filename: filename | ||
}; | ||
addModule(depTree, path.dirname(filename), moduleName, options, reason, function(err, moduleId) { | ||
if(err) { | ||
depTree.warnings.push("Cannot find module '" + moduleName + "'\n " + err + | ||
"\n @ " + filename + " (line " + requires[moduleName][0].line + ", column " + requires[moduleName][0].column + ")"); | ||
} else { | ||
requires[moduleName].forEach(function(requireItem) { | ||
requireItem.id = moduleId; | ||
}); | ||
function addContext(m) { | ||
return function(c) { | ||
contexts.push({context: c, module: m}); | ||
} | ||
} | ||
if(modu.requires) { | ||
modu.requires.forEach(add); | ||
modu.requires.forEach(function(r) { | ||
directRequire[r.name] = true; | ||
}); | ||
} | ||
if(modu.contexts) { | ||
modu.contexts.forEach(addContext(modu)); | ||
modu.contexts.forEach(function(c) { | ||
directContexts[c.name] = true; | ||
}); | ||
} | ||
if(modu.asyncs) | ||
modu.asyncs.forEach(function addAsync(c) { | ||
if(c.requires) | ||
c.requires.forEach(add); | ||
if(c.asyncs) | ||
c.asyncs.forEach(addAsync); | ||
if(c.contexts) | ||
c.contexts.forEach(addContext(c)); | ||
}); | ||
requiresNames = Object.keys(requires); | ||
var count = requiresNames.length + contexts.length + 1; | ||
var errors = []; | ||
if(requiresNames.length) | ||
requiresNames.forEach(function(moduleName) { | ||
var reason = { | ||
type: directRequire[moduleName] ? "require" : "async require", | ||
count: requires[moduleName].length, | ||
filename: filename | ||
}; | ||
addModule(depTree, path.dirname(filename), moduleName, options, reason, function(err, moduleId) { | ||
if(err) { | ||
depTree.errors.push("Cannot find module '" + moduleName + "'\n " + err + | ||
"\n @ " + filename + " (line " + requires[moduleName][0].line + ", column " + requires[moduleName][0].column + ")"); | ||
} else { | ||
requires[moduleName].forEach(function(requireItem) { | ||
requireItem.id = moduleId; | ||
}); | ||
} | ||
endOne(); | ||
}); | ||
}); | ||
if(contexts) { | ||
contexts.forEach(function(contextObj) { | ||
var context = contextObj.context; | ||
var module = contextObj.module; | ||
var reason = { | ||
type: directContexts[context.name] ? "context" : "async context", | ||
filename: filename | ||
}; | ||
addContextModule(depTree, path.dirname(filename), context.name, options, reason, function(err, contextModuleId) { | ||
if(err) { | ||
depTree.errors.push("Cannot find context '"+context.name+"'\n " + err + | ||
"\n @ " + filename + " (line " + context.line + ", column " + context.column + ")"); | ||
} else { | ||
context.id = contextModuleId; | ||
module.requires.push({id: context.id}); | ||
} | ||
endOne(); | ||
}); | ||
if(context.warn) { | ||
depTree.warnings.push(filename + " (line " + context.line + ", column " + context.column + "): " + | ||
"implicit use of require.context(\".\") is not recommended."); | ||
} | ||
endOne(); | ||
}); | ||
}); | ||
if(contexts) { | ||
contexts.forEach(function(contextObj) { | ||
var context = contextObj.context; | ||
var module = contextObj.module; | ||
var reason = { | ||
type: directContexts[context.name] ? "context" : "async context", | ||
filename: filename | ||
}; | ||
addContextModule(depTree, path.dirname(filename), context.name, options, reason, function(err, contextModuleId) { | ||
if(err) { | ||
errors.push(err+"\n @ " + filename + " (line " + context.line + ", column " + context.column + ")"); | ||
} | ||
endOne(); | ||
function endOne() { | ||
count--; | ||
if(count === 0) { | ||
if(errors.length) { | ||
callback(errors.join("\n")); | ||
} else { | ||
context.id = contextModuleId; | ||
module.requires.push({id: context.id}); | ||
callback(null, modu.id); | ||
} | ||
endOne(); | ||
}); | ||
if(context.warn) { | ||
depTree.warnings.push(filename + " (line " + context.line + ", column " + context.column + "): " + | ||
"implicit use of require.context(\".\") is not recommended."); | ||
} | ||
}); | ||
} | ||
endOne(); | ||
function endOne() { | ||
count--; | ||
if(count === 0) { | ||
if(errors.length) { | ||
callback(errors.join("\n")); | ||
} else { | ||
callback(null, module.id); | ||
} | ||
} | ||
@@ -215,2 +287,6 @@ } | ||
depTree.modulesById[contextModule.id] = contextModule; | ||
var contextModuleNameWithLoaders = dirname; | ||
var loaders = dirname.split(/!/g); | ||
dirname = loaders.pop(); | ||
var prependLoaders = loaders.length === 0 ? "" : loaders.join("!") + "!"; | ||
var extensions = (options.resolve && options.resolve.extensions) || [".web.js", ".js"]; | ||
@@ -249,8 +325,14 @@ function doDir(dirname, moduleName, done) { | ||
} else { | ||
var hasExt = false; | ||
extensions.forEach(function(ext) { | ||
if(file.substr(file.length - ext.length) === ext) | ||
hasExt = true; | ||
}); | ||
if(!hasExt) { | ||
var match = false; | ||
if(loaders.length === 0) | ||
extensions.forEach(function(ext) { | ||
if(file.substr(file.length - ext.length) === ext) | ||
match = true; | ||
if(options.resolve && options.resolve.loaders) | ||
options.resolve.loaders.forEach(function(loader) { | ||
if(loader.test.test(filename)) | ||
match = true; | ||
}); | ||
}); | ||
if(!match && loaders.length === 0) { | ||
endOne(); | ||
@@ -263,3 +345,3 @@ return; | ||
}; | ||
addModule(depTree, null, filename, options, reason, function(err, moduleId) { | ||
addModule(depTree, dirname, prependLoaders + filename, options, reason, function(err, moduleId) { | ||
if(err) { | ||
@@ -266,0 +348,0 @@ depTree.warnings.push("A file in context was excluded because of error: " + err); |
@@ -10,22 +10,4 @@ /* | ||
/** | ||
* context: absolute filename of current file | ||
* identifier: module to find | ||
* options: | ||
* paths: array of lookup paths | ||
* callback: function(err, absoluteFilename) | ||
*/ | ||
module.exports = function resolve(context, identifier, options, callback) { | ||
if(!callback) { | ||
callback = options; | ||
options = {}; | ||
} | ||
if(!options) | ||
options = {}; | ||
if(!options.extensions) | ||
options.extensions = [".web.js", ".js"]; | ||
if(!options.paths) | ||
options.paths = []; | ||
if(!options.alias) | ||
options.alias = {}; | ||
function resolve(context, identifier, options, type, callback) { | ||
function finalResult(err, absoluteFilename) { | ||
@@ -50,15 +32,29 @@ if(err) { | ||
var pathname = identArray[0][0] === "." ? join(contextArray, identArray) : path.join.apply(path, identArray); | ||
loadAsFile(pathname, options, function(err, absoluteFilename) { | ||
if(err) { | ||
loadAsDirectory(pathname, options, finalResult); | ||
return; | ||
} | ||
callback(null, absoluteFilename); | ||
}); | ||
if(type === "context") { | ||
fs.stat(pathname, function(err, stat) { | ||
if(err) { | ||
finalResult(err); | ||
return; | ||
} | ||
if(!stat.isDirectory()) { | ||
finalResult("Context \"" + identifier + "\" in not a directory"); | ||
return; | ||
} | ||
callback(null, pathname); | ||
}); | ||
} else { | ||
loadAsFile(pathname, options, type, function(err, absoluteFilename) { | ||
if(err) { | ||
loadAsDirectory(pathname, options, type, finalResult); | ||
return; | ||
} | ||
callback(null, absoluteFilename); | ||
}); | ||
} | ||
} else { | ||
loadNodeModules(contextArray, identArray, options, finalResult); | ||
loadNodeModules(contextArray, identArray, options, type, finalResult); | ||
} | ||
} | ||
module.exports.context = function(context, identifier, options, callback) { | ||
function doResolve(context, identifier, options, type, callback) { | ||
if(!callback) { | ||
@@ -70,31 +66,72 @@ callback = options; | ||
options = {}; | ||
if(!options.extensions) | ||
options.extensions = ["", ".webpack.js", ".web.js", ".js"]; | ||
if(!options.loaders) | ||
options.loaders = []; | ||
if(!options.postfixes) | ||
options.postfixes = ["", "-webpack", "-web"]; | ||
if(!options.loaderExtensions) | ||
options.loaderExtensions = [".webpack-web-loader.js", ".webpack-loader.js", ".web-loader.js", ".loader.js", "", ".js"]; | ||
if(!options.loaderPostfixes) | ||
options.loaderPostfixes = ["-webpack-web-loader", "-webpack-loader", "-web-loader", "-loader", ""]; | ||
if(!options.paths) | ||
options.paths = []; | ||
function finalResult(err, absoluteFilename) { | ||
if(err) { | ||
callback("Context \"" + identifier + "\" not found in context \"" + context + "\""); | ||
return; | ||
if(!options.alias) | ||
options.alias = {}; | ||
var identifiers = identifier.split(/!/g); | ||
if(identifiers.length === 1) { | ||
var resource = identifiers.pop(); | ||
for(var i = 0; i < options.loaders.length; i++) { | ||
var line = options.loaders[i]; | ||
if(line.test.test(resource)) { | ||
identifiers.push(line.loader); | ||
break; | ||
} | ||
} | ||
callback(null, absoluteFilename); | ||
identifiers.push(resource); | ||
} | ||
var identArray = identifier.split("/"); | ||
var contextArray = split(context); | ||
if(identArray[0] === "." || identArray[0] === ".." || identArray[0] === "") { | ||
var pathname = join(contextArray, identArray); | ||
fs.stat(pathname, function(err, stat) { | ||
if(err) { | ||
finalResult(err); | ||
var errors = []; | ||
var count = identifiers.length; | ||
function endOne() { | ||
count--; | ||
if(count === 0) { | ||
if(errors.length > 0) { | ||
callback(errors.join("\n")); | ||
return; | ||
} | ||
if(!stat.isDirectory()) { | ||
finalResult("Context \"" + identifier + "\" in not a directory"); | ||
return; | ||
callback(null, identifiers.join("!")); | ||
} | ||
} | ||
identifiers.forEach(function(ident, index) { | ||
resolve(context, ident, options, index === identifiers.length - 1 ? type : "loader", function(err, filename) { | ||
if(err) { | ||
errors.push(err); | ||
} else { | ||
if(!filename) { | ||
throw new Error(JSON.stringify({identifiers: identifiers, from: ident, to: filename})); | ||
} | ||
identifiers[index] = filename; | ||
} | ||
callback(null, pathname); | ||
endOne() | ||
}); | ||
} else { | ||
loadNodeModulesAsContext(contextArray, identArray, options, finalResult); | ||
} | ||
}); | ||
} | ||
/** | ||
* context: absolute filename of current file | ||
* identifier: module to find | ||
* options: | ||
* paths: array of lookup paths | ||
* callback: function(err, absoluteFilename) | ||
*/ | ||
module.exports = function(context, identifier, options, callback) { | ||
return doResolve(context, identifier, options, "normal", callback); | ||
} | ||
module.exports.context = function(context, identifier, options, callback) { | ||
return doResolve(context, identifier, options, "context", callback); | ||
} | ||
function split(a) { | ||
@@ -113,20 +150,22 @@ return a.split(/[\/\\]/g); | ||
function loadAsFile(filename, options, callback) { | ||
var pos = -1, result; | ||
function loadAsFile(filename, options, type, callback) { | ||
var pos = -1, result = "NOT SET"; | ||
var extensions = type === "loader" ? options.loaderExtensions : options.extensions; | ||
function tryCb(err, stats) { | ||
if(err || !stats || !stats.isFile()) { | ||
pos++; | ||
if(pos >= options.extensions.length) { | ||
callback(err); | ||
if(pos >= extensions.length) { | ||
callback(err || "Isn't a file"); | ||
return; | ||
} | ||
fs.stat(result = filename + options.extensions[pos], tryCb); | ||
fs.stat(result = filename + extensions[pos], tryCb); | ||
return; | ||
} | ||
if(!result) throw new Error("no result"); | ||
callback(null, result); | ||
} | ||
fs.stat(result = filename, tryCb); | ||
tryCb(true); | ||
} | ||
function loadAsDirectory(dirname, options, callback) { | ||
function loadAsDirectory(dirname, options, type, callback) { | ||
var packageJsonFile = join(split(dirname), ["package.json"]); | ||
@@ -137,53 +176,65 @@ fs.stat(packageJsonFile, function(err, stats) { | ||
fs.readFile(packageJsonFile, "utf-8", function(err, content) { | ||
if(err) { | ||
callback(err); | ||
return; | ||
} | ||
content = JSON.parse(content); | ||
if(content.main) | ||
if(content.webpackLoader && type === "loader") | ||
mainModule = content.webpackLoader; | ||
else if(content.webpack) | ||
mainModule = content.webpack; | ||
else if(content.browserify) | ||
mainModule = content.browserify; | ||
else if(content.main) | ||
mainModule = content.main; | ||
loadAsFile(join(split(dirname), [mainModule]), options, callback); | ||
loadAsFile(join(split(dirname), [mainModule]), options, type, callback); | ||
}); | ||
} else | ||
loadAsFile(join(split(dirname), [mainModule]), options, callback); | ||
loadAsFile(join(split(dirname), [mainModule]), options, type, callback); | ||
}); | ||
} | ||
function loadNodeModules(context, identifier, options, callback) { | ||
nodeModulesPaths(context, options, function(err, dirs) { | ||
function loadNodeModules(context, identifier, options, type, callback) { | ||
var moduleName = identifier.shift(); | ||
var postfixes = type === "loader" ? options.loaderPostfixes : options.postfixes; | ||
nodeModulesPaths(context, options, function(err, paths) { | ||
var dirs = []; | ||
paths.forEach(function(path) { | ||
postfixes.forEach(function(postfix) { | ||
dirs.push(join(split(path), [moduleName+postfix])); | ||
}); | ||
}); | ||
function tryDir(dir) { | ||
var pathname = join(split(dir), identifier); | ||
loadAsFile(pathname, options, function(err, absoluteFilename) { | ||
if(err) { | ||
loadAsDirectory(pathname, options, function(err, absoluteFilename) { | ||
if(err) { | ||
if(dirs.length === 0) { | ||
callback("no module in any path of paths"); | ||
return; | ||
} | ||
tryDir(dirs.shift()); | ||
if(type === "context") { | ||
fs.stat(pathname, function(err, stat) { | ||
if(err || !stat.isDirectory()) { | ||
if(dirs.length === 0) { | ||
callback("no directory in any path of paths"); | ||
return; | ||
} | ||
callback(null, absoluteFilename); | ||
}); | ||
return; | ||
} | ||
callback(null, absoluteFilename); | ||
}); | ||
} | ||
tryDir(dirs.shift()); | ||
}); | ||
} | ||
function loadNodeModulesAsContext(context, identifier, options, callback) { | ||
nodeModulesPaths(context, options, function(err, dirs) { | ||
function tryDir(dir) { | ||
var pathname = join(split(dir), identifier); | ||
fs.stat(pathname, function(err, stat) { | ||
if(err || !stat.isDirectory()) { | ||
if(dirs.length === 0) { | ||
callback(true); | ||
tryDir(dirs.shift()); | ||
return; | ||
} | ||
tryDir(dirs.shift()); | ||
return; | ||
} | ||
callback(null, pathname); | ||
}); | ||
callback(null, pathname); | ||
}); | ||
} else { | ||
loadAsFile(pathname, options, type, function(err, absoluteFilename) { | ||
if(err) { | ||
loadAsDirectory(pathname, options, type, function(err, absoluteFilename) { | ||
if(err) { | ||
if(dirs.length === 0) { | ||
callback("no module in any path of paths"); | ||
return; | ||
} | ||
tryDir(dirs.shift()); | ||
return; | ||
} | ||
callback(null, absoluteFilename); | ||
}); | ||
return; | ||
} | ||
callback(null, absoluteFilename); | ||
}); | ||
} | ||
} | ||
@@ -190,0 +241,0 @@ tryDir(dirs.shift()); |
@@ -42,5 +42,9 @@ /* | ||
- resolve.extensions (object) | ||
possible extentions for files | ||
possible extensions for files | ||
- resolve.paths (array) | ||
search paths | ||
- resolve.loaders (array) | ||
extension to loader mappings | ||
{test: /\.extension$/, loader: "myloader"} | ||
loads files that matches the RegExp to the loader if no other loader set | ||
- parse.overwrites (object) | ||
@@ -78,5 +82,8 @@ free module varables which are replaced with a module | ||
options.resolve.paths.push(path.join(path.dirname(__dirname), "buildin", "node_modules")); | ||
options.resolve.paths.push(path.join(path.dirname(__dirname), "node_modules")); | ||
options.resolve.alias = options.resolve.alias || {}; | ||
options.resolve.alias.http = options.resolve.alias.http || path.join(path.dirname(__dirname), "node_modules", "http-browserify") | ||
options.resolve.alias.vm = options.resolve.alias.vm || path.join(path.dirname(__dirname), "node_modules", "vm-browserify") | ||
options.resolve.loaders = options.resolve.loaders || []; | ||
options.resolve.loaders.push({test: /\.coffee$/, loader: "coffee"}); | ||
options.resolve.loaders.push({test: /\.json$/, loader: "json"}); | ||
options.resolve.loaders.push({test: /\.jade$/, loader: "jade"}); | ||
buildDeps(context, moduleName, options, function(err, depTree) { | ||
@@ -119,7 +126,7 @@ if(err) { | ||
buffer.push("/******/({a:"); | ||
buffer.push(stringify(options.outputPostfix)); | ||
buffer.push(JSON.stringify(options.outputPostfix)); | ||
buffer.push(",b:"); | ||
buffer.push(stringify(options.outputJsonpFunction)); | ||
buffer.push(JSON.stringify(options.outputJsonpFunction)); | ||
buffer.push(",c:"); | ||
buffer.push(stringify(options.scriptSrcPrefix)); | ||
buffer.push(JSON.stringify(options.scriptSrcPrefix)); | ||
buffer.push(",\n"); | ||
@@ -140,3 +147,8 @@ } else { | ||
buffer = buffer.join(""); | ||
if(options.minimize) buffer = uglify(buffer, filename); | ||
try { | ||
if(options.minimize) buffer = uglify(buffer, filename); | ||
} catch(e) { | ||
callback(e); | ||
return; | ||
} | ||
fs.writeFile(filename, buffer, "utf-8", function(err) { | ||
@@ -178,2 +190,3 @@ if(err) throw err; | ||
buffer.warnings = depTree.warnings; | ||
buffer.errors = depTree.errors; | ||
buffer.fileModules = fileModulesMap; | ||
@@ -192,4 +205,8 @@ callback(null, buffer); | ||
buffer = buffer.join(""); | ||
if(options.minimize) buffer = uglify(buffer, "output"); | ||
callback(null, buffer); | ||
try { | ||
if(options.minimize) buffer = uglify(buffer, "output"); | ||
callback(null, buffer); | ||
} catch(e) { | ||
callback(e); | ||
} | ||
} | ||
@@ -207,10 +224,6 @@ }); | ||
} catch(e) { | ||
console.error(filename + " @ Line " + e.line + ", Col " + e.col + ", " + e.message); | ||
throw new Error(filename + " @ Line " + e.line + ", Col " + e.col + ", " + e.message); | ||
return input; | ||
} | ||
return source; | ||
} | ||
function stringify(str) { | ||
return '"' + str.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"") + '"'; | ||
} |
@@ -5,6 +5,2 @@ /* | ||
*/ | ||
function stringify(str) { | ||
return '"' + str.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"") + '"'; | ||
} | ||
module.exports = function(module, options) { | ||
@@ -58,3 +54,3 @@ if(!module.source) { | ||
to: contextItem.calleeRange[1], | ||
value: "require(" + prefix + ((contextItem.id || "throw new Error('there is not id for this')") + "") + ")" | ||
value: "require(" + prefix + ((contextItem.id || JSON.stringify("context: " + contextItem.name || "context failed")) + "") + ")" | ||
}); | ||
@@ -65,3 +61,3 @@ if(contextItem.replace) | ||
to: contextItem.replace[0][1], | ||
value: stringify(contextItem.replace[1]) | ||
value: JSON.stringify(contextItem.replace[1]) | ||
}); | ||
@@ -72,3 +68,3 @@ } else { | ||
to: contextItem.expressionRange[1], | ||
value: "require(" + prefix + ((contextItem.id || "throw new Error('there is not id for this')") + "") + ")" + postfix | ||
value: "require(" + prefix + ((contextItem.id || JSON.stringify("context: " + contextItem.name || "context failed")) + "") + ")" + postfix | ||
}); | ||
@@ -116,3 +112,26 @@ } | ||
}); | ||
if(options.debug) { | ||
if(options.minimize) { | ||
result = [uglify(result.join(""), module.filename)]; | ||
} | ||
result.push("\n\n// WEBPACK FOOTER //\n"+ | ||
"// module.id = " + module.id + "\n" + | ||
"//@ sourceURL=webpack-module://" + encodeURI(module.filename).replace(/%5C|%2F/g, "/")); | ||
return "eval(" + JSON.stringify(result.join("")) + ")"; | ||
} | ||
return result.join(""); | ||
} | ||
function uglify(input, filename) { | ||
var uglify = require("uglify-js"); | ||
try { | ||
source = uglify.parser.parse(input); | ||
source = uglify.uglify.ast_mangle(source); | ||
source = uglify.uglify.ast_squeeze(source); | ||
source = uglify.uglify.gen_code(source); | ||
} catch(e) { | ||
throw new Error(filename + " @ Line " + e.line + ", Col " + e.col + ", " + e.message); | ||
return input; | ||
} | ||
return source; | ||
} |
{ | ||
"name": "webpack", | ||
"version": "0.2.8", | ||
"version": "0.3.0", | ||
"author": "Tobias Koppers @sokra", | ||
"description": "Packs CommonJs Modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand.", | ||
"dependencies": { | ||
"esprima": "0.9.8", | ||
"esprima": "0.9.x", | ||
"optimist": "0.2.x", | ||
"uglify-js": "1.2.5", | ||
"uglify-js": "1.2.x", | ||
"sprintf": "0.1.x" | ||
}, | ||
"optionalDependencies": { | ||
"http-browserify": "*", | ||
"vm-browserify": "*" | ||
"raw-loader": "0.1.x", | ||
"json-loader": "0.1.x", | ||
"jade-loader": "0.1.x", | ||
"coffee-loader": "0.1.x" | ||
}, | ||
@@ -34,3 +36,3 @@ "licenses": [ | ||
}, | ||
"licence": "MIT" | ||
"license": "MIT" | ||
} |
// Polyfill for node.js | ||
// - adds require.ensure | ||
// - adds require.context | ||
// call it like this: | ||
// call it like this: | ||
// require = require("webpack/require-polyfill")(require.valueOf()); | ||
@@ -12,3 +12,89 @@ // This is only required when you want to use the special require.xxx methods | ||
req = function(name) { | ||
return oldReq(name); | ||
if(name.indexOf("!") !== -1) { | ||
var items = name.split(/!/g); | ||
var resource = oldReq.resolve(items.pop()); | ||
var resolved = []; | ||
items.forEach(function(item, index) { | ||
var relative = false; | ||
if(item.length > 2 && | ||
item[0] === ".") { | ||
if(item[1] === "/") | ||
relative = true; | ||
else if(item.length > 3 && | ||
item[1] === "." && | ||
item[2] === "/") | ||
relative = true; | ||
} | ||
if(item.length > 3 && | ||
item[1] === ":" && | ||
item[2] === "\\") | ||
relative = true; | ||
var tries = []; | ||
if(!relative) { | ||
postfixes.forEach(function(postfix) { | ||
if(item.indexOf("/") !== -1) | ||
tries.push(item.replace("/", postfix+"/")); | ||
else | ||
tries.push(item + postfix); | ||
}); | ||
} | ||
tries.push(item); | ||
for(var i = 0; i < tries.length; i++) { | ||
for(var ext = 0; ext < extensions.length; ext++) { | ||
try { | ||
var file = oldReq.resolve(tries[i] + extensions[ext]); | ||
} catch(e) {} | ||
if(file) { | ||
resolved.push(file); | ||
break; | ||
} | ||
} | ||
if(ext !== extensions.length) | ||
break; | ||
} | ||
if(i === tries.length) | ||
throw new Error("Cannot find loader module '"+item+"'"); | ||
}); | ||
resolved = resolved.reverse(); | ||
var cacheLine = resolved.join("!") + "!" + resource; | ||
var cacheEntry = oldReq.cache[cacheLine]; | ||
if(cacheEntry) | ||
return cacheEntry; | ||
var content = [require("fs").readFileSync(resource, "utf-8")]; | ||
var values; | ||
function exec(code, filename) { | ||
var Module = require("module"); | ||
var m = new Module("exec in " + cacheLine, module); | ||
m._compile(code, filename); | ||
return m.exports; | ||
} | ||
resolved.forEach(function(loader) { | ||
var set = false, err = null; | ||
var context = { | ||
request: cacheLine, | ||
filenames: [resource], | ||
exec: exec, | ||
async: function() { return false; }, | ||
callback: function() { | ||
set = true; | ||
content = Array.prototype.slice.apply(arguments); | ||
err = content.shift(); | ||
values = context.values; | ||
}, | ||
inputValues: values, | ||
values: undefined | ||
}; | ||
var retVal = oldReq(loader).apply(context, content); | ||
if(set) { | ||
if(err) throw err; | ||
} else { | ||
content = [retVal]; | ||
values = context.values; | ||
} | ||
}); | ||
if(values !== undefined) | ||
return values[0]; | ||
return exec(content[0], cacheLine); | ||
} else | ||
return oldReq(name); | ||
}; | ||
@@ -31,2 +117,4 @@ req.__proto__ = oldReq; | ||
return req; | ||
} | ||
} | ||
var extensions = [".webpack-loader.js", ".loader.js", ".js", ""]; | ||
var postfixes = ["-webpack-loader", "-loader", ""] |
@@ -108,1 +108,23 @@ // Should not break it... should not include complete directory... | ||
}, 3000); | ||
// Loader tests | ||
window.test(require("testloader!../resources/abc.txt") === "abcwebpack", "Loader in package.json"); | ||
window.test(require("testloader/lib/loader!../resources/abc.txt") === "abcwebpack", "Loader with .webpack-loader.js extention"); | ||
window.test(require("testloader/lib/loader.web-loader.js!../resources/abc.txt") === "abcweb", "Loader with .web-loader.js extention"); | ||
window.test(require("testloader/lib/loader.loader.js!../resources/abc.txt") === "abcloader", "Loader with .loader.js extention"); | ||
window.test(require("testloader/lib/loader-indirect!../resources/abc.txt") === "abcwebpack", "Loader with .js extention and requires in loader"); | ||
window.test(require("testloader!../loaders/reverseloader!../resources/abc.txt") === "cbawebpack", "Multiple loaders and relative paths"); | ||
window.test(require("raw!../resources/abc.txt") === "abc", "Buildin 'raw' loader"); | ||
window.test(require("jade!../resources/template.jade")({abc: "abc"}) === "<p>abc</p>", "Buildin 'jade' loader"); | ||
window.test(require("../resources/template.jade")({abc: "abc"}) === "<p>abc</p>", "Buildin 'jade' loader, by ext"); | ||
window.test(require("json!../../../package.json").name === "webpack", "Buildin 'json' loader"); | ||
window.test(require("../../../package.json").name === "webpack", "Buildin 'json' loader, by ext"); | ||
window.test(require("coffee!../resources/script.coffee") === "coffee test", "Buildin 'coffee' loader"); | ||
window.test(require("../resources/script.coffee") === "coffee test", "Buildin 'coffee' loader, by ext"); | ||
// Loader & Context | ||
var abc = "abc", scr = "script.coffee"; | ||
window.test(require("../resources/" + scr) === "coffee test", "context should process extensions"); | ||
window.test(require("raw!../resources/" + abc + ".txt") === "abc", "raw loader with context"); | ||
@@ -22,2 +22,13 @@ /* | ||
} | ||
function testResolveContext(context, moduleName, result) { | ||
return { | ||
topic: function() { | ||
resolve.context(context, moduleName, {}, this.callback); | ||
}, | ||
"correct filename": function(filename) { | ||
assert.equal(filename, result); | ||
} | ||
} | ||
} | ||
vows.describe("resolve").addBatch({ | ||
@@ -34,4 +45,6 @@ | ||
"m2/b.js", path.join(fixtures, "node_modules", "m2", "b.js")), | ||
"resolve loader 1": testResolve(fixtures, "m1/a!./main1.js", path.join(fixtures, "node_modules", "m1", "a.js") + "!" + path.join(fixtures, "main1.js")), | ||
"resolve loader context 1": testResolveContext(fixtures, "m1/a!./", path.join(fixtures, "node_modules", "m1", "a.js") + "!" + fixtures), | ||
}).export(module); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
3224
11.21%2
-60%112453
-12.39%8
33.33%89
-5.32%1
Infinity%0
-100%42
13.51%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated