webentwicklung-frage-antwort-db.com.de

Browserify - Aufruf der Funktion in einer Datei, die durch Browserify im Browser erstellt wurde

Ich bin neu bei nodejs und browserify. Ich habe mit diesem link angefangen.

Ich habe die Datei main.js, die diesen Code enthält

var unique = require('uniq');

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

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

Nun installiere ich das uniq-Modul mit npm:

 npm install uniq

Dann füge ich alle erforderlichen Module zusammen, beginnend bei main.js in einer einzigen Datei namens bundle.js mit dem Befehl browserify: 

browserify main.js -o bundle.js

Die generierte Datei sieht folgendermaßen aus:

(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])

Wie rufe ich nach dem Einbinden der bundle.js-Datei in meine index.htm-Seite die logData-Funktion auf?

69
SharpCoder

In der Standardeinstellung erlaubt browserify nicht, auf die Module außerhalb des browsergeprüften Codes zuzugreifen. Wenn Sie Code in einem browsergeprüften Modul aufrufen möchten, sollten Sie Ihren Code zusammen mit dem Modul browserüberprüfen. Siehe http://browserify.org/ für Beispiele dafür.

Natürlich können Sie Ihre Methode auch explizit von außen zugänglich machen:

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

Dann können Sie LogData() von einer anderen Stelle der Seite aus anrufen.

64
thejh

Der Schlüssel zum Bündeln von Standalone-Modulen mit Browserify ist die Option --s. Es macht das, was Sie aus Ihrem Modul exportieren, mit module.exports des Knotens als globale Variable verfügbar. Die Datei kann dann in ein <script>-Tag eingefügt werden.

Sie müssen dies nur tun, wenn die globale Variable aus irgendeinem Grund verfügbar gemacht werden muss. In meinem Fall benötigte der Client ein eigenständiges Modul, das in Webseiten eingefügt werden konnte, ohne dass er sich um dieses Browserify-Geschäft kümmern müsste.

Hier ein Beispiel, bei dem wir die --s-Option mit dem Argument module verwenden:

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

Dadurch wird unser Modul als globale Variable mit dem Namen module verfügbar gemacht.
Quelle

Update: Danke an @fotinakis. Stellen Sie sicher, dass Sie --standalone your-module-name übergeben. Wenn Sie vergessen, dass --standalone ein Argument verwendet, generiert Browserify möglicherweise ein leeres Modul, da es es nicht finden konnte.

Ich hoffe, das erspart Ihnen etwas Zeit.

83

@Matas Vaitkevicius ' Antwort mit der Standalone-Option von Browserify ist korrekt (@ thejhs Antwort mit der globalen Fenstervariable funktioniert auch, aber wie andere bemerkt haben, verschmutzt es den globalen Namespace, so dass es nicht ist Ideal). Ich wollte etwas mehr Details zur Verwendung der Standalone-Option hinzufügen.

Stellen Sie im Quellenskript, das Sie bündeln möchten, sicher, dass Sie die Funktionen verfügbar machen, die Sie über module.exports aufrufen möchten. Im Client-Skript können Sie diese exponierten Funktionen über <Bundle-Name>. <Funk-Name> aufrufen. Hier ist ein Beispiel:

Meine Quelldatei src/script.js hat Folgendes:
module.exports = {myFunc: func};

Mein browserify-Befehl sieht ungefähr so ​​aus:
browserify src/script.js --standalone myBundle > dist/bundle.js

Und mein Client-Skript dist/client.js lädt das mitgelieferte Skript
<script src="bundle.js"></script>
und rufen Sie die exponierte Funktion folgendermaßen auf:
<script>myBundle.myFunc();</script>


Es ist nicht erforderlich, den Bundle-Namen im Client-Skript vor dem Aufrufen der exponierten Funktionen, z. <script src="bundle.js"></script><script>var bundled = require("myBundle"); bundled.myFunc();</script> ist nicht notwendig und wird nicht funktionieren.

