62943


JavaScriptを実行している環境が次の3つのうちどれであるかをJavaScriptから検知して条件分岐をしたいです。

  1. 通常のWebページとして動作している
  2. node-webkitで動作している
  3. Node.js上で動作している

一度に3つ同時に判定しなくても、1か2かの分岐・2か３かの分岐ができれば良いです。


CC BY-SA 3.0
2014-12-18T13:42:09.170
2046
2020-02-11T02:15:34.140
2014-12-18T13:48:02.683
450
450
question
javascript node.js
JavaScript実行環境の判定方法について


ブラウザーとブラウザーじゃない環境を識別するためには、これが使えます：

[code]

    var runningInBrowser = (typeof window !== 'undefined');
    
[/code]

  
[このスレッド](https://groups.google.com/forum/#!topic/node-
webkit/A6F-cBKW6Es)によると、Node.jsとnode-webkitを識別するためにはいくつかの方法があります：

[code]

    var isNodeWebkit = !!(require && require('nw.gui'));
    
[/code]

又は

[code]

    var isNodeWebkit = !!(typeof(process) === 'object' && process.features.uv);
    
[/code]

最初の二つを組み合わせると、

[code]

    var currentEnvironment;
    if (typeof window !== 'undefined') {
        currentEnvironment = 'browser';
    } else if (require && require('nw.gui')) {
        currentEnvironment = 'node-webkit';
    } else {
       currentEnvironment = 'node';
    }
    
[/code]

になります。


CC BY-SA 3.0
2014-12-18T14:30:12.113
2049
2014-12-18T16:06:18.613
2014-12-18T16:06:18.613
4788
4788
2046
answer


以下のように、Node.js 環境でのみ利用可能な変数やモジュールの存在チェックで環境の判定をします。

### 2. Node.js 上で動作していることのチェック

`process` 変数と、 `require` 変数が存在すればいいかをチェックします。

[code]

    var isNode = (typeof process !== "undefined" && typeof require !== "undefined");
    
[/code]

### 1. 通常のWebページとして動作していることのチェック

非 Node.js 環境であるかどうかだけチェックします。

[code]

    var isBrowser = !isNode;
    
[/code]

### 3. Node-Webkit 上で動作していることのチェック

組み込まれているはずの[nw.gui モジュール](https://github.com/rogerwang/node-webkit/wiki/API-
Overview-and-Notices)の有無をチェックします。

[code]

    var isNodeWebkit = (typeof require('nw.gui'))
    
[/code]

### 組み合わせて分岐を作る

[code]

    // Node.js で動作しているか
    var isNode = (typeof process !== "undefined" && typeof require !== "undefined");
    // ブラウザ上(非Node.js)で動作しているか
    var isBrowser = !isNode
    // node-webkitで動作しているか
    var isNodeWebkit;
    try {
        isNodeWebkit = isNode ? (typeof require('nw.gui') !== "undefined") : false;
    } catch(e) {
        isNodeWebkit = false;
    }
    
    if (isNodeWebkit) {
        // node-webkitで動作
    } else if ( isNode) {
        // Node.js上で動作している
    } else {
        //  通常のWebページとして動作している
    }
    
[/code]

[先人のブログ記事](http://videlais.com/2014/08/23/lessons-learned-from-detecting-node-
webkit/)が参考になります。


CC BY-SA 3.0
2014-12-18T15:56:37.293
2054
2014-12-18T15:56:37.293
4978
2046
answer


お二人の回答および他のブログ記事などを参考に自分なりの答えを考えてみました。

[code]

    function detectEnvironment() {
      var isBrowser = typeof window !== 'undefined';
      var isNode = typeof process !== 'undefined' && typeof require !== 'undefined';
      var isNodeWebkit = isBrowser && isNode;
      return {
        isBrowser: isBrowser,
        isNode: isNode,
        isNodeWebkit: isNodeWebkit
      };
    }
    
[/code]

  * Node.js環境で `require('nw.gui')` をすると例外になる。
  * node-webkitでHTML内の `<script>` で別のJSを `require` した場合、その先のJSでは `require('nw.gui')` が例外になる。 `window` へのアクセスは可能。

という理由により、 `require('nw.gui')` を使わずに書いてみました。

このファイルを `detector.js` として使う場合、下記のようにしたら `<script src="detector.js">` でも
`require('./detector.js')` でもうまく使えるんじゃないかと思います。

[code]

    (function() {
    
      if (typeof module !== 'undefined') {
        module.exports = detectEnvironment;
      } else if (typeof window !== 'undefined') {
        window.detectEnvironment = detectEnvironment;
      }
    
      function detectEnvironment() {
        var isBrowser = typeof window !== 'undefined';
        var isNode = typeof process !== 'undefined' && typeof require !== 'undefined';
        var isNodeWebkit = isBrowser && isNode;
        return {
          isBrowser: isBrowser,
          isNode: isNode,
          isNodeWebkit: isNodeWebkit
        };
      }
    
    })();
    
[/code]


CC BY-SA 3.0
2014-12-19T09:53:34.840
2128
2014-12-19T09:53:34.840
450
2046
answer


2020/2/11 現在、この記事を参考に isNode を実装してみたがうまくいかなかった。  
前提としてブラウザー側には webpack を使っている。  
webpack を使った環境においては process も require も undefined ではない。  
代わりに process.title の値を判断材料にしてみた。

[code]

    const isNode = (process.title !== 'browser');
    
[/code]

isNode の実装方法を調べてここにたどり着く人が他にもいると思うので参考にメモ残しておきます。

## 前提

  * Windows 10 Home Edition 上の Ubuntu(WSL)
  * Node.js v12.15.0
  * webpack 4.41.5
  * babel 7.8.4

## process.title の値の調査結果

  * Node.js の場合："/usr/local/bin/node"（たぶん、node のパスかな？）
  * ブラウザーの場合："browser" 


CC BY-SA 4.0
2020-02-11T02:15:34.140
62943
2020-02-11T02:15:34.140
37787
2046
answer