Ok, so r.js can run on Rhino. Which is great.
To do the stuff it needs to do.
On rhino it basically uses java.io.File, java.io.FileOutputStream and java.io.FileInputStream to achieve the filesystem modifications that it needs to do.
(Background: I am working on delivering a better development experience for Maven based Java/Javascript developers. Being Maven, there is the power of convention and the power of being opinionated. You can see the progress at jszip.org.)
So what I want to do is have the on-disk structure appear by magic as a virtual file system.
So on disk we will have a structure like so:
/
/module1/src/main/js/controllers/controller.js
/module2/src/main/js/models/model.js
/module3/src/main/js/views/view.js
/webapp/src/build/js/profile.js
/webapp/src/main/js/main.js
/webapp/src/main/webapp/index.html
The /webapp/src/build/js/profile.js should look something like this:
({
appDir: "src",
baseUrl:".",
dir: "target",
optimize: "closure",
modules:[
{
name:"main"
}
]
})
Such that
when r.js asks for
new File("src/main.js")I will actually give itnew File("/webapp/src/main/js/main.js")when it asks for
new File("profile.js")I will give itnew File("/webapp/src/build/js/profile.js")when it asks for
new File("controllers/controller.js")I will give itnew File("/module1/src/main/js/controllers/controller.js")when it asks for
new File("target")I will give itnew File("/webapp/target/webapp-1.0-SNAPSHOT").
I have no issue writing the three mock classes required, i.e. the ones to use in place of java.io.File, java.io.FileInputStream and java.io.FileOutputStream,
Some questions such as this have answers that point to things like ClassShutter, which I can see I could use like this:
context.setClassShutter(new ClassShutter() {
public boolean visibleToScripts(String fullClassName) {
if (File.class.getName().equals(fullClassName)) return false;
if (FileOutputStream.class.getName().equals(fullClassName)) return false;
if (FileInputStream.class.getName().equals(fullClassName)) return false;
return true;
}
});
To hide the original implementations.
The problem is then getting Rhino to resolve the sandboxed equivalents... I keep on getting
TypeError: [JavaPackage java.io.File] is not a function, it is object.
Even if I prefix the call with a prior execution of java.io.File = org.jszip.rhino.SandboxFile map my sandboxed implementation over the now missing java.io.File
I could even consider using search and replace on the loaded r.js file just prior to compiling it... but I feel there must be a better way.
Does anyone have any hints?