Node-Webkit, ES6, AMD, and CommonJS [resolved!]

I’m really excited by the possibility of creating rich, cross platform desktop applications using Node-Webkit and Ember. Ember is perfectly suited for long-running apps, and the idea that we can break out of the web browser seems like a game changer.

With this in mind I’ve tried to setup a basic application. Ideally, I’d like to use the Ember-CLI workflow to build out the app, but I’ve run into some problems. Specifically, Node.js uses CommonJS requires, while Ember is compiled down from ES6 to AMD. Within the node-webkit app, when I use the require command, it assumes I’m using the CommonJS require and promptly explodes.

Has anyone had any luck compiling Ember down to CommonJS? Or likewise has anyone been able to get Node-Webkit up and running with Ember using the module pattern (I was able to get a browser version running… but it feels dirty…)?

I’m pretty new to modules and server side JS in general, so please be gentile with your responses and judgements. :blush:

As far as I’m concerned, you can’t do that. The only way to load Ember is a script tag. If you could event compile it to CommonJS module, it wouldn’t work in node’s context (it has no window). After it is loaded you can pass Ember and window to node’s context and work as usual.

Node-Webkit definitely exposes the window object (it’s webkit, but you can use native node modules). I think getting the window context into a module would be as simple as passing it in as a dependency.

sure, you can pass window and event attach it to global, but still there is not guarantee that Ember will initialize itself properly. My opinion, it safer and easier to load it in window context. The only caveat (at least, the only one I’ve discovered) is that you need to copy all Ember-specific prototype extensions from window-context globals to node.

I think @vkurchatkin is right, Ember can only be loaded through a script tag. Maybe it is possible to serve Ember through something like webpack, or similar, but i doubt the advantages one would get from it.

i have successfully deployed a node-webkit based app using a live-reload server in conjunction with node-webkit in dev (not serving files, just notifying on changes) mode and then build and package it for production. Brunch was used as the build tool by that time as ember-cli wasn’t ready to use yet. It works well, runs your tests in node-webkit and also keeps your file sizes down in production. I remember also testing EAK without errors.

To load node modules in my Ember code i stubbed out the require as node_require. That way it was easily possible to load files from disk, etc. node_require-ing path, fsor other modules, such as iniparser.

What you could try is to use an AMD module for nodejs loader such as the es6-module-loader. But i guess the window context will get you into trouble. Afaik, there is an ember npm package, but it is quite outdated and i wasn’t really able to build it from source either.

I think it would be good to sort out, what the benefits are using Ember on a cjs/amd module basis without a build chain.

When you’re building your app, are you using ES6 modules? That’s pretty much what I’m looking for since the testing story around Ember almost requires them now.

I would love to see how you setup the require stuff. It sounds like you’re just aliasing node’s native require method with node_require, which is awesome. Are you just then overriding node’s require method with the browser based AMD require?

Specifically, when the ES6 transplier transpiles down to AMD, which uses require to import modules - how do override nodes default require with the new AMD based one?

I’ve added a basic example repo. It is literally just a shiny new Ember-CLI app and the most recent version of node-webkit. When you boot the app you’ll see the error I’m talking about:

If anyone could help me get these requires figured out, I would be forever greatful.

hi @Emerson, yes, i stubbed out the require from node in my index.html as such:

    if (window.nwDispatcher) {
      window.win = require('nw.gui').Window.get();
      window.node_require = window.require;
      window.require = undefined;
    }
