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

Graceful fallback if the renderer process can't access the remote module #159

Merged
merged 1 commit into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 13 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,40 +30,22 @@ You can require this module from either the **main** or **renderer** process (wi
Running on Electron >10 renderer processes
------------------------------------------

When loaded in renderer processes, this module will make use of
When loaded in renderer processes, this module will try to make use of
`electron.remote` in order to fetch the `userData` path.

Electron 10 now [defaults `enableRemoteModule` to
false](https://www.electronjs.org/docs/breaking-changes#default-changed-enableremotemodule-defaults-to-false),
which means that `electron-json-storage` will not work on Electron 10 renderer
processes unless you manually set `enableRemoteModule` to `true`:
which means that `electron-json-storage` will be able to calculate a data path by default.

```js
const win = new BrowserWindow({
webPreferences: {
enableRemoteModule: true
}
})
```

Alternatively, you can avoid using the `remote` module by:

- Passing the `electron.app.getPath('userData')` value from the **main**
process to your **renderer** processes through IPC or a medium of your choice

- Calling `storage.setDataPath()`, on the **renderer** process, with the user
data path obtained on the previous step before calling any other
`electron-json-storage` function.

If you do this, the user data path will be cached by the renderer process,
which will not need to go through the `remote` module to obtain it.
The solution is to manually call `storage.setDataPath()` before reading or
writing any values or setting `enableRemoteModule` to `true`.

Documentation
-------------


* [storage](#module_storage)
* [.getDefaultDataPath()](#module_storage.getDefaultDataPath) ⇒ <code>String</code>
* [.getDefaultDataPath()](#module_storage.getDefaultDataPath) ⇒ <code>String</code> \| <code>Null</code>
* [.setDataPath(directory)](#module_storage.setDataPath)
* [.getDataPath()](#module_storage.getDataPath) ⇒ <code>String</code>
* [.get(key, [options], callback)](#module_storage.get)
Expand All @@ -77,10 +59,15 @@ Documentation

<a name="module_storage.getDefaultDataPath"></a>

### storage.getDefaultDataPath() ⇒ <code>String</code>
### storage.getDefaultDataPath() ⇒ <code>String</code> \| <code>Null</code>
This function will return `null` when running in the
renderer process without support for the `remote` IPC
mechanism. You have to explicitly set a data path using
`.setDataPath()` in these cases.

**Kind**: static method of [<code>storage</code>](#module_storage)
**Summary**: Get the default data path
**Returns**: <code>String</code> - default data path
**Returns**: <code>String</code> \| <code>Null</code> - default data path
**Access**: public
**Example**
```js
Expand Down Expand Up @@ -222,6 +209,7 @@ storage.getAll(function(error, data) {
| [options] | <code>Object</code> | options |
| [options.dataPath] | <code>String</code> | data path |
| [options.validate] | <code>String</code> | validate writes by reading the data back |
| [options.prettyPrinting] | <code>boolean</code> | adds line breaks and spacing to the written data |
| callback | <code>function</code> | callback (error) |

**Example**
Expand Down
26 changes: 4 additions & 22 deletions doc/README.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,15 @@ You can require this module from either the **main** or **renderer** process (wi
Running on Electron >10 renderer processes
------------------------------------------

When loaded in renderer processes, this module will make use of
When loaded in renderer processes, this module will try to make use of
`electron.remote` in order to fetch the `userData` path.

Electron 10 now [defaults `enableRemoteModule` to
false](https://www.electronjs.org/docs/breaking-changes#default-changed-enableremotemodule-defaults-to-false),
which means that `electron-json-storage` will not work on Electron 10 renderer
processes unless you manually set `enableRemoteModule` to `true`:

```js
const win = new BrowserWindow({
webPreferences: {
enableRemoteModule: true
}
})
```

Alternatively, you can avoid using the `remote` module by:

- Passing the `electron.app.getPath('userData')` value from the **main**
process to your **renderer** processes through IPC or a medium of your choice

- Calling `storage.setDataPath()`, on the **renderer** process, with the user
data path obtained on the previous step before calling any other
`electron-json-storage` function.
which means that `electron-json-storage` will be able to calculate a data path by default.

If you do this, the user data path will be cached by the renderer process,
which will not need to go through the `remote` module to obtain it.
The solution is to manually call `storage.setDataPath()` before reading or
writing any values or setting `enableRemoteModule` to `true`.

Documentation
-------------
Expand Down
8 changes: 7 additions & 1 deletion lib/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,13 @@ const readFile = function(fileName, callback, times) {
* @function
* @public
*
* @returns {String} default data path
* @description
* This function will return `null` when running in the
* renderer process without support for the `remote` IPC
* mechanism. You have to explicitly set a data path using
* `.setDataPath()` in these cases.
*
* @returns {(String|Null)} default data path
*
* @example
* const defaultDataPath = storage.getDefaultDataPath()
Expand Down
13 changes: 11 additions & 2 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
const _ = require('lodash');
const path = require('path');
const electron = require('electron');
const app = electron.app || electron.remote.app;
const app = electron.app || (electron.remote && electron.remote.app) || null;

/**
* @summary Get the default data path
Expand All @@ -40,6 +40,10 @@ const app = electron.app || electron.remote.app;
* const defaultDataPath = utils.getDefaultDataPath()
*/
exports.getDefaultDataPath = function() {
if (!app) {
return null;
}

return path.join(app.getPath('userData'), 'storage');
};

Expand Down Expand Up @@ -123,7 +127,12 @@ exports.getFileName = function(key, options) {
const escapedFileName = encodeURIComponent(keyFileName)
.replace(/\*/g, '-').replace(/%20/g, ' ');

return path.join(options.dataPath || exports.getDataPath(), escapedFileName);
const dataPath = options.dataPath || exports.getDataPath();
if (!dataPath) {
throw new Error('You must explicitly set a data path');
}

return path.join(dataPath, escapedFileName);
};

/**
Expand Down
Loading