views:

62

answers:

2

How do you "require" another file into the existing file in Javascript? Is there anything similar to Ruby's "require" or "load"?

> Note: I'm using JS in server (Rhino)

Reason: I just need to access the methods in the other JS files.

Update: This works only when executing it from cmd line. When I try to call it programatically it fails. Here's my code: http://pastie.org/1240495

+2  A: 

In Rhino shell, you can should be able to use load(), which is a predefined global method:

load([filename, ...])

Load JavaScript source files named by string arguments. If multiple arguments are given, each file is read in and executed in turn.

Daniel Vassallo
No, it doesn't work for me. I'm getting an error. Here's the code+errors: http://pastie.org/1241101
instantsetsuna
@instantsetsuna: It works for me... Do the other predefined functions work? like `print()`?
Daniel Vassallo
No, print() isn't working either. I'm using mozilla rhino 1.7r2, not the one the comes with the JDK. Maybe the difference is due to this?
instantsetsuna
That's weird. Upstream rhino definitely bundles load() and print() as part of its default environment. How are you executing it? "java -jar js.jar"?
echo-flow
@Echo: I've updated my question. It works fine from cmd line, but it fails when embedded inside java.
instantsetsuna
@instantsetsuna: please see my answer below
echo-flow
+2  A: 

To use the load function in js embedded from Java, you must first expose it in on the scripting context. There's probably a way to do it from Java, but you can do it using js as well.

Disclaimer: this solution uses source code taken from an Apache-licensed project I have been working on. You can see the original source file here.

This js file sets up your global variables, and lives in a file named setupglobals.js:

var shell = org.mozilla.javascript.tools.shell.Main;
var args = ["-e","var a='STRING';"];
shell.exec(args);

var shellGlobal = shell.global;

//grab functions from shell global and place in current global
load=shellGlobal.load;
print=shellGlobal.print;
defineClass=shellGlobal.defineClass;
deserialize=shellGlobal.deserialize;
doctest=shellGlobal.doctest;
gc=shellGlobal.gc;
help=shellGlobal.help;
loadClass=shellGlobal.loadClass;
quit=shellGlobal.quit;
readFile=shellGlobal.readFile;
readUrl=shellGlobal.readUrl;
runCommand=shellGlobal.runCommand;
seal=shellGlobal.seal;
serialize=shellGlobal.serialize;
spawn=shellGlobal.spawn;
sync=shellGlobal.sync;
toint32=shellGlobal.toint32;
version=shellGlobal.version;
environment=shellGlobal.environment;

Here is your original Java host file, now augmented to evaluate setupglobals.js before any other scripts:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import org.mozilla.javascript.*;

public class RhinoRunner {
    public static void main(String args[]) throws IOException 
    {
        BufferedReader script = new BufferedReader(new FileReader("setupglobals.js"));
        BufferedReader script2 = new BufferedReader(new FileReader("example.js"));
        Context context = Context.enter();
        try {
            ScriptableObject scope = context.initStandardObjects();
            context.evaluateReader(scope, script, "script", 1, null);
            context.evaluateReader(scope, script2, "script2", 1, null);
            Function fct = (Function)scope.get("abc", scope);
            Object result = fct.call(context, scope, scope, new Object[] {2, 3});
            System.out.println(Context.jsToJava(result, int.class));
        } 
        finally 
        {
            Context.exit();
        }
    }
}

Here is your example.js, now augmented to use the global load function to load the file hello.js:

function abc(x,y) 
{
    return x+y 
}

load("hello.js")

And finally, here is hello.js:

print("hello world!")

When executed, RhinoRunner prints the following:

hello world!
5
echo-flow
Wow! It works perfectly! Thank you very much! :) If you don't mind, can you explain what's happening in the first few lines of setupglobals.js?
instantsetsuna
It sets up and executes a Rhino shell. It's a bit magical, but it works.
echo-flow
Oh, Thanks anyway! :)
instantsetsuna