2017-01-25 4 views
7

Ich habe ein test.js Skript, das eine Klasse App definiert und die aus einer HTML-Datei geladen wird, und alles funktioniert.Zugriff auf "öffentliche" Mitglieder nach der Bündelung mit browserify oder webpack

Wenn ich ein testBundle.js Bündel von test.js, mit browserify oder webpack, der Klasse App innerhalb testBundle.js scheint nicht mehr definiert.

Wie soll ich den Code schreiben oder welche Optionen gebe ich zum browserify um App zu definieren und benutze es aus HTML wie vorher, aber aus dem Bundle ?.

Der Fehler, den ich nach dem Bündeln erhalten ist:

<html> 
    <script src="testBundle.js"></script> 

    <script> 
     var app = new App(); 
    </script> 
</html> 

test.js:

'use strict'; 

class App { 
    constructor() { 
     console.log("App ctor") 
    } 
} 

der Befehl das Bündel zu bauen

Uncaught ReferenceError: App is not defined 

Die HTML-Datei die folgende ist :

browserify -t [ babelify --presets [ es2015 ] ] test.js -o testBundle.js 

Es scheint mir, innerhalb des Pakets, dass App tatsächlich privat ist.

testBundle.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);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.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){ 
'use strict'; 

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 

var App = function App() { 
    _classCallCheck(this, App); 

    console.log("App ctor"); 
}; 


},{}]},{},[1]); 

All Javascript im Browser, ES6 verwenden.

+0

Sorry, aber ich glaube, (Hoffnung) gibt es bessere Möglichkeiten, das Problem zu lösen, ich Ich starte ein Kopfgeld – cdarwin

Antwort

1

Im Wesentlichen, was Sie tun möchten erstellt eine Bibliothek anstelle eines regulären Bundles. Wenn Sie webpack verwenden, können Sie angeben, dass Ihre Ausgabe eine Bibliothek sein soll, die sie ähnlich wie jQuery global über einen Namespace verfügbar macht.

// relevant part of your webpack config 
// from webpack docs 
{ 
    output: { 
    // export itself to a global var 
    libraryTarget: "var", 
    // name of the global var: "Foo" 
    library: "Foo" 
    } 
} 

Dann können Sie alle Ihre Funktionen über Foo aufrufen:

var app = new Foo.App() 
var somethingElse = Foo.doSomethingElse() 

Dokumentation & Beispiele: https://webpack.github.io/docs/library-and-externals.html#examples

8

Sie versuchen, im globalen Kontext auf App zuzugreifen. App wird jedoch standardmäßig nicht global verfügbar gemacht. Node.js verwendet Module und Browserify berücksichtigt die Einkapselungsmodule. Wenn Sie Tools wie Browserify oder Webpack verwenden, ist es am häufigsten, dass Sie ein oder mehrere Einstiegspunktmodule (d. H. Dateien) haben, die Modulimporte/require() verwenden, um auf andere Module zuzugreifen.

Aber wenn man in der Lage sein wollen, im Browser App im globalen Kontext zuzugreifen, können Sie einen Verweis auf die App Klasse auf eine Eigenschaft von window in test.js zuweisen:

z.B.

window.App = App; 

oder

Object.assign(window, { App }); 
+0

das funktioniert, aber wenn ich andere Klassen habe, muss ich jeden am Ende jedes Skripts mit windows.MyClass = MyClass "exportieren"? Ich hoffte, dass es eine andere Lösung gab – cdarwin

+0

Der normale Weg, auf Entitäten von anderen Modulen zuzugreifen, ist die Verwendung von Import/Export oder require(). Sie umgehen dies, indem Sie alle Ihre Klassen global zugänglich machen wollen, ohne dass Browserify oder Webpack verwendet werden sollen. Sie brauchen wahrscheinlich keine separate '' in Ihrem HTML und sollten stattdessen eine Einstiegspunkt-js-Datei haben, die die Skripte importiert/benötigt, von denen sie abhängt. Dies sollte die Eintragsdatei sein, die Sie für Browserify oder Webpack angeben. – fvgs

+0

Sie sagen "sollte stattdessen einen Einstiegspunkt js Datei, die importiert/erfordert die Skripte", aber ich benutze Javascript aus dem Browser und kann nicht importieren oder erfordern ... – cdarwin

0

Webpack oder Browserify Ihre Skripte in bestimmtem Kontext bündeln, so dass Sie nur die Klassen oder Funktionen in diesem gebündelt Kontext in Verbindung treten können, die irgendwo in der mitgelieferten Skript. Wenn Sie also ein weiteres Skript in HTML hinzufügen, kann es nicht auf den Kontext dieses gebündelten Skripts zugreifen. Wenn Sie auf die App-Klasse zugreifen wollen, können Sie, soweit ich weiß, das neue Skript importieren/exportieren (das jetzt nur eine neue App erstellt) in den test.js

+0

können Sie besser angeben, was Sie für "Importieren/Exportieren des neuen Skripts" benötigen? – cdarwin

+0

Grundsätzlich würde ich vermeiden, neues Skript in HTML mit hinzufügen und machen webpack Eintragsdatei enthält alle Skripte, wie implementieren App in einer anderen Datei, app.js und importieren sie in test.js (das ist Eintragsdatei) –

Verwandte Themen