Angular-CLI and NW.js for development
Tags: angular, nwjs, desktop, xpda
Published: 2019-02-24 17:37:09

![Angular, NW.js, and Angular-CLI Logos](https://thepracticaldev.s3.amazonaws.com/i/qim6c92bwih0ws7imjgw.jpg)

This will walk you through setting up NW.js and Angular-CLI from scratch.

*"Why not just do all this for me and just give me a boilerplate"*

Do you want a fish, or do you want to learn how to fish? Plus, boilerplates already exist, you can look around for them.

* * *

**Editors Note:**

Due to [the limitations of Dev.to](https://github.com/thepracticaldev/dev.to/issues/1855) some codeblocks below are not formatted well. Sorry about that, out of my control.


* * *

## Step 1: Angular CLI

Angular is pretty complex, there's a lot of tooling required to get your standard Angular app up off the ground. Fortunately they offer a tool to generate and scaffold your projects.

1. `npm install -g @angular/cli`
1. `ng new`
 * Fill out the options for app name, routing, Sass pre-processing, etc
 * It will auto-create a folder with your app name
 * The CLI will produce a default project with files and install its dependencies


## Step 2: Verify Angular CLI worked

Before we add anything else, let's just make sure everything is working as expected. We'll navigate to the project folder, start the server and look at it in the browser.

1. `cd your-app-name`
1. `npm start`
 * This will run a local webserver with a note of what port it is running on. For me it was port `4200`.
1. Visit the local server in your browser.
 * http://localhost:4200
1. Open the file `src/app/app.component.ts`
1. Change the `title = 'your-app-name';` to `title = 'Does this update automatically?';`
1. Save the file and look in the browser, after a second or two, you should see the text on the page change automatically!


## Step 3: Adding in NW.js

Now that we know the basic Angular project works as expected, we can start adding NW.js and set this up for development.

1. Kill the local webserver you had running
1. `npm install --save-dev nw@sdk concurrently`
1. Open the `package.json` file
1. In the `"scripts"` section, change:
 * `"start": "ng serve",`
 * to:
 * `"start": "concurrently \"ng serve --port=8964\" \"nw .\"",`
1. On the root of the `package.json` object add these values:
    ```js
    "main": "http://localhost:8964",
    "node-remote": "http://localhost:8964",
    "window": {
      "width": 960,
      "height": 600,
      "min_width": 700,
      "min_height": 500,
      "icon": "your-app-logo.png"
    },
    ```
1. For some (assumingly stupid) reason Angular adds a "global" object when it loads. Since Node.js uses a `global` object in a similar way to how browsers use a `window` object, NW.js exposes it for easy access. We need to move the Node global object somewhere else so that Angular can selfishly use that name space.
1. Open the `src/index.html` file
1. In the `<head>` section add this in:
    ```html
    <script>
      window.nw_global = window.global;
      window.global = undefined;
    </script>
    ```
1. NW.js stores all of it's API in the `window.nw` object, because Angular has this weird *thing* for Typescript, we need to inform it of the existence of `window.nw`.
1. Open the `src/polyfill.ts` and add this:
    ```js
    declare global {
      interface Window {
        nw: any;
      }
    }
    ```


## Step 4: Verifying NW.js loads

1. Now you can run `npm start`
1. NW.js should pop up and try to load the localhost address specified in the `"main"` of `package.json`. Since Webpack takes a while to spin up the local server, you should 
see a message that the page couldn't load. Once the server is up you can refresh the page in NW.js to see the app.
1. The window size will match what was placed in the `"window"` section of `package.json`. There are [many other settings](http://docs.nwjs.io/en/latest/References/Manifest%20Format/#window-subfields) that can be added here as well.
1. **Important Note:** Normally in NW.js you would just access `nw` directly, but due to the glories of Typescript, you must instead access it with `window.nw`. Similarly you would normally be able to access `process` and `require` directly (Node.js specific features), but now you will need to get them from `window.nw.process` and `window.nw.require`. But you still have access to them and can alias them with variables however you like.
1. Let's go back to the file `your-app-name/src/app/app.component.ts`
1. Change the `title = 'Does this update automatically?';` to `title = String(window.nw.require('fs').readFileSync('./package.json'));`
1. Save and you should see the app automatically reload and display the contents of the `package.json` file on the page which was accessed using Node's built-in file system module `fs`. You can also access any 3rd-party node_modules this way.

* * *

## The End

And that's it! You now have a dev environment that runs normally, but inside your desktop app. You can write Angular code and access Node commands right from the DOM!

*But what about packaging for distribution*

We'll have to save that for another time. For now you can look at the NW.js documentation and maybe try it out on a simpler "Hello World" app first, then apply those ideas. Who knows, maybe you'll be the one to write up those instructions for others.

If you have any other issues with Angular and NW.js, look at this Github Issue:

* https://github.com/nwjs/nw.js/issues/6804

**References:**

* [NW-Angular-CLI-Example (GitHub)](https://github.com/nwutils/nw-angular-cli-example)
* [NW.js Docs - Package & Distribute](http://docs.nwjs.io/en/latest/For%20Users/Package%20and%20Distribute/)
* Here's another Dev.To article from me: [Reducing the size of an NW.js app](https://dev.to/thejaredwilcurt/reducing-app-distribution-size-in-nwjs-3d5f)
* [Beginner-friendly NW.js tutorial which includes steps for packaging/distribution at the bottom](https://gitlab.com/TheJaredWilcurt/battery-app-workshop)
* [XPDA.net - Cross-Platform Desktop App tooling comparison](https://xpda.net)