```
any other place did not seem to work properly. `AMD`s own `require` was exactly the issue i had to do it also.
with that Embers own loader worked fine. Also, i used `Brunch` as my build chain, this might have differences on how the modules (browser ones) might be resolved as all the js get concatenated into one.

unfortunately i have don't have time left today, but i will have a look at your example repo tomorrow, as i am also interested in a nice boilerplate for such projects.

i'll report.

PS.: Note, that the above snippet has be located before any other script is loaded or put in a script-tag.

Thanks for the help - looking forward to trying your technique. I’ve just noticed that my repo has a bunch of problems, but I can’t really fix them at the moment because Ember-CLI is totally broken right now: https://github.com/stefanpenner/ember-cli/issues/265.

Also, I’ve realized that Ember-CLI serves a dynamic app.js file in development, which makes it potentially impossible to use within Node-Webkit.

Yes, your repo is strange; no offense. I had to fix quite a bit by using a freshly generated ember-cli app, based on the most recetn version 0.0.22 as of now. I got ember server working again. But, yes, the dynamically generated tree served by broccoli under the hood makes it very hard to use it with node-webkit. This is also the main difference to my setup as Brunch writes the files to disk on changes. Although makes broccoli faster, one would have to write a broccoli-plugin that writes files to disk (to be picked up by node-webkit) and runs a livereload server that notifies on changes!? I had a look in the broccoli source – it doesn’t seem to be hard, like a merge from build and serve.

I will try to skin down my project with Brunch and put it up in a repo as a scaffold, just can’t do it right away, sorry. You might want to consider to use either the node-webkit npmmodule or the grunt-node-webkit-builder to get hold of node-webkit instead of putting a version in your repo. I should put up my scaffold asap, it makes clear how it works.

All good - I think it’s not that far off actually, it’s just a question of getting ember-cli to optionally rebuild static assets rather than always serving them dynamically.

I’m in the midst of requesting a new feature on ember-cli, I’m suggesting that we add a ember build --watch command that would rebuild the assets when they change.

I’ll report back when I hear more about this. I tried to investigate adding this myself, but I think it’s a bigger question that the maintainers need to chime in on.

I actually have an app up and running within Node-Webkit, but it’s using gulp to build everything. It works for now, but I was really hoping to take advantage of all the ES6 testing goodness.

Alright - I believe I have things up and running properly now.

I’ve filled an issue with ember-cli and have updated my example repo. Things appear to be working well (note: that you can remove the web toolbar by editing the package.json file).

1 Like

Great work and I love the fact you made a repository for this. It will certainly help others who go down this road!

Nice! I agree, it is good idea to have a ember build --watch or ember watch command. that would make integrating easier.

i also found time to strip down my project to a boilerplate. you can find it here: https://github.com/jens-a-e/ember-nw

It does not package node-webkitbut makes it easy to install and available for builds through the grunt-node-webkit-builder module. This is very nice to do x-platforms builds from one machine too.

feedback welcome!

ps. live-reload works too. so, no need to re-start node-webkit on any change :wink:

@Emerson awesome work! any luck progressing this issue any further? I notice your Issue was closed on github and all my googling has turned up nothing but dead ends

I’m interested in using your example repo but i’m just wondering how it has stood the test of time. Ember-Cli is moving crazy fast :wink:

Hey @real_ate,

I’ve been caught up in another project and haven’t been actively developing my node-webkit app. In all honesty, it ended up feeling a little weird, primarily due to issues around require statements (node require vs ember-cli require).

If I was going to do this again, I would probably look at Atom Shell used by Github’s atom.io editor. It sounds like they’ve solved many of the problems associated with node-webkit.

Hi @real_ate, did you have any success with your project? I’ve tried a bunch of things myself for a project I’m working on but haven’t been able to get anything going yet. :smile:

I’ve managed to get it working:

  • Using the latest Ember-CLI

  • No shims required

  • set main in package.json (for the node-webkit build) as app://yourcoolapp/dist/index.html (I plan to update this so the dist folder isn’t needed in mine).

  • set base href to match instead of using ‘/’:

    <base href=“app://yourcoolapp/dist/”>

  • Set router location to ‘hash’ so it doesn’t try to point to different files (since it’s served over file protocol).

I think that is all that was needed to get it going (although it took a bit of mucking around to get there). We’ll see what happens when I try to start linking in with more of node’s features. If I have a chance in a couple of weeks once this project’s wrapped up I’ll see if I can set up a pull request on @Emerson’s project.

:smiley: