diff --git a/lib/buildDeps.js b/lib/buildDeps.js index 5a0b05109..2e2581fe7 100644 --- a/lib/buildDeps.js +++ b/lib/buildDeps.js @@ -77,108 +77,147 @@ function addModule(depTree, context, module, options, reason, callback) { reasons: [reason] }; depTree.modulesById[module.id] = module; - fs.readFile(filename, "utf-8", function(err, source) { + var filenameWithLoaders = filename; + var loaders = filename.split(/!/g); + filename = loaders.pop(); + fs.readFile(filename, "utf-8", function(err, content) { if(err) { callback(err); return; } - 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; - - 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}); + if(loaders.length === 0) + processJs(content); + else { + var loaderFunctions = []; + try { + loaders.forEach(function(name) { + var loader = require(name); + loaderFunctions.push(loader); + }); + } catch(e) { + callback(e); + return; } - } - 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; - }); - } - 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 + ")"); - } 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."); + function nextLoader(err, content) { + if(err) { + callback(err); + return; } - }); - } - endOne(); - function endOne() { - count--; - if(count === 0) { - if(errors.length) { - callback(errors.join("\n")); + if(loaderFunctions.length > 0) { + try { + loaderFunctions.pop()([content], { + request: filenameWithLoaders, + filename: filename + }, nextLoader); + } catch(e) { + callback(err); + return; + } } else { - callback(null, module.id); + processJs(content); + } + } + nextLoader(null, content); + } + function processJs(source) { + var deps; + try { + deps = parse(source, options.parse); + } catch(e) { + callback("File \"" + filenameWithLoaders + "\" parsing failed: " + e); + return; + } + module.requires = deps.requires || []; + module.asyncs = deps.asyncs || []; + module.contexts = deps.contexts || []; + module.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}); + } + } + 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; + }); + } + 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 + ")"); + } 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(); + function endOne() { + count--; + if(count === 0) { + if(errors.length) { + callback(errors.join("\n")); + } else { + callback(null, module.id); + } } } } diff --git a/lib/resolve.js b/lib/resolve.js index facd12783..3d3988c1c 100644 --- a/lib/resolve.js +++ b/lib/resolve.js @@ -7,26 +7,8 @@ var fs = require("fs"); // http://nodejs.org/docs/v0.4.8/api/all.html#all_Together... -/** - * 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) { if(err) { callback("Module \"" + identifier + "\" not found in context \"" + @@ -46,18 +28,86 @@ module.exports = function resolve(context, identifier, options, callback) { } if(identArray[0] === "." || identArray[0] === ".." || identArray[0] === "" || identArray[0].match(/^[A-Z]:$/i)) { var pathname = identArray[0][0] === "." ? join(contextArray, identArray) : path.join.apply(path, identArray); - loadAsFile(pathname, options, function(err, absoluteFilename) { + loadAsFile(pathname, options, type, function(err, absoluteFilename) { if(err) { - loadAsDirectory(pathname, options, finalResult); + loadAsDirectory(pathname, options, type, finalResult); return; } callback(null, absoluteFilename); }); } else { - loadNodeModules(contextArray, identArray, options, finalResult); + loadNodeModules(contextArray, identArray, options, type, 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) { + if(!callback) { + callback = options; + options = {}; + } + if(!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 = []; + 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; + } + } + identifiers.push(resource); + } + var errors = []; + var count = identifiers.length; + function endOne() { + count--; + if(count === 0) { + if(errors.length > 0) { + callback(errors.join("\n")); + return; + } + callback(null, identifiers.join("!")); + } + } + identifiers.forEach(function(ident, index) { + resolve(context, ident, options, index === identifiers.length - 1 ? "normal" : "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; + } + endOne() + }); + }); +} + module.exports.context = function(context, identifier, options, callback) { if(!callback) { callback = options; @@ -107,46 +157,66 @@ function join(a, b) { return path.join.apply(path, c); } -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"]); fs.stat(packageJsonFile, function(err, stats) { var mainModule = "index"; if(!err && stats.isFile()) { 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) { + loadAsFile(pathname, options, type, function(err, absoluteFilename) { if(err) { - loadAsDirectory(pathname, options, function(err, absoluteFilename) { + loadAsDirectory(pathname, options, type, function(err, absoluteFilename) { if(err) { if(dirs.length === 0) { callback("no module in any path of paths"); diff --git a/lib/webpack.js b/lib/webpack.js index 615c2c8cd..19041aeb0 100644 --- a/lib/webpack.js +++ b/lib/webpack.js @@ -39,9 +39,13 @@ var templateSingle = require("fs").readFileSync(path.join(__dirname, "templateSi - resolve.alias (object) replace a module. ex {"old-module": "new-module"} - 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) free module varables which are replaced with a module ex. { "$": "jquery" } @@ -74,9 +78,14 @@ module.exports = function(context, moduleName, options, callback) { options.resolve.paths.push(path.join(path.dirname(__dirname), "buildin")); options.resolve.paths.push(path.join(path.dirname(__dirname), "buildin", "web_modules")); 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.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) { if(err) { callback(err); @@ -134,7 +143,12 @@ module.exports = function(context, moduleName, options, callback) { buffer.push(writeChunk(depTree, chunk, options)); buffer.push("/******/})"); 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) { if(err) throw err; }); @@ -184,8 +198,12 @@ module.exports = function(context, moduleName, options, callback) { buffer.push(writeChunk(depTree, options)); buffer.push("/******/})"); 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); + } } }); } @@ -198,7 +216,7 @@ function uglify(input, filename) { source = uglify.uglify.ast_squeeze(source); source = uglify.uglify.gen_code(source); } 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; diff --git a/package.json b/package.json index bc445917d..434539079 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,21 @@ { "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": "*" + "vm-browserify": "*", + "raw-loader": "0.1.x", + "json-loader": "0.1.x", + "jade-loader": "0.1.x", + "coffee-loader": "0.1.x" }, "licenses": [ { @@ -31,5 +35,5 @@ "scripts": { "test": "node node_modules/vows/bin/vows" }, - "licence": "MIT" + "license": "MIT" } \ No newline at end of file diff --git a/require-polyfill.js b/require-polyfill.js index 4d610c48f..7b1968c12 100644 --- a/require-polyfill.js +++ b/require-polyfill.js @@ -9,7 +9,66 @@ module.exports = function(req) { if(!req.webpackPolyfill) { var oldReq = req; 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")]; + resolved.forEach(function(loader) { + content = oldReq(loader)(content, { + request: cacheLine, + filename: resource + }); + }); + return content; + } else + return oldReq(name); }; req.__proto__ = oldReq; req.webpackPolyfill = true; @@ -27,4 +86,6 @@ module.exports = function(req) { } } return req; -} \ No newline at end of file +} +var extensions = [".webpack-loader.js", ".loader.js", ".js", ""]; +var postfixes = ["-webpack-loader", "-loader", ""] \ No newline at end of file diff --git a/test/browsertest/lib/index.web.js b/test/browsertest/lib/index.web.js index f0a1d2ce1..d3cfdacb2 100644 --- a/test/browsertest/lib/index.web.js +++ b/test/browsertest/lib/index.web.js @@ -105,3 +105,19 @@ setTimeout(function() { window.test(sum === 2, "Multiple callbacks on code load finish"); window.test(sum2 === 2, "process.nextTick and process.emit/on should be polyfilled"); }, 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"}) === "

