2015-06-01 12 views
22

Sto provando a portare una libreria da grunt/requirejs al webpack e mi sono imbattuto in un problema, che potrebbe essere un rompicapo per questa impresa.Richiede i file JS in modo dinamico su runtime usando il webpack

La libreria che provo a port ha una funzione, che carica e valuta più moduli, in base ai nomi dei file che otteniamo da un file di configurazione, nella nostra app. Il codice simile a questo (caffè):

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

Il require qui ha bisogno di essere invitato runtime e si comportano come ha fatto con requireJS. A Webpack sembra interessare solo ciò che accade nel "processo di costruzione".

È qualcosa a cui il webpack non interessa fondamentalmente? In tal caso, posso ancora utilizzare requireJS con esso? Qual è una buona soluzione per caricare le risorse dinamicamente durante il runtime?

modifica: loadModule può caricare moduli, che non sono presenti sul build-time di questa libreria. Saranno forniti dall'app, che implementa la mia libreria.

+0

Ho un problema simile a Cordova, che utilizza un caricatore AMD non standard, ma la mia app è costruita utilizzando il webpack. La mia app dipende da alcuni plugin Cordova, che vengono caricati in runtime e non presenti in fase di compilazione. Ho provato molte soluzioni, ma nessuno di loro mi piace. Mi piacerebbe vedere la risoluzione del modulo webpack nativo delle dipendenze "runtime". In linea di principio l'implementazione dovrebbe essere facile. Alcune funzioni di fabbrica, che verranno chiamate (e restituiranno alcuni oggetti/funzioni definite in runtime), quando il modulo è richiesto da qualche altro modulo. – mauron85

+0

Aggiunta la richiesta di funzionalità al webpack. https://github.com/webpack/webpack/issues/5984 – mauron85

risposta

12

Così ho scoperto che la mia esigenza di avere alcuni file caricati sul runtime, che sono disponibili solo su "App- compile-time "e non su" library-compile-time "non è facilmente possibile con il webpack.

Cambierò il meccanismo, in modo che la mia libreria non richieda più i file, ma deve essere passato i moduli richiesti. In qualche modo mi dice, questa sarà comunque la migliore API.

modifica per chiarire:

In sostanza, invece di:

# 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") 

faccio questo:

# 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) 

Il primo codice ha lavorato in require.js ma non in webpack.

Con il senno di poi mi sembra piuttosto sbagliato avere un file di caricamento di libreria di terze parti comunque in fase di esecuzione.

+7

Perché questa risposta è stata downvoted? Ho bisogno di fare esattamente la stessa cosa dell'autore di questa domanda, e non ho ancora trovato il modo di farlo, il contesto funziona solo quando i file necessari sono presenti al momento della compilazione. – Dmitri

+0

Come hai risolto questo? Puoi pubblicare un esempio di codice. –

+0

Ho modificato la soluzione per maggiore chiarezza. Spero che questo aiuti – sra

8

C'è il concetto context (http://webpack.github.io/docs/context.html), consente di rendere dinamico richiede.

Inoltre v'è la possibilità di definire i punti di codice di divisione: 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)); 
} 

e usarlo come segue:

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

Ma probabilmente non è quello che serve - si vuole avere un sacco di blocchi invece di un pacchetto con tutti i moduli richiesti, e probabilmente non sarebbe ottimale ..

E 'meglio definire modulo richiede in te file di configurazione, e comprendono al vostro costruzione:

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

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

Grazie per la risposta. Non posso usare il contesto, perché sembra che quei moduli caricati dinamicamente debbano essere presenti in fase di costruzione. Questo non è il caso nella mia biblioteca. Saranno disponibili solo una volta creata l'app stessa, non nella mia libreria. – sra

Problemi correlati