Building a large project with NWJC

1,509 views
Skip to first unread message

be...@orchestrate.io

unread,
Mar 4, 2015, 5:10:06 PM3/4/15
to nwjs-g...@googlegroups.com
I have a large project (about 80 source JS files, in a deeply nested module hierarchy), organized roughly like this:

// myproject/app/index.html
-----------------------------------
<html>
  <script src="vendor/jquery.js" />
  <script src="main.js" />
</html>
-----------------------------------

// myproject/app/main.js
-----------------------------------
"use strict";
var Application = require('./lib/Application');
$(document).ready(function () {
  Application.initialize($, Various, Other, Globals);
});

// myproject/app/lib/Application.js
-----------------------------------
"use strict";
var Application = (function() {
  var MyModule = require("./my/Module");
  var MyOtherModule = require("./my/Other/Module");
  function initialize ($, Various, Other, Globals) {
    MyModule.doStuff();
    MyOtherModule.doOtherStuff();
  }
  exports.initialize = initialize;
})();

Anyhow, this method of organizing my project that has been very effective so far, allowing me to run all of my code in node context (as I've mentioned before https://github.com/nwjs/nw.js/issues/3107 ) but now that I want to take advantage of the new nwjc compiler, I don't know how to build my project. Can I individually compile all the files, maintaining their module hierarchy, or do I need to concatenate them first? Do I need to replace every "require" function call with this:

require('nw.gui').Window.get().evalNWBin(null, 'binary.bin');

If so, it's going to be very difficult to write code that works both in dev mode (with source files) and in production mode (with bin files). Any advice would be much appreciated.

Thanks!

Benji Smith

aidan....@glassechidna.com.au

unread,
Mar 7, 2015, 1:26:28 AM3/7/15
to nwjs-g...@googlegroups.com, be...@orchestrate.io
I'm also extremely interested in an answer to this question. If there are no immediate plans to address this in NW.js itself, there's an opportunity to write a helper tool for this purpose and I might start looking into it.

mikef...@gmail.com

unread,
Mar 13, 2015, 11:35:09 AM3/13/15
to nwjs-g...@googlegroups.com, be...@orchestrate.io
+1 for this.  I am just beginning to use nwjc and have the same development/production issue between the two.  I have combined and minified all of my source with google closure compiler, and then I turn that into a single .bin file which my main HTML page loads in its <script> tag.  Performance is actually quite good so far, and I have not seen the 30% dip.  But using this method requires that every source change I make, I run closure compiler and then nwjc.

In addition to some nice solution to this, I have some other thoughts on the nwjc workflow.

1) "snapshot" in the manifest was a nice feature which seems to be replaced with "bg-script".  Is it possible to bring "snapshot" back to load a .bin on invoking the app?  This would really bring some closure to the loop of viewing or tampering with the application source.
2) Is there any way to run nwjc on the "node-main" script and call that .bin from the manifest; or otherwise protect it?  From my understanding of v8 snapshot, I'm not sure this will even be possible.  My client browser code is protected, but my server code is not.


Thanks to everyone who contributes to this project.  It is awesome, and the way of the future.

Mike

myk...@gmail.com

unread,
Jan 13, 2017, 8:23:59 AM1/13/17
to nw.js, be...@orchestrate.io
Hi, everyone. 
Did anyone got an answer for this issue? 
I've got the same scenario with many javascripts running in the node context and need to turn them to binary.
thanks. 

port...@googlemail.com

unread,
Feb 10, 2017, 7:55:42 PM2/10/17
to nw.js, be...@orchestrate.io, myk...@gmail.com
I've been looking into this lately and I've come to the conclusion that the most sane approach right now is to run the project entry point through browserify, then compile the resulting bundle with nwjc. Some caveats and considerations if you go with this:
  • The nwjc compiler takes literal JS code in, literal JS code in binary form out, hence when require("./something.js") is "compiled" the resulting binary snapshot will not have something.js bundled but instead will look for a something.js file as if the original code had ran. Browserify solves this "problem" by recursively walking through all the project files and inlining all the required modules into a single file, thus enabling nwjc to compile the whole thing by feeding it the entire project in a single file.
  • Make sure to run browserify with the --node flag, otherwise native modules are by default stripped out and you'll lose the node part functionality of NW.js.
  • nw.Window.get().evalNWBin runs the binary in window context, which means that using the browserify approach all your (non-native) requires will run in window context too. This *could* cause discrepancies since in non-browserified code 'requires' run in node context, though in practice I haven't found this to be too problematic since you can still require native node modules or use the shared 'global' node object. NW.js has a "mixed context" mode via the "--mixed-context" flag that you could look into if the context difference becomes problematic.
  • For best results dealing with context differences I recommend having the entry point of the app in window context, i.e. point to an html file in your package.json and load a js file via the script tag from there. If you do this you can safely replace your '<script src="/app.js"></script>' with '<script>nw.Window.get().evalNWBin(null, 'app.bin');</script>' and have the exact same context in the entry point of both scenarios.
  • Don't forget that nwjc is platform dependent, you can run browserify once for all platforms, but you need to compile the resulting bundle in each platform separately (i.e. Windows, Linux, MacOS)
All in all, compiling large projects with nwjc can be viable, but it's not a particularly mature, documented or battle tested compiler, so keep that in mind. You'll have to do your own assessment and extensive testing to see if it works for your particular project.
Reply all
Reply to author
Forward
0 new messages