2019/11/21

electron v7 以降は Raspberry Pi にデフォルトでインストールできない

Raspberry Pi で electron をインストールしようとすると以下のように落ちてしまいました。

```
> electron@7.1.2 postinstall /home/pi/test/node_modules/electron
> node install.js

(node:5861) UnhandledPromiseRejectionWarning: HTTPError: Response code 404 (Not Found)
    at EventEmitter. (/home/pi/test/node_modules/got/source/as-stream.js:35:24)
    at EventEmitter.emit (events.js:210:5)
    at module.exports (/home/pi/test/node_modules/got/source/get-response.js:22:10)
    at ClientRequest.handleResponse (/home/pi/test/node_modules/got/source/request-as-event-emitter.js:155:5)
    at Object.onceWrapper (events.js:300:26)
    at ClientRequest.emit (events.js:215:7)
    at ClientRequest.origin.emit (/home/pi/test/node_modules/@szmarczak/http-timer/source/index.js:37:11)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:583:27)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:115:17)
    at TLSSocket.socketOnData (_http_client.js:456:22)
(node:5861) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:5861) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
npm WARN saveError ENOENT: no such file or directory, open '/home/pi/test/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/home/pi/test/package.json'
npm WARN test No description
npm WARN test No repository field.
npm WARN test No README data
npm WARN test No license field.

+ electron@7.1.2
added 87 packages from 91 contributors and audited 104 packages in 22.813s
found 0 vulnerabilities
```


### 対策
先に対処方法を書いておくと、以下のように `--arch=armv7l` を指定してインストールすれば大丈夫。

```bash
`gutter: false;
$ npm install --arch=armv7l electron
```

もしくは、`~/.npmrc` に以下を追加しておけばOK。
```text
`title: "~/.npmrc";
arch=armv7l
```

> 参考
>
> [Error installing on RPi4 · Issue #20723 · electron/electron](https://github.com/electron/electron/issues/20723)


### 原因
`install.js` の中でリリースファイルをダウンロードしているのですが、ここで `process.arch` を使っています。この値は `arm` になるので、
`https://github.com/electron/electron/releases/download/v7.1.2/electron-v7.1.2-linux-arm.zip` というファイルをダウンロードしようとします。
しかし、アップロードされているファイルは `electron-v7.1.2-linux-armv7l.zip` です。(`arm` ではなく `armv7l`) 

electron 7.1.2
```javascript
`title: "electron/install.js"; first-line: 31; highlight: 37;
downloadArtifact({
  version,
  artifactName: 'electron',
  force: process.env.force_no_cache === 'true',
  cacheRoot: process.env.electron_config_cache,
  platform: process.env.npm_config_platform || process.platform,
  arch: process.env.npm_config_arch || process.arch
}).then((zipPath) => extractFile(zipPath)).catch((err) => onerror(err))
```

electron v6 ではどうだったかと言うと、以下のように `process.arch` を使っていません。

electron 6.1.4
```javascript
`title: "electron/install.js"; first-line: 30; highlight: 35;
// downloads if not cached
download({
  cache: process.env.electron_config_cache,
  version: version,
  platform: process.env.npm_config_platform,
  arch: process.env.npm_config_arch,
  strictSSL: process.env.npm_config_strict_ssl === 'true',
  force: process.env.force_no_cache === 'true',
  quiet: process.env.npm_config_loglevel === 'silent' || process.env.CI
}, extractFile)
```

`process.env.npm_config_arch` が `undefined` の場合、`download()` の中で `process.arch` を `getNodeArch()` という関数で変換します。
以下のように、`arm` は 適切なアーキテクチャに変換されるため、v6 までは正しく動いていたようです。

```javascript
function getNodeArch(arch) {
    if (arch === 'arm') {
        switch (process.config.variables.arm_version) {
            case '6':
                return uname();
            case '7':
                return 'armv7l';
            default:
                break;
        }
    }
    return arch;
}
```

> 参考
>
> [electron/get: Download Electron release artifacts](https://github.com/electron/get)

0 件のコメント: