From 96cc08ac4a1066344f4d57726c17be117a7113ef Mon Sep 17 00:00:00 2001 From: jrburke Date: Wed, 10 Feb 2010 22:06:16 -0800 Subject: [PATCH] RequireJS support in Rhino --- README.md | 19 +++ require.js | 4 +- require/rhino.js | 30 +++++ tests/all-rhino.js | 28 +++++ tests/circular-tests.js | 25 ++++ tests/circular.html | 28 +---- tests/doh/runner.js | 257 ++++++++++++++++++++-------------------- tests/doh/runner.sh | 2 +- tests/simple-tests.js | 18 +++ tests/simple.html | 21 +--- 10 files changed, 255 insertions(+), 177 deletions(-) create mode 100644 require/rhino.js create mode 100644 tests/all-rhino.js create mode 100644 tests/circular-tests.js create mode 100644 tests/simple-tests.js diff --git a/README.md b/README.md index 894a80b93..0745d28e8 100644 --- a/README.md +++ b/README.md @@ -341,6 +341,7 @@ Some advanced features: * Loading code after page load * require.pause()/require.resume() for build layers/bundles * Module Modifiers +* Rhino support ## Multiversion Support @@ -475,6 +476,24 @@ For the example given above in Modifier Registration, where "my/target1" is the } ); +## Rhino Support + +RequireJS can be used in Rhino, just be sure to load require.js and require/rhino.js before doing any require calls: + + load("requirejs/require.js"); + load("requirejs/require/rhino.js"); + + //Set up any config values, baseUrl is required so module names + //will map correctly to paths. + require({ + baseUrl: 'path/to/scripts' + }); + + //Now load the top level script. + require(['startingscript']); + +You can see an example of RequireJS working in Rhino by looking at [tests/all-rhino.js](tests/all-rhino.js). The test file is a bit different from above since each test sets its own baseUrl. + # History and Influences I work a lot on the Dojo Loader. The normal dojo loader uses synchronous XMLHttpRequest (XHR) calls. However, the XHR loader cannot load Dojo modules from other domains because of the same-origin restrictions. So I created the xdomain loader that required a build step to inject function wrappers similar to what RequireJS uses, but more complex, due to i18n bundle loading and dojo.requireIf behavior. Because of the more complex i18n and requireIf requirements and the existence of many dojo modules already out in the world, I did not feel like the Dojo community would consider writing modules with function wrappers manually. diff --git a/require.js b/require.js index dd98d6df2..e5604a827 100644 --- a/require.js +++ b/require.js @@ -94,7 +94,7 @@ var require; //Do more work, either return require.def.apply(require, arguments); - } + }; /** * The function that handles definitions of modules. Differs from @@ -614,7 +614,7 @@ var require; * * @returns {Object} the exported module value. */ - require.get = function(moduleName, contextName) { + require.get = function (moduleName, contextName) { if (moduleName === "exports" || moduleName === "module") { throw new Error("require of " + moduleName + " is not allowed."); } diff --git a/require/rhino.js b/require/rhino.js new file mode 100644 index 000000000..394904e4c --- /dev/null +++ b/require/rhino.js @@ -0,0 +1,30 @@ +/** + * @license RequireJS rhino Copyright (c) 2010, The Dojo Foundation All Rights Reserved. + * Available via the MIT, GPL or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +/*global require: false, readFile: false */ + +/* +TODO: Work out relative paths, that use ./ and such, and allow loading normal +CommonJS modules, by overriding require.get(). +*/ + +/*globals load: false */ +"use strict"; + +require.load = function (moduleName, contextName) { + var url = require.nameToUrl(moduleName, null, contextName), + context = require.s.contexts[contextName]; + + //isDone is used by require.ready() + require.s.isDone = false; + + //Indicate a the module is in process of loading. + context.loaded[moduleName] = false; + + load(url); + + //Mark the module loaded. + context.loaded[moduleName] = true; +}; diff --git a/tests/all-rhino.js b/tests/all-rhino.js new file mode 100644 index 000000000..2d45e8336 --- /dev/null +++ b/tests/all-rhino.js @@ -0,0 +1,28 @@ +/** + * Run the tests in Rhino via this command: + * java -jar ../build/lib/rhino/js.jar all-rhino.js + * + * To run with debugger: + * java -classpath ../build/lib/rhino/js.jar org.mozilla.javascript.tools.debugger.Main all-rhino.js + */ + +//A hack to doh to avoid dojo setup stuff in doh/runner.js +skipDohSetup = true; + +//Load test framework +load("doh/runner.js"); +load("doh/_rhinoRunner.js"); + +//Load require with rhino extension +load("../require.js"); +load("../require/rhino.js"); + +//Load the tests. +load("simple-tests.js"); +load("circular-tests.js"); +load("depoverlap-tests.js"); + +//Hmm, this is an odd requirement, call doh.run() for each test listed above? +//May be because the tests above call doh.run() in a callback sometimes? +doh.run(); +doh.run(); diff --git a/tests/circular-tests.js b/tests/circular-tests.js new file mode 100644 index 000000000..c296680bb --- /dev/null +++ b/tests/circular-tests.js @@ -0,0 +1,25 @@ +require({ + baseUrl: "./" + }, + ["require", "two", "funcTwo", "funcThree"], + function(require, two, funcTwo, funcThree) { + var args = two.doSomething(); + var twoInst = new funcTwo("TWO"); + doh.register( + "circular", + [ + function circular(t) { + t.is("small", args.size); + t.is("redtwo", args.color); + }, + + function circularFunc(t) { + t.is("TWO", twoInst.name); + t.is("ONE-NESTED", twoInst.oneName()); + t.is("THREE-THREE_SUFFIX", funcThree("THREE")); + } + ] + ); + doh.run(); + } +); diff --git a/tests/circular.html b/tests/circular.html index 594723402..70d4eadc4 100644 --- a/tests/circular.html +++ b/tests/circular.html @@ -5,33 +5,7 @@ - +

