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?