web-dev-qa-db-fra.com

Exiger des fichiers JS dynamiquement lors de l'exécution à l'aide de webpack

J'essaie de porter une bibliothèque de grunt/requirejs vers webpack et suis tombé sur un problème, qui pourrait être un jeu-breaker pour cette entreprise.

La bibliothèque que j'essaye de porter a une fonction, qui charge et évalue plusieurs modules - en fonction de leurs noms de fichiers que nous obtenons d'un fichier de configuration - dans notre application. Le code ressemble à ceci (café):

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

Le require ici doit être appelé lors de l'exécution et se comporter comme il le faisait avec requireJS. Webpack semble ne se soucier que de ce qui se passe dans le "processus de construction".

Est-ce quelque chose dont Webpack ne se soucie pas fondamentalement? Si oui, puis-je toujours utiliser requireJS avec lui? Quelle est la bonne solution pour charger dynamiquement des actifs pendant l'exécution?

edit: loadModule peut charger des modules qui ne sont pas présents lors de la construction de cette bibliothèque. Ils seront fournis par l'application qui implémente ma bibliothèque.

24
sra

J'ai donc constaté que mon exigence de charger certains fichiers à l'exécution, qui ne sont disponibles que sur "app-compile-time" et non sur "library-compile-time" n'est pas facilement possible avec webpack.

Je vais changer le mécanisme, afin que ma bibliothèque ne nécessite plus les fichiers, mais doit passer les modules requis. Cela me dit quelque peu que ce sera de toute façon la meilleure API.

modifier pour clarifier:

Fondamentalement, au lieu de:

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

Je fais ça:

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

Le premier code fonctionnait dans require.js mais pas dans webpack.

Avec le recul, je pense qu'il est tout à fait erroné d'avoir un fichier de chargement de bibliothèque tiers au moment de l'exécution de toute façon.

15
sra

Il existe un concept nommé context ( http://webpack.github.io/docs/context.html ), il permet de faire des exigences dynamiques.

Il existe également une possibilité de définir des points de partage de code: 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));
}

Et utilisez-le comme suit:

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

Mais ce n'est probablement pas ce dont vous avez besoin - vous aurez beaucoup de morceaux au lieu d'un bundle avec tous les modules requis, et ce ne serait probablement pas optimal.

Il est préférable de définir le module requis dans votre fichier de configuration et de l'inclure dans votre build:

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

// run.js
require('modulesConfig').forEach(function(module){
    module(moduleAPI);
})
9
Bogdan Savluk

Vous pouvez également essayer d'utiliser une bibliothèque comme celle-ci: https://github.com/Venryx/webpack-runtime-require

Avertissement: je suis son développeur. Je l'ai écrit parce que j'étais également frustré par l'impossibilité d'accéder librement au contenu du module lors de l'exécution. (dans mon cas, pour tester depuis la console)

2
Venryx