JavaScript (Rhino) use library or include other scripts
Asked Answered
K

4

28

In JDK6, is there a way to load multiple scripts, each in a file, and have the one script reference a method of another script? Sort of like "include"?

Kneeland answered 16/3, 2009 at 13:14 Comment(0)
S
31

I think you're after the load() method/property of Rhino's global object/scope

load("file1.js");
load("file2.js");
load("file3.js");

methodFromFileOne();
var bar = methodFromFileTwo();
var etc = dotDotDot();

This will load a javascript source file, similar to how include/require will in PHP. Once you load a file, you'll be able to call and function or use any object defined in the loaded file.

This is how things work when you're using the Rhino shell, which is the only context I know (your question mentioned the Java SDK, which is outside my area of experience)

Segalman answered 16/3, 2009 at 18:31 Comment(2)
Is this available outside of the Rhino shell?Odo
Not sure, that's not my pay rate. (updated the question to reflect that)Segalman
B
10

if you happen to be trying to do this within ant, you might see this error:

<script language="javascript">
    load('foo.js');
</script>
javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: TypeError: Cannot find function load.

but you can sidestep it:

<script language="javascript">
    eval(''+new String(org.apache.tools.ant.util.FileUtils.readFully(new java.io.FileReader('foo.js'))));
</script>
Bruner answered 19/8, 2011 at 18:28 Comment(1)
The >>''+<< is of major importance here!Flux
D
10

A real-life example this time, i.e. running the esprima parser with Rhino 1.7R4.

import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
...

Context context = Context.enter();
Scriptable globalScope = context.initStandardObjects();
Reader esprimaLibReader = new InputStreamReader(getClass().getResourceAsStream("/esprima.js"));
context.evaluateReader(globalScope, esprimaLibReader, "esprima.js", 1, null);

// Add a global variable out that is a JavaScript reflection of the System.out variable:
Object wrappedOut = Context.javaToJS(System.out, globalScope);
ScriptableObject.putProperty(globalScope, "out", wrappedOut);

String code = "var syntax = esprima.parse('42');" +
    "out.print(JSON.stringify(syntax, null, 2));";

// The module esprima is available as a global object due to the same
// scope object passed for evaluation:
context.evaluateString(globalScope, code, "<mem>", 1, null);
Context.exit();

After running this code, you should see the output as follows:

{
  "type": "Program",
  "body": [
    {
      "type": "ExpressionStatement",
      "expression": {
        "type": "Literal",
        "value": 42,
        "raw": "42"
      }
    }
  ]
}

So indeed, the trick is in reusing the globalScope object.

Dieselelectric answered 29/4, 2013 at 13:24 Comment(0)
D
6

As long as you use the same scope to execute each file, they will be able to reference functions and variables from previously executed files.

Drying answered 16/3, 2009 at 15:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.