abc

", "Buildin 'jade' loader"); +window.test(require("../resources/template.jade")({abc: "abc"}) === "

abc

", "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"); diff --git a/test/browsertest/loaders/reverseloader.js b/test/browsertest/loaders/reverseloader.js new file mode 100644 index 000000000..7890582ea --- /dev/null +++ b/test/browsertest/loaders/reverseloader.js @@ -0,0 +1,3 @@ +module.exports = function(contents, options, callback) { + callback(null, contents[0].split("").reverse().join("")); +} diff --git a/test/browsertest/node_modules/testloader/lib/loader-indirect.js b/test/browsertest/node_modules/testloader/lib/loader-indirect.js new file mode 100644 index 000000000..9c2b0d812 --- /dev/null +++ b/test/browsertest/node_modules/testloader/lib/loader-indirect.js @@ -0,0 +1 @@ +module.exports = require("./loader.webpack-loader.js"); \ No newline at end of file diff --git a/test/browsertest/node_modules/testloader/lib/loader.js b/test/browsertest/node_modules/testloader/lib/loader.js new file mode 100644 index 000000000..9b053c24c --- /dev/null +++ b/test/browsertest/node_modules/testloader/lib/loader.js @@ -0,0 +1,7 @@ +module.exports = function(contents, options, callback) { + var content = contents[0]; + callback(null, "module.exports=" + stringify(content)); +} +function stringify(str) { + return '"' + str.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"") + '"'; +} \ No newline at end of file diff --git a/test/browsertest/node_modules/testloader/lib/loader.loader.js b/test/browsertest/node_modules/testloader/lib/loader.loader.js new file mode 100644 index 000000000..e96b65e22 --- /dev/null +++ b/test/browsertest/node_modules/testloader/lib/loader.loader.js @@ -0,0 +1,7 @@ +module.exports = function(contents, options, callback) { + var content = contents[0]; + callback(null, "module.exports=" + stringify(content+"loader")); +} +function stringify(str) { + return '"' + str.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"") + '"'; +} \ No newline at end of file diff --git a/test/browsertest/node_modules/testloader/lib/loader.web-loader.js b/test/browsertest/node_modules/testloader/lib/loader.web-loader.js new file mode 100644 index 000000000..beb7b85b4 --- /dev/null +++ b/test/browsertest/node_modules/testloader/lib/loader.web-loader.js @@ -0,0 +1,7 @@ +module.exports = function(contents, options, callback) { + var content = contents[0]; + callback(null, "module.exports=" + stringify(content+"web")); +} +function stringify(str) { + return '"' + str.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"") + '"'; +} \ No newline at end of file diff --git a/test/browsertest/node_modules/testloader/lib/loader.webpack-loader.js b/test/browsertest/node_modules/testloader/lib/loader.webpack-loader.js new file mode 100644 index 000000000..36f00e6b1 --- /dev/null +++ b/test/browsertest/node_modules/testloader/lib/loader.webpack-loader.js @@ -0,0 +1,7 @@ +module.exports = function(contents, options, callback) { + var content = contents[0]; + callback(null, "module.exports=" + stringify(content+"webpack")); +} +function stringify(str) { + return '"' + str.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"") + '"'; +} \ No newline at end of file diff --git a/test/browsertest/node_modules/testloader/package.json b/test/browsertest/node_modules/testloader/package.json new file mode 100644 index 000000000..22074ead5 --- /dev/null +++ b/test/browsertest/node_modules/testloader/package.json @@ -0,0 +1,4 @@ +{ + "name": "testloader", + "webpackLoader": "lib/loader.webpack-loader.js" +} \ No newline at end of file diff --git a/test/browsertest/resources/abc.txt b/test/browsertest/resources/abc.txt new file mode 100644 index 000000000..f2ba8f84a --- /dev/null +++ b/test/browsertest/resources/abc.txt @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/test/browsertest/resources/script.coffee b/test/browsertest/resources/script.coffee new file mode 100644 index 000000000..d4e982f86 --- /dev/null +++ b/test/browsertest/resources/script.coffee @@ -0,0 +1,5 @@ +condition = true +obj = + text: "coffee test" + +module.exports = obj.text if condition? \ No newline at end of file diff --git a/test/browsertest/resources/template.jade b/test/browsertest/resources/template.jade new file mode 100644 index 000000000..e192d1788 --- /dev/null +++ b/test/browsertest/resources/template.jade @@ -0,0 +1,2 @@ +p + = abc \ No newline at end of file diff --git a/test/fixtures/abc.txt b/test/fixtures/abc.txt new file mode 100644 index 000000000..f2ba8f84a --- /dev/null +++ b/test/fixtures/abc.txt @@ -0,0 +1 @@ +abc \ No newline at end of file diff --git a/test/polyfills_test.js b/test/polyfills_test.js new file mode 100644 index 000000000..eb02be30c --- /dev/null +++ b/test/polyfills_test.js @@ -0,0 +1,111 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +var vows = require("vows"); +var assert = require("assert"); +var path = require("path"); +require = require("../require-polyfill")(require.valueOf()); + +vows.describe("polyfills").addBatch({ + + "polyfill context": { + topic: function() { + return require.context("./fixtures") + }, + + "simple file": { + topic: function(context) { + return context("./a"); + }, + + "correct file": function(a) { + assert.equal(a(), "This is a"); + } + }, + + "simple file with extension": { + topic: function(context) { + return context("./a.js"); + }, + + "correct file": function(a) { + assert.equal(a(), "This is a"); + } + }, + + "file in folder": { + topic: function(context) { + return context("./lib/complex1"); + }, + + "correct file": function(complex1) { + assert.equal(complex1, "lib complex1"); + } + } + }, + + "polyfill ensure": { + "empty ensure list": { + topic: function() { + var cb = this.callback; + require.ensure([], function(require) { + cb(null, require("./fixtures/a")); + }); + }, + + "executed": function(a) { + assert.equal(a(), "This is a"); + } + }, + "with ensure list": { + topic: function() { + var cb = this.callback; + require.ensure(["./fixtures/a"], function(require) { + cb(null, require("./fixtures/a")); + }); + }, + + "executed": function(a) { + assert.equal(a(), "This is a"); + } + } + }, + + "polyfill loaders": { + "buildin raw loader": { + topic: require("raw!./fixtures/abc.txt"), + + "raw loaded": function(abc) { + assert.equal(abc, "abc"); + } + }, + "buildin json loader": { + topic: require("json!../package.json"), + + "json loaded": function(packageJson) { + assert.equal(packageJson.name, "webpack"); + } + }, + "buildin jade loader": { + topic: function() { + return require("jade!./browsertest/resources/template.jade"); + }, + + "jade loaded": function(template) { + assert.equal(template({abc:"abc"}), "

abc

"); + } + }, + "buildin coffee loader": { + topic: function() { + return require("coffee!./browsertest/resources/script.coffee") || 1; + }, + + "coffee loaded": function(result) { + assert.equal(result, "coffee test"); + } + } + } + + +}).export(module); \ No newline at end of file diff --git a/test/resolve_test.js b/test/resolve_test.js index 131942207..136a94e31 100644 --- a/test/resolve_test.js +++ b/test/resolve_test.js @@ -30,6 +30,7 @@ vows.describe("resolve").addBatch({ "resolve complex 1": testResolve(fixtures, "complexm/step1", path.join(fixtures, "node_modules", "complexm", "step1.js")), "resolve complex 2": testResolve(path.join(fixtures, "node_modules", "complexm", "web_modules", "m1"), "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")), }).export(module); \ No newline at end of file