diff --git a/lib/module.js b/lib/module.js index 308fd4e8e308..ba8862aa9d8a 100644 --- a/lib/module.js +++ b/lib/module.js @@ -380,6 +380,44 @@ Module.prototype._compile = function(content, filename) { } require.cache = Module._cache; + function define(id, dependencies, factory) { + var deps, fac, len; + // id is always ignored + + // decode arguments + len = arguments.length; + if (len == 3) { + deps = dependencies; + fac = factory; + } else { + if (len == 1) { + fac = arguments[0]; + deps = ["require", "exports", "module"]; + } else { + if (Array.isArray(id)) { + deps = id; + } else { + deps = ["require", "exports", "module"]; + } + fac = dependencies; + } + } + define.amd = {}; + + // validate argument types? + args = deps.map(function(dep) { + return { + "require": require, + "exports": self.exports, + "module": self + }[dep] || require(dep); + }); + + var exports = fac.apply(global, args); + if (exports) + self.exports = exports; + } + var dirname = path.dirname(filename); if (Module._contextLoad) { @@ -391,6 +429,7 @@ Module.prototype._compile = function(content, filename) { sandbox[k] = global[k]; } sandbox.require = require; + sandbox.define = define; sandbox.exports = self.exports; sandbox.__filename = filename; sandbox.__dirname = dirname; @@ -404,6 +443,7 @@ Module.prototype._compile = function(content, filename) { debug('load root module'); // root module global.require = require; + global.define = define; global.exports = self.exports; global.__filename = filename; global.__dirname = dirname; @@ -419,7 +459,7 @@ Module.prototype._compile = function(content, filename) { if (filename === process.argv[1] && global.v8debug) { global.v8debug.Debug.setBreakPoint(compiledWrapper, 0, 0); } - var args = [self.exports, require, self, filename, dirname]; + var args = [self.exports, require, self, define, filename, dirname]; return compiledWrapper.apply(self.exports, args); }; diff --git a/src/node.js b/src/node.js index 1f512a5f6f17..e88f09a45078 100644 --- a/src/node.js +++ b/src/node.js @@ -436,7 +436,7 @@ }; NativeModule.wrapper = [ - '(function (exports, require, module, __filename, __dirname) { ', + '(function (exports, require, module, define, __filename, __dirname) { ', '\n});' ]; diff --git a/test/fixtures/amd/explicit_deps.js b/test/fixtures/amd/explicit_deps.js new file mode 100644 index 000000000000..21b07fe0af36 --- /dev/null +++ b/test/fixtures/amd/explicit_deps.js @@ -0,0 +1,5 @@ +define(["fs"], function(fs) { + return { + args: arguments + } +}); \ No newline at end of file diff --git a/test/fixtures/amd/return_exports.js b/test/fixtures/amd/return_exports.js new file mode 100644 index 000000000000..9831119470a1 --- /dev/null +++ b/test/fixtures/amd/return_exports.js @@ -0,0 +1,5 @@ +define(function(require, exports, module) { + return { + foo: "bar" + } +}); \ No newline at end of file diff --git a/test/fixtures/amd/simple.js b/test/fixtures/amd/simple.js new file mode 100644 index 000000000000..386f7e0b610a --- /dev/null +++ b/test/fixtures/amd/simple.js @@ -0,0 +1,8 @@ +define(function(require, exports, module) { + + // check for module and exports argument + exports.id = module.id; + + // check require + exports.fs = require("fs"); +}); \ No newline at end of file diff --git a/test/simple/test-module-amd.js b/test/simple/test-module-amd.js new file mode 100644 index 000000000000..d5dda5f4ceed --- /dev/null +++ b/test/simple/test-module-amd.js @@ -0,0 +1,42 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var common = require('../common'); +var assert = require('assert'); +var path = require('path'); +var fs = require('fs'); + +// the canonical way +common.debug('test load AMD with only a factory defined should default to require, exports, module'); + +var m = require("../fixtures/amd/simple.js"); +assert.ok(m.id.match(/fixtures\/amd\/simple\.js$/)); +assert.equal(m.fs, fs); + +common.debug("test return value from factory should take this as exports"); +var m = require("../fixtures/amd/return_exports.js"); +assert.equal(m.foo, "bar"); + +// the dojo way +common.debug("test load AMD with explicit dependencies"); +var m = require("../fixtures/amd/explicit_deps.js"); +assert.equal(m.args.length, 1); +assert.equal(m.args[0], fs); \ No newline at end of file