Skip to content

Commit

Permalink
feat: install multiple binaries (#138)
Browse files Browse the repository at this point in the history
Closes: #47
  • Loading branch information
ayushmanchhabra authored Mar 25, 2024
1 parent 0e318cc commit 615f661
Show file tree
Hide file tree
Showing 17 changed files with 439 additions and 800 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ jobs:
- name: Enable corepack
run: corepack enable
- name: Install dependencies
run: npm ci
run: npm ci --nwjs-build-type=sdk
- name: Run test
run: npm test
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,49 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

## [0.85.0-1]

### Added

- Option to specify cache directory by setting `nwjs_cache_dir` in `.npmrc` or `NWJS_CACHE_DIR` as ENV variable. Defaults to `./node_modules/nw`.

- Option to customise caching behaviour by enabling/disabling `nwjs_cache` in `.npmrc` or `NWJS_CACHE` as ENV variable. Defaults to `false`.

- Option to download community ffmpeg by enabling/disabling `nwjs_ffmpeg` in `.npmrc` or `NWJS_FFMPEG` as ENV variable. Defaults to `false`.

- Option to download NW.js Node headers by enabling/disabling `nwjs_native_addon` in `.npmrc` or `NWJS_NATIVE_ADDON` as ENV variable. Defaults to `false`.

### Changed

Switch from CJS to ESM.

ESM import:

```javascript
import { findpath } from 'nw';
```

Previous CJS import:

```javascript
const { findpath } = require('nw');
```

Current CJS import:

```javascript
let nw;
import('nw').then(object => {
nw = object;
});
```

### Removed

- CJS support.
- `compressing` package.
- `cli-progress` package.

## [0.85.0]

## Changed
Expand Down
187 changes: 61 additions & 126 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,173 +1,108 @@
# nw

An installer for [NW.js](https://nwjs.io).
An npm installer for [NW.js](https://nwjs.io).

> NW.js is a runtime-environment based on Chromium and Node.js. It is used to build desktop applications that run on Windows, OSX, and Linux.
[![npm](https://img.shields.io/npm/v/nw)](https://www.npmjs.com/package/nw)

[![npm](https://img.shields.io/npm/v/nw.svg?style=flat)](https://www.npmjs.com/package/nw)
## Install

## usage
Install locally to your project with: `npm install nw` and then in your `package.json` add a script:
### Latest version of normal build flavor:

```json
{
"scripts": {
"start": "nw"
}
}
```shell
npm install --save-dev nw
```

Now it will run your local project when you type `npm start`.

If your project is in another folder, add the path to the project `"start": "nw path/to/app"`.

You could also call `nw` directly from `node_modules/.bin/nw` instead of adding to your `package.json`.

### global
You can also install globally with `npm install nw -g` and then in any project type `nw` to run the project. Installing locally is recommended though as each project can have its own dependent version of nw.js.
### Specific version with changes to installer:

## example
If you want a really quick example try this:

1. `git clone https://github.com/zcbenz/nw-sample-apps && cd nw-sample-apps`
2. `npm init`
3. `npm install nw`
4. `"node_modules/.bin/nw" file-explorer`

and now you should see a file explorer demo app.

## command line options
There are a few (platform-specific) arguments you can pass to the `nw` executable to
customize your nw.js application:

* `--mac_plist <path-to-plist-file>`: (OS X only) Copies the given file to Info.plist in the app
bundle. This lets you do things like change your app's name and point to a different icon.

* `--mac_icon <path-to-icns-file>`: (OS X only) Copies the given .icns file to the Resources/ dir
in the app bundle. You will need to point to the file with a custom plist file as well (see
`--mac_list`)

**NOTE**: These options will keep the copied files in the app bundle for as long as the bundle is
on the filesystem (they're not deleted between app invocations). As a result, they're not
recommended if you installed nw globally using `-g`. Also note that
[OS X caches these files](http://proteo.me.uk/2011/08/mac-application-bundle-caching/),
so you may need to manually clear these cached files during development.

## install a specific version of nw.js

To install a specific version of nw.js use npm with the specific version: `npm install [email protected]`

> *Please note:* This npm package version tracks the version of nw.js that will be installed, with an additional build number that is used for revisions to the installer. As such `0.12.0-1` and `0.12.0-2` will both install `[email protected]` but the latter has newer changes to the installer.
You may use `npm view nw versions` to view the list of available versions.
```shell
npm install --save-dev [email protected]
```

## install a specific build type of nw.js
> You may use `npm view nw versions` to view the list of available versions.
nw.js has three build types: `normal`, `sdk` and `nacl`. To install a specific build type you may set npm config property `nwjs_build_type`, environment variable `NWJS_BUILD_TYPE` or pass command line option `--nwjs_build_type`:
### Specify build flavor:

``` shell
npm install nw --nwjs_build_type=sdk
```shell
npm install --save-dev nw@sdk
```

Setting option in `.npmrc` file (https://www.npmjs.org/doc/files/npmrc.html):

```
nwjs_build_type=sdk
```
> Optionally set `nwjs_build_type=sdk` in `.npmrc` or `NWJS_BUILD_TYPE=sdk` environment variable.
Setting environment variable `NWJS_BUILD_TYPE`:
### Specify platform:

``` shell
export NWJS_BUILD_TYPE=sdk
```
Set `nwjs_platform` in `.npmrc` or `NWJS_PLATFORM` environment variable. Defaults to `process.platform`.

You can alternatively install `sdk` build by specifying `-sdk` suffix in version:
### Specify architecture:

``` shell
npm install [email protected]
```
Set `nwjs_arch` in `.npmrc` or `NWJS_ARCH` environment variable. Defaults to `process.arch`.

You can also run `npm install nw@sdk` to get the latest of published SDK versions. (Note: that may be a beta version.)
### Specify cache directory:

## install a specific architecture
Set `nwjs_cache_dir` in `.npmrc` or `NWJS_ARCH` environment variable. Defaults to `./node_modules/nw`.

You may use the environment variable `npm_config_nwjs_process_arch` to override the default architecture (`process.arch`) and to download NW.js built for some other architecture.
### Specify cache flag:

## finding the path to the nw.js binary
Set `nwjs_cache` in `.npmrc` or `NWJS_ARCH` environment variable to keep or delete cached binaries. Defaults to `true`.

If you would like to programmatically retrieve the path to the nw.js binary use:
### Specify ffmpeg flag:

``` js
var findpath = require('nw').findpath;
var nwpath = findpath();
// nwpath will equal the path to the binary depending on your environment
```
Set `nwjs_ffmpeg` in `.npmrc` or `NWJS_ARCH` environment variable to toggle downloading [community FFmpeg binaries](https://github.com/nwjs-ffmpeg-prebuilt/nwjs-ffmpeg-prebuilt). Defaults to `false`.

## finding the path to the chromedriver binary
### Specify Native Addon flag:

If you would like to programmatically retrieve the path to the chromedriver use:
Set `nwjs_native_addon` in `.npmrc` or `NWJS_NATIVE_ADDON` environment variable to toggle downloading NW.js Node headers. Defaults to `false`.

``` js
var findpath = require('nw').findpath;
var chromedriver_path = findpath('chromedriver');
// chromedriver_path will equal the path to the binary depending on your environment
```
### Specify download URL:

Then you can use that path to run NW.js programmatically. For example, to run in the current script's directory:

```js
require('child_process').spawn(
require('nw').findpath(),
['.'].concat( process.argv.slice(2) ),
{
cwd: __dirname,
detached: true,
stdio: 'ignore'
}
).unref();
```
Set `nwjs_urlbase` in `.npmrc` or `NWJS_URLBASE` environment variable. Defaults to `https://dl.nwjs.io`. The file system (`file://`) is also supported.

## retrieve binaries from custom download location or file path
## Usage

The installer attempts to download binaries from the default location of `https://dl.nwjs.io/v`. You can override this by setting the npm config property `nwjs_urlbase` on the command line by passing the `--nwjs_urlbase` option:
Add a script in your `package.json`:

``` shell
npm install nw --nwjs_urlbase=http://my.own.location/somewhere
```json
{
"scripts": {
"start": "nw /path/to/app"
}
}
```

or adding it to your `.npmrc` file (https://www.npmjs.org/doc/files/npmrc.html):
Executing `npm start` runs the NW.js app. Omitting the file path makes NW.js check for valid project in current working directory. You can also call `nw` directly from `node_modules/.bin/nw`.

```
nwjs_urlbase=http://my.own.location/somewhere
```
## Command Line Options

You can alternatively set an environment variable `NWJS_URLBASE`:
There are a few (platform-specific) arguments you can pass to the `nw` executable to customize your nw.js application:

``` shell
export NWJS_URLBASE=http://my.own.location/somewhere
```
* `--mac_plist <path-to-plist-file>`: (OS X only) Copies the given file to Info.plist in the app
bundle. This lets you do things like change your app's name and point to a different icon.

The installer supports `file://` URLs to retrieve files from the local filesystem:
* `--mac_icon <path-to-icns-file>`: (OS X only) Copies the given .icns file to the Resources/ dir
in the app bundle. You will need to point to the file with a custom plist file as well (see
`--mac_list`)

``` shell
export NWJS_URLBASE=file:///home/bilbo/my/own/mirror
```
**NOTE**: These options will keep the copied files in the app bundle for as long as the bundle is
on the filesystem (they're not deleted between app invocations). As a result, they're not
recommended if you installed nw globally using `-g`. Also note that
[OS X caches these files](http://proteo.me.uk/2011/08/mac-application-bundle-caching/),
so you may need to manually clear these cached files during development.

## using a proxy with or without authentication
## APIs

If you are behind a proxy server you have to set an environment variable `http_proxy` with proxy servers url:
### Find path to the NW.js binary:

```
export http_proxy="http://username:[email protected]:8080"
``` js
import { findpath } from 'nw';
var path = findpath();
```

or
## Find the path to the chromedriver binary

```
export http_proxy="http://myproxy.com:8080"
``` js
import { findpath } from 'nw';
var path = findpath('chromedriver');
```

(However, if the environment variable `https_proxy` is set, then it will be preferred, as [programmed](https://github.com/kevva/get-proxy/blob/master/index.js) in the `get-proxy` package.)
## License

## license
[nw.js](https://github.com/nwjs/nw.js)'s code and this installer use the MIT license.
[NW.js](https://github.com/nwjs/nw.js)'s code and this installer use the MIT license.
20 changes: 10 additions & 10 deletions bin/nw.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { platform, argv, nextTick, exit, execPath } from 'node:process';
import { fileURLToPath } from 'node:url';

import { copyAssets } from '../lib/app_assets.js';
import { findpath } from '../lib/findpath.js';
import util from '../src/util.js';

const __dirname = dirname(fileURLToPath(import.meta.url));

Expand All @@ -18,11 +18,11 @@ function run() {
if (!existsSync(packagejsonBackup)) {
try {
renameSync(packagejson, packagejsonBackup);
} catch (err) {}
} catch (err) { }
}

// copy over any asset files (icons, etc) specified via CLI args:
copyAssets(platform, findpath());
copyAssets(platform, util.findpath());

// Normalize cli args
var args = argv.slice(2);
Expand All @@ -34,26 +34,26 @@ function run() {
}

// Spawn node-webkit
var nw = spawn(findpath(), args, { stdio: 'inherit' });
nw.on('close', function() {
nextTick(function() {
var nw = spawn(util.findpath(), args, { stdio: 'inherit' });
nw.on('close', function () {
nextTick(function () {
exit(0);
});
});

// Restore package.json shortly after nw is spawned
setTimeout(function() {
setTimeout(function () {
try {
if (existsSync(packagejsonBackup)) {
renameSync(packagejsonBackup, packagejson);
}
} catch (err) {}
} catch (err) { }
}, 1000);
}

if (!existsSync(findpath())) {
if (!existsSync(util.findpath())) {
console.log('nw.js appears to have failed to download and extract. Attempting to download and extract again...');
var child = spawn(execPath, [resolve(__dirname, '..', 'scripts', 'install.js')], { stdio: 'inherit' });
var child = spawn(execPath, [resolve(__dirname, '..', 'src', 'postinstall.js')], { stdio: 'inherit' });
child.on('close', run);
} else {
run();
Expand Down
19 changes: 11 additions & 8 deletions lib/app_assets.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { readFileSync, writeFileSync } from 'fs';
import { join, basename } from 'path';
import { argv } from 'yargs';
import fs from 'node:fs';
import path from 'node:path';

import yargs from 'yargs';

const argv = yargs(process.argv.slice(2)).argv;

// Helper to simulate the shell's "cp" command
function copyFileSync(srcFile, destFile) {
var content = readFileSync(srcFile);
writeFileSync(destFile, content);
let content = fs.readFileSync(srcFile);
fs.writeFileSync(destFile, content);
}

// Copy asset files (specified via process.argv) over to the app binary's folder
Expand All @@ -14,16 +17,16 @@ export function copyAssets(platform, binPath) {
// app bundle. This lets you customize things like the app's menubar
// name and icon (see argv.mac_icon below)
if (argv.mac_plist && platform === 'darwin') {
var plistPath = join(binPath, '..', '..', 'Info.plist');
let plistPath = path.join(binPath, '..', '..', 'Info.plist');
copyFileSync(argv.mac_plist, plistPath);
}

// OS X: Save icon files to the Resources dir in the app bundle.
// Note that for the icon to work properly you need to point to
// it with a custom plist file.
if (argv.mac_icon && platform === 'darwin') {
var iconName = basename(argv.mac_icon); // Preserve the file's name
var iconPath = join(binPath, '..', '..', 'Resources', iconName);
let iconName = path.basename(argv.mac_icon); // Preserve the file's name
let iconPath = path.join(binPath, '..', '..', 'Resources', iconName);
copyFileSync(argv.mac_icon, iconPath);
}
}
Loading

0 comments on commit 615f661

Please sign in to comment.