require.js: Circular Test

diff --git a/tests/doh/runner.js b/tests/doh/runner.js index eccb81c57..a0c7d060d 100644 --- a/tests/doh/runner.js +++ b/tests/doh/runner.js @@ -1367,130 +1367,133 @@ doh.average = function(/* Number [] */ a){ tests = doh; -(function(){ - // scope protection - var x; - try{ - if(typeof dojo != "undefined"){ - dojo.platformRequire({ - browser: ["doh._browserRunner"], - rhino: ["doh._rhinoRunner"], - spidermonkey: ["doh._rhinoRunner"] - }); - try{ - var _shouldRequire = dojo.isBrowser ? (dojo.global == dojo.global["parent"] || !Boolean(dojo.global.parent.doh) ) : true; - }catch(e){ - //can't access dojo.global.parent.doh, then we need to do require - _shouldRequire = true; - } - if(_shouldRequire){ - if(dojo.isBrowser){ - dojo.addOnLoad(function(){ - if (dojo.global.registerModulePath){ - dojo.forEach(dojo.global.registerModulePath, function(m){ - dojo.registerModulePath(m[0], m[1]); - }); - } - if(dojo.byId("testList")){ - var _tm = ( (dojo.global.testModule && dojo.global.testModule.length) ? dojo.global.testModule : "dojo.tests.module"); - dojo.forEach(_tm.split(","), dojo.require, dojo); - setTimeout(function(){ - doh.run(); - }, 500); - } - }); - }else{ - // dojo.require("doh._base"); - } - } - }else{ - if(typeof load == "function" && - (typeof Packages == "function" || typeof Packages == "object")){ - throw new Error(); - }else if(typeof load == "function"){ - throw new Error(); - } - - if(this["document"]){ - /* - // if we survived all of that, we're probably in a browser but - // don't have Dojo handy. Load _browserRunner.js using a - // document.write() call. - - // find runner.js, load _browserRunner relative to it - var scripts = document.getElementsByTagName("script"), runnerFile; - for(x=0; x"); - } - */ - } - } - }catch(e){ - print("\n"+doh._line); - print("The Dojo Unit Test Harness, $Rev: 20389 $"); - print("Copyright (c) 2009, The Dojo Foundation, All Rights Reserved"); - print(doh._line, "\n"); - - try{ - var dojoUrl = "../../dojo/dojo.js"; - var testUrl = ""; - var testModule = "dojo.tests.module"; - var dohBase = ""; - for(x=0; x"); + } + */ + } + } + }catch(e){ + print("\n"+doh._line); + print("The Dojo Unit Test Harness, $Rev: 20389 $"); + print("Copyright (c) 2009, The Dojo Foundation, All Rights Reserved"); + print(doh._line, "\n"); + + try{ + var dojoUrl = "../../dojo/dojo.js"; + var testUrl = ""; + var testModule = "dojo.tests.module"; + var dohBase = ""; + for(x=0; x - +

require.js: Simple Test