web-dev-qa-db-ja.com

Browserify-ブラウザのbrowserifyで生成されたファイルにバンドルされている関数を呼び出す方法

私はnodejsとbrowserifyが初めてです。私はこれで始めました link

このコードを含むファイルmain.jsがあります

var unique = require('uniq');

var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];

this.LogData =function(){
console.log(unique(data));
};

ここで、npmを使用してuniqモジュールをインストールします。

 npm install uniq

次に、mainify.jsから始まるすべての必要なモジュールをbrowserifyコマンドでbundle.jsという単一のファイルにまとめます。

browserify main.js -o bundle.js

生成されたファイルは次のようになります。

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var unique = require('uniq');

var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];

this.LogData =function(){
console.log(unique(data));
};

},{"uniq":2}],2:[function(require,module,exports){
"use strict"

function unique_pred(list, compare) {
  var ptr = 1
    , len = list.length
    , a=list[0], b=list[0]
  for(var i=1; i<len; ++i) {
    b = a
    a = list[i]
    if(compare(a, b)) {
      if(i === ptr) {
        ptr++
        continue
      }
      list[ptr++] = a
    }
  }
  list.length = ptr
  return list
}

function unique_eq(list) {
  var ptr = 1
    , len = list.length
    , a=list[0], b = list[0]
  for(var i=1; i<len; ++i, b=a) {
    b = a
    a = list[i]
    if(a !== b) {
      if(i === ptr) {
        ptr++
        continue
      }
      list[ptr++] = a
    }
  }
  list.length = ptr
  return list
}

function unique(list, compare, sorted) {
  if(list.length === 0) {
    return []
  }
  if(compare) {
    if(!sorted) {
      list.sort(compare)
    }
    return unique_pred(list, compare)
  }
  if(!sorted) {
    list.sort()
  }
  return unique_eq(list)
}

module.exports = unique
},{}]},{},[1])

bundle.jsファイルをindex.htmページに含めた後、logData関数を呼び出すにはどうすればよいですか?

74
SharpCoder

デフォルトでは、browserifyはブラウザー化されたコードの外部からモジュールにアクセスできません。ブラウザー化されたモジュール内のコードを呼び出したい場合は、モジュールとともにコードをブラウザー化することになっています。 http://browserify.org/ を参照してください。

もちろん、次のようにメソッドを外部から明示的にアクセス可能にすることもできます。

_window.LogData =function(){
  console.log(unique(data));
};
_

次に、ページの他のどこからでもLogData()を呼び出すことができます。

67
thejh

Browserifyにスタンドアロンモジュールをバンドルする重要な部分は、--sオプションです。ノードのmodule.exportsをグローバル変数として使用して、モジュールからエクスポートしたものをすべて公開します。その後、ファイルを<script>タグに含めることができます。

何らかの理由でそのグローバル変数を公開する必要がある場合にのみ、これを行う必要があります。私の場合、クライアントには、Browserifyのビジネスを心配することなく、Webページに含めることができるスタンドアロンモジュールが必要でした。

moduleの引数で--sオプションを使用する例を次に示します。

browserify index.js --s module > dist/module.js

これにより、モジュールがmoduleという名前のグローバル変数として公開されます。
ソース

更新:@fotinakisに感謝します。 --standalone your-module-nameを渡していることを確認してください。 --standaloneが引数を取ることを忘れた場合、Browserifyはそれを見つけることができなかったため、空のモジュールを静かに生成します。

これで時間を節約できることを願っています。

85

@Matas Vaitkeviciusの Browserifyのスタンドアロンオプションでの回答 は正しい(@thejhの ウィンドウグローバル変数を使用した回答 も機能しますが、他の人が指摘したように、グローバルネームスペースを汚染するため、理想)。スタンドアロンオプションの使用方法についてもう少し詳しく説明したいと思いました。

バンドルするソーススクリプトで、module.exportsを介して呼び出したい関数を必ず公開してください。クライアントスクリプトでは、これらの公開された関数を<bundle-name>。<func-name>経由で呼び出すことができます。以下に例を示します。

私のソースファイルsrc/script.jsはこれを持っています:
_module.exports = {myFunc: func};_

私のbrowserifyコマンドは次のようになります。
_browserify src/script.js --standalone myBundle > dist/bundle.js_

そして、私のclient script dist/client.jsはバンドルされたスクリプトをロードします
_<script src="bundle.js"></script>_
そして公開された関数を次のように呼び出します:
<script>myBundle.myFunc();</script>


公開された関数を呼び出す前に、クライアントスクリプトでバンドル名を要求する必要はありません。 <script src="bundle.js"></script><script>var bundled = require("myBundle"); bundled.myFunc();</script> 必要ではなく、機能しません。

