Skip to content
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

feat: install multiple binaries #138

Merged
merged 23 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5bf4a66
feat: integrate postinstall with new download logic
ayushmanchhabra Mar 24, 2024
a651667
fix: handle windows permission error
ayushmanchhabra Mar 24, 2024
5d4930a
chore: remove old postinstall logic
ayushmanchhabra Mar 24, 2024
2d3fb52
chore(docs): update changelog
ayushmanchhabra Mar 24, 2024
039bc27
fix: correctly install packages
ayushmanchhabra Mar 24, 2024
e7b9e2f
chore: annotate .gitignore
ayushmanchhabra Mar 24, 2024
3d9b92b
fix(yargs): get argv
ayushmanchhabra Mar 25, 2024
c12142d
chore: refactor a bunch
ayushmanchhabra Mar 25, 2024
3cf3e64
chore: update tar
ayushmanchhabra Mar 25, 2024
0559dce
chore: revert gitignore changes
ayushmanchhabra Mar 25, 2024
2494cf5
Merge branch 'main' into dev-47
ayushmanchhabra Mar 25, 2024
138b6be
fix(test): default import
ayushmanchhabra Mar 25, 2024
14c0aa3
fix(util): set platform correctly
ayushmanchhabra Mar 25, 2024
43d7aee
chore(docs): revamp
ayushmanchhabra Mar 25, 2024
7e9fb99
Merge branch 'main' into dev-47
ayushmanchhabra Mar 25, 2024
a991e96
chore: add lock file
ayushmanchhabra Mar 25, 2024
63a0a28
Merge branch 'dev-47' of github.com:nwjs/npm-installer into dev-47
ayushmanchhabra Mar 25, 2024
742aa6f
chore(test): add selenium test
ayushmanchhabra Mar 25, 2024
2e7b979
chore(test): download sdk for tests
ayushmanchhabra Mar 25, 2024
65c1d00
fix
ayushmanchhabra Mar 25, 2024
4e3137e
fix: flavor parsing
ayushmanchhabra Mar 25, 2024
56fdf4e
chore(test): remove chromedriver ttest
ayushmanchhabra Mar 25, 2024
4ff10a6
chore: bump version
ayushmanchhabra Mar 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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