Genau wie bei allen Funktionen, die von browserify ohne Standalone-Modus gebündelt werden, ist require-Funktion außerhalb des gebündelten Skripts nicht verfügbar . Mit Browserify können Sie einige Node Funktionen clientseitig verwenden, aber nur im gebündelten Skript selbst; Es ist nicht dazu gedacht, ein eigenständiges Modul zu erstellen, das Sie auf Client-Seite überall importieren und verwenden können. Aus diesem Grund müssen wir uns mit all diesen zusätzlichen Mühen befassen, nur um eine einzelne Funktion außerhalb ihres gebündelten Kontexts aufzurufen.

22
Galen Long

Lies README.md von browserify über --standalone-Parameter Oder google "browserify umd"

7
undoZen

Ich habe die Antworten gerade durchgelesen und scheint, dass niemand die Verwendung des Bereichs der globalen Variablen erwähnt hat. Welches ist nützlich, wenn Sie denselben Code in node.js und im Browser verwenden möchten.

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

Dann können Sie auf die TestClass von überall zugreifen.

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

Hinweis: Die TestClass wird dann überall verfügbar. Dies ist das gleiche wie bei der Verwendung der Fenstervariable.

Außerdem können Sie einen Dekorator erstellen, der eine Klasse für den globalen Bereich verfügbar macht. Was wirklich schön ist, macht es aber schwer nachzuvollziehen, wo eine Variable definiert ist.

5
Azarus

Sie haben einige Möglichkeiten:

  1. Lassen Sie das Plugin browserify-bridge die Module automatisch in ein generiertes Einstiegsmodul exportieren. Dies ist hilfreich für SDK-Projekte oder Situationen, in denen Sie nicht manuell mit dem Exportieren Schritt halten müssen.

  2. Folgen Sie einem Pseudo-Namespace-Muster für die Rollup-Belichtung:

Ordnen Sie Ihre Bibliothek zunächst so an und nutzen Sie Index-Lookups für Ordner:

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

Mit diesem Muster definieren Sie einen Eintrag wie folgt:

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

Beachten Sie, dass es erforderlich ist, die index.js automatisch aus dem jeweiligen Unterordner zu laden

In Ihren Unterordnern können Sie einfach ein ähnliches Manifest der verfügbaren Module in diesem Kontext einfügen:

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

Dieses Muster lässt sich sehr gut skalieren und ermöglicht die kontextuelle (Ordner für Ordner) Verfolgung dessen, was in der zusammengefassten API enthalten sein soll.

1
deepelement

Damit Ihre Funktion sowohl im HTML- als auch im serverseitigen Knoten verfügbar ist:

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>

Ausführen:

npm install uniq
browserify main.js > bundle.js

und Sie sollten beim Öffnen von main.html in einem Browser die gleichen Ergebnisse erzielen wie beim Ausführen

node main.js
0
Ori Miller

ich brauche eine Weile, um dieses Problem auch mit diesen Antworten zu verstehen und zu verstehen

es ist wirklich einfach - es geht um das Einwickeln

zu diesem Zweck gehe ich davon aus, dass Sie nur ein Skript für die gesamte App {{app_name}} haben.

1 Alternative

funktion zum Objekt "this" hinzufügen

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

dann müssen Sie das Objekt benennen, um verfügbar zu sein - Sie werden den Parameter "Standalone mit Namen" hinzufügen, wie von anderen empfohlen

wenn Sie also "watchify" mit "browserify" verwenden verwenden Sie dies

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

oder Befehlszeile

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

dann können Sie Ihre Funktion vom Browser aus aufrufen

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

2 alternative

funktion zum Objekt "Fenster" hinzufügen

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

dann können Sie Ihre Funktion vom Browser aus aufrufen

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

-

vielleicht helfe ich jemandem

0
BG Bruno