Skip to content

Calling Optimizer Programmatically via Rhino #382

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
semperos opened this issue Feb 15, 2013 · 10 comments
Closed

Calling Optimizer Programmatically via Rhino #382

semperos opened this issue Feb 15, 2013 · 10 comments
Milestone

Comments

@semperos
Copy link

I see at this line, that the function for optimize is added to the requirejs object at this point in the code:

https://github.com/jrburke/r.js/blob/3401eeee35d4fe750139efc2c128ac325abf9ccb/dist/r.js#L23891

This doesn't seem to account for Rhino, and when I inspect the requirejs object via Rhino, I see that 'optimize' is not one of the available fields. Is this intentional? Is there a way other than requirejs.optimize that one calls the optimizer programmatically via Rhino?

@semperos
Copy link
Author

I apologize if I posted this prematurely. I may just not be loading it up correctly.

Using this:

require(['requirejs'], function(requirejs) {
    // call requirejs.optimize with config
}

I now just get the error that load is not defined. I saw mention of needing to define this. Is there an example implementation lying around for the use case of calling the optimizer programmatically via Rhino? I've found http://stackoverflow.com/a/11075667/339701 , but was curious if there's something you have "lying around" or would suggest.

@jrburke
Copy link
Member

jrburke commented Feb 15, 2013

Correct, right now optimize() is not exposed to rhino. If a rhino branch was added after this:
https://github.com/jrburke/r.js/blob/master/build/jslib/x.js#L264

and createRjsApi(); was called in there (not sure what to set for baseUrl), then I would probably work. However, I have not done the work to try it and test it out. If you want to give it a shot and see how it goes, I'm all for that.

After doing that change in x.js, then run node dist.js at the top of the repo to generate an r.js at the top of the repo. Try that r.js to see if you can run optimize()

@semperos
Copy link
Author

Great, thanks for that. I'll give all that a spin and see if I can't get things working.

@semperos
Copy link
Author

Yep, I was able to add that section and then, as a stand-in, use "." as the baseUrl and it worked!

diff --git a/build/jslib/x.js b/build/jslib/x.js
index 83b5253..27186fb 100644
--- a/build/jslib/x.js
+++ b/build/jslib/x.js
@@ -266,6 +266,10 @@ var requirejs, require, define;
         setBaseUrl(location.href);
         createRjsApi();
         return;
+    } else if (env === 'rhino') {
+        setBaseUrl('.');
+        createRjsApi();
+        return;
     }

     if (commandOption === 'o') {

I'm certain this is not comprehensive enough, given the checking you do in the node section of this conditional, but at least I can verify that it works. I still encountered some exceptions, but I think that lies in my own code. I'll let you know if I have any more info.

@jrburke
Copy link
Member

jrburke commented Feb 18, 2013

Maybe for the rhino case, it should be setBaseUrl(fileName); since fileName is the script that will be executed by r.js.

@semperos
Copy link
Author

That makes the most sense to me.
On Feb 18, 2013 6:47 PM, "James Burke" [email protected] wrote:

Maybe for the rhino case, it should be setBaseUrl(fileName); since
fileName is the script that will be executed by r.js.


Reply to this email directly or view it on GitHubhttps://github.com//issues/382#issuecomment-13749546.

@jrburke
Copy link
Member

jrburke commented Feb 20, 2013

The other trick with that piece of code -- it knows to bail early instead of processing command line args because in node, it figures out it is called as a module, and in the browser, it can only be used a library. However, for rhino, the primary use case is command line arg processing.

Can you describe how you loaded the r.js file in rhino, and what thing I could detect to know if it was OK to do the createRjsApi() work and return early because r.js is being used like a library and not a command line tool?

@semperos
Copy link
Author

I'd have to do a little research to see if there were anything that could be checked programmatically to differentiate between running r.js on the command-line vs. as a library. At the very least, I'm sure we could use some Java reflection facilities to see how the current Rhino environment has been started or is running from inside r.js itself. I'll report back if/when I figure something out.

As for my own use of r.js programmatically, I do the following:

  • Focus solely on JS optimization at this point
  • Provide the user an interface to specify which modules are the "main" ones that need to be optimized in their JS codebase
  • Enhance the Rhino runtime with needed functions (like print which are not defined by default, and which in my case proxy out to a Log4j Logger instance) and an internal object I use (I'm also doing things like compiling CoffeeScript and LESS via Rhino)
  • Evaluate the r.js source inside Rhino
  • Create a separate single-file r.js build config for each of the main modules specified by the user and store this in my internal object
  • Evaluate a short bit of my own JavaScript inside Rhino that takes those separate build configs, iterates through them and calls the optimizer with each

So from a Rhino perspective, I start up Rhino, I setup a few definitions, then I evaluate all of r.js by passing in a Reader instance to Rhino, which then reads the contents of the file and evaluates it. After all of that is in place, I evaluate a last little bit of custom JavaScript that ties it all together and calls the optimizer via requirejs.optimizer.

@semperos
Copy link
Author

Alright, found out. When you run Rhino from the command-line, you should have access to an environment object, defined in the global namespace. This is undefined when using Rhino programmatically, but is defined and has keys for all sorts of Java properties when run from the command-line. I've tested it myself, running a JavaScript REPL with Rhino from the command-line and running my own code programmatically, but I'd be curious to know if you get the same results.

@jrburke jrburke closed this as completed in 445ac65 Mar 4, 2013
@jrburke
Copy link
Member

jrburke commented Mar 4, 2013

The environment test did not work out for my test cases, just using rhino's load function, so I went with checking for a variable name. If you set requirejsAsLib = true before loading r.js has a script, it will work. See build.js and run.js in the tests/rhino directory.

If we figure out something later that works better that would be great, but for now it is usable.

Try the master snapshot to confirm that it works for you, but I also hope to do a 2.1.5 release within the next day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants