2017-01-25 14 views
7

Mam skrypt test.js, który definiuje klasę App i który jest ładowany z pliku HTML, a wszystko działa.Uzyskiwanie dostępu do "publicznych" członków po pakiecie z przeglądarką lub pakietem internetowym

Po utworzeniu zestawu testBundle.js z test.js, używając przeglądarki internetowej lub pakietu WWW, klasa App w numerze testBundle.js nie jest już zdefiniowana.

W jaki sposób powinienem napisać kod lub jakie opcje powinienem podać przeglądarce, aby uzyskać zdefiniowaną aplikację i używać jej z HTML-a jak poprzednio, ale z pakietu ?.

Błąd pojawia po łączenie jest:

Uncaught ReferenceError: App is not defined 

pliku HTML jest następujący:

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

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

test.js:

'use strict'; 

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

polecenie, aby zbudować pakiet :

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

Wydaje mi się, patrząc na pakiet, że aplikacja jest rzeczywiście prywatna.

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

Wszystko to za pomocą JavaScript w przeglądarce, ES6.

+0

Niestety ale wierzę (nadzieja), że są lepsze sposoby, aby rozwiązać ten problem, Zaczyna się bounty – cdarwin

Odpowiedz

1

Zasadniczo to, co chcesz robić tworzy bibliotekę zamiast zwykłego pakietu. Jeśli korzystasz z WebPacka, możesz określić, że chcesz, aby Twoje dane wyjściowe były biblioteką, dzięki czemu będą dostępne globalnie w przestrzeni nazw, podobnie do jQuery.

// 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" 
    } 
} 

Następnie można wywołać wszystkie swoje funkcje przez Foo:

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

Dokumentacja & przykłady: https://webpack.github.io/docs/library-and-externals.html#examples

8

Próbujesz uzyskać dostęp do App w kontekście globalnym. Jednak App nie jest domyślnie udostępniany globalnie. Node.js korzysta z modułów, a Browserify respektuje dostarczanie modułów enkapsulacji. Podczas korzystania z narzędzi takich jak Browserify lub Webpack, najczęściej jest mieć jeden lub więcej modułów punktu wejścia (to znaczy plików), które wykorzystują moduł import/require() w celu uzyskania dostępu do innych modułów.

Ale jeśli chcesz mieć dostęp do App w kontekście globalnym w przeglądarce, można przypisać odniesienie do klasy App do własności window w test.js:

np

window.App = App; 

lub

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

to działa, ale jeśli mam inne klasy, muszę "wyeksportować" każdą z nich za pomocą windows.MyClass = MyClass na końcu każdego skryptu? Miałem nadzieję, że istnieje inne rozwiązanie. – cdarwin

+0

. Normalnym sposobem uzyskania dostępu do jednostek z innych modułów jest użycie importu/eksportu lub wymagania(). Pomijasz to, chcąc, aby wszystkie klasy były globalnie dostępne, a nie w jaki sposób mają być używane Browserify lub Webpack. Prawdopodobnie nie musisz mieć osobnego '' 'w swoim html i zamiast tego powinien on mieć plik js punktu wejścia, który importuje/wymaga skryptów, od których to zależy. Powinien to być plik wejściowy określony jako Browserify lub Webpack. – fvgs

+0

mówisz "powinien zamiast tego mieć plik js punktu wejścia, który importuje/wymaga skryptów", ale używam javascript z przeglądarki i nie mogę użyć importu lub wymagać ... – cdarwin

0

WebPACK lub Browserify pakiet skryptów w pewnym kontekście, więc można tylko skontaktować klasy lub funkcji w tym pakiecie kontekście, który jest w gdzieś w pakiecie skryptu. Kiedy dodajesz kolejny skrypt w HTML, nie ma on dostępu do kontekstu skryptu dołączonego do pakietu. Jeśli chcesz uzyskać dostęp do klasy App, o ile mi wiadomo, możesz zaimportować/wyeksportować nowy skrypt (który właśnie tworzy nową aplikację) do pliku test.js

+0

czy możesz określić lepszą wartość dla "importu/eksportu nowego skryptu"? – cdarwin

+0

Zasadniczo uniknęłabym dodania nowego skryptu w html z i sprawiłaby, że plik wpisu do Webpacka zawierałby wszystkie skrypty, np. Implementował aplikację w innym pliku, app.js i importował ją do pliku test.js (który jest plikiem wejściowym) –

Powiązane problemy