2015-06-01 12 views
22

Próbuję przenieść bibliotekę z pliku/requirejs do pakietu sieciowego i natknąłem się na problem, który może być przełomem dla tego przedsięwzięcia.Żądaj plików JS dynamicznie w środowisku wykonawczym za pomocą pakietu sieciowego

Biblioteka, którą próbuję portować, ma funkcję, która ładuje i ocenia wiele modułów - na podstawie ich nazw plików, które otrzymujemy z pliku konfiguracyjnego - do naszej aplikacji. Kod wygląda następująco (kawa):

loadModules = (arrayOfFilePaths) -> 
    new Promise (resolve) -> 
    require arrayOfFilePaths, (ms...) -> 
     for module in ms 
     module ModuleAPI 
     resolve() 

require tutaj musi być wywołana na starcie i zachowywać się jak to miało miejsce z requireJS. Wydaje się, że Webpack dba tylko o to, co dzieje się w "procesie budowania".

Czy to jest coś, co zasadniczo nie ma znaczenia dla pakietu internetowego? Jeśli tak, czy mogę nadal używać requireJS? Jakie jest dobre rozwiązanie do dynamicznego ładowania zasobów w czasie wykonywania?

edit: loadModule może załadować moduły, których nie ma w czasie kompilacji tej biblioteki. Będą one dostarczane przez aplikację, która implementuje moją bibliotekę.

+0

Mam podobny problem z Cordova, który używa niestandardowego programu ładującego AMD, ale moja aplikacja jest zbudowana przy użyciu pakietu internetowego. Moja aplikacja zależy od niektórych wtyczek Cordova, które są ładowane w środowisku uruchomieniowym i nie są obecne w czasie kompilacji. Próbowałem wielu rozwiązań, ale żaden z nich nie przemawiał do mnie. Chciałbym zobaczyć natywną rozdzielczość modułu webpack dla zależności "runtime". Zasadniczo wdrożenie powinno być łatwe. Pewna funkcja fabryczna, która zostanie wywołana (i zwróci obiekt/func zdefiniowane w środowisku wykonawczym), kiedy moduł jest wymagany przez jakiś inny moduł. – mauron85

+0

Dodano prośbę o dodanie funkcji do pakietu internetowego. https://github.com/webpack/webpack/issues/5984 – mauron85

Odpowiedz

12

Więc stwierdziliśmy, że mój wymóg posiadania pewnych plików załadowanych na starcie, które są dostępne tylko na „app- "kompilacja", a nie "biblioteka-kompilacja" nie jest łatwo dostępna przy użyciu pakietu internetowego.

Zmienię mechanizm, aby moja biblioteka nie wymagała już plików, ale musi zostać przekazana wymagane moduły. Trochę mi to mówi, to i tak będzie lepszym API.

edit wyjaśnienie:

Zasadniczo zamiast:

# in my library 
load = (path_to_file) -> 
    (require path_to_file).do_something() 

# in my app (using the 'compiled' libary) 
cool_library.load("file_that_exists_in_my_app") 

zrobić to:

# in my library 
load = (module) -> 
    module.do_something() 

# in my app (using the 'compiled' libary) 
module = require("file_that_exists_in_my_app") 
cool_library.load(module) 

Pierwszy kod pracował w require.js ale nie w WebPack.

Z perspektywy czasu uważam, że jest bardzo źle mieć pliki ładujące bibliotekę zewnętrzną w czasie rzeczywistym.

+7

Dlaczego ta odpowiedź jest odrzucana? Muszę zrobić dokładnie to samo, co autor tego pytania, i nie znalazłem sposobu, aby to zrobić, kontekst działa tylko wtedy, gdy potrzebne pliki są obecne w czasie kompilacji. – Dmitri

+0

Jak to rozwiązałeś? Czy możesz umieścić przykład kodu? –

+0

Edytowałem rozwiązanie dla większej przejrzystości. Mam nadzieję, że to pomoże – sra

8

Istnieje koncepcja o nazwie context (http://webpack.github.io/docs/context.html), która pozwala na dynamiczne wymagania.

Ponadto istnieje możliwość zdefiniowania punktów kod dzielone: ​​http://webpack.github.io/docs/code-splitting.html

function loadInContext(filename) { 
    return new Promise(function(resolve){ 
     require(['./'+filename], resolve); 
    }) 
} 

function loadModules(namesInContext){ 
    return Promise.all(namesInContext.map(loadInContext)); 
} 

i używać go jak następuje:

loadModules(arrayOfFiles).then(function(){ 
    modules.forEach(function(module){ 
     module(moduleAPI); 
    }) 
}); 

Ale prawdopodobnie nie jest to, czego potrzebujesz - będziesz mieć wiele porcji zamiast jednego pakietu ze wszystkimi wymaganymi modułami, i prawdopodobnie nie będzie to optymalne ..

Lepiej jest określić moduł wymaga w config pliku i umieścić go na swojej budowie:

// modulesConfig.js 
module.exports = [ 
    require(...), 
    .... 
] 

// run.js 
require('modulesConfig').forEach(function(module){ 
    module(moduleAPI); 
}) 
+5

Dzięki za odpowiedź. Nie mogę użyć kontekstu, ponieważ wydaje się, że te dynamicznie ładowane moduły muszą być obecne podczas budowania. Tak nie jest w mojej bibliotece. Będą dostępne tylko po uruchomieniu samej aplikacji, a nie mojej biblioteki. – sra

Powiązane problemy