実際、スタンドアロンモードなしでbrowserifyにバンドルされているすべての関数と同様に、 require関数はバンドルされたスクリプトの外部では使用できません 。 Browserifyでは、クライアント側でNode関数を使用)を使用できますが、バンドルされたスクリプト自体でのみ;インポートしてどこでも使用できるスタンドアロンモジュールを作成するためのものではありませんクライアント側。このため、バンドルされたコンテキストの外で単一の関数を呼び出すためだけに、この余分な問題に取り組む必要があります。

22
Galen Long

Browserifyの--standaloneパラメータまたはgoogle "browserify umd"のREADME.mdを読む

7
undoZen

私は答えを読んだだけで、誰もグローバル変数スコープの使用に言及していないようです? node.jsとブラウザで同じコードを使用する場合、これは便利です。

class Test
{
  constructor()
  {
  }
}
global.TestClass = Test;

その後、どこでもTestClassにアクセスできます。

<script src="bundle.js"></script>
<script>
var test = new TestClass(); // Enjoy!
</script>

注: TestClassはどこでも利用可能になります。これは、ウィンドウ変数を使用するのと同じです。

さらに、クラスをグローバルスコープに公開するデコレータを作成できます。これは本当に素晴らしいことですが、変数が定義されている場所を追跡するのが難しくなります。

6
Azarus

いくつかのオプションがあります:

  1. Plugin browserify-bridge 生成されたエントリモジュールにモジュールを自動エクスポートします。これは、SDKプロジェクトや、エクスポートされたものに手動で対応する必要がない状況に役立ちます。

  2. ロールアップ露出の擬似名前空間パターンに従います。

最初に、フォルダーのインデックス検索を利用して、ライブラリを次のように配置します。

/src
--entry.js
--/helpers
--- index.js
--- someHelper.js
--/providers
--- index.js
--- someProvider.js
...

このパターンでは、次のようにエントリを定義します。

exports.Helpers = require('./helpers');
exports.Providers = require('./providers');
...

Requireがそれぞれのサブフォルダーからindex.jsを自動的にロードすることに注意してください

サブフォルダーには、そのコンテキストで使用可能なモジュールの同様のマニフェストを含めることができます。

exports.SomeHelper = require('./someHelper');

このパターンは非常によくスケーリングし、ロールアップされたAPIに含めるものをコンテキスト(フォルダーごとのフォルダー)で追跡できます。

1
deepelement

HTMLとサーバー側ノードの両方から関数を使用可能にするには:

main.js:

var unique = require('uniq');

function myFunction() {
    var data = [1, 2, 2, 4, 3];
    return unique(data).toString();
}
console.log ( myFunction() );

// When browserified - we can't call myFunction() from the HTML, so we'll externalize myExtFunction()
// On the server-side "window" is undef. so we hide it.
if (typeof window !== 'undefined') {
    window.myExtFunction = function() {
        return myFunction();
    }
}

main.html:

<html>
    <head>
        <script type='text/javascript' src="bundle.js"></script>
    <head>
    <body>
        Result: <span id="demo"></span>
        <script>document.getElementById("demo").innerHTML = myExtFunction();</script>
    </body>
</html>

実行:

npm install uniq
browserify main.js > bundle.js

ブラウザでmain.htmlを開いたときと実行したときと同じ結果が得られるはずです

node main.js
0
Ori Miller

これらの答えがあっても、この問題を把握して理解するにはしばらく時間がかかります

それは本当に簡単です-それはラッピングについてです

この目的のために、アプリ全体{{app_name}}に対して1つのスクリプトしかないと仮定します。

1つの選択肢

オブジェクト「this」に関数を追加します

function somefunction(param) {}
->
this.somefunction = function(param) {}

次に、そのオブジェクトに使用できる名前を付ける必要があります-他の人が推奨するように、「名前付きのスタンドアロン」パラメータを追加します

"watchify" with "browserify" これを使用する場合

var b = browserify({
    ...
    standalone: '{{app_name}}'
});

またはコマンドライン

browserify index.js --standalone {{app_name}} > index-bundle.js

その後、ブラウザから関数を呼び出すことができます

app_name.somefunction(param);
window.app_name.somefunction(param);

2つの選択肢

オブジェクト「ウィンドウ」に機能を追加

function somefunction(param) {}
->
window.somefunction = function(param) {}

その後、ブラウザから関数を呼び出すことができます

somefunction(param);
window.somefunction(param);

-

多分私は誰かを助ける

0
BG Bruno