web-dev-qa-db-fra.com

chargeur de module dynamique webpack par require

OK, j'ai cherché haut et bas mais je ne peux pas dissuader de manière fiable si c'est ou n'est pas possible avec webpack.

https://github.com/webpack/webpack/tree/master/examples/require.context Apparaît pour indiquer que l'on peut passer une chaîne à une fonction et charger un module ...

Mais ma tentative ne fonctionne tout simplement pas: webpack.config.js

'use strict';
let webpack     = require('webpack'),
    jsonLoader  = require("json-loader"),
    path        = require("path"),
    fs          = require('fs'),
    nodeModules = {};

fs.readdirSync('node_modules')
    .filter(function(x) {
        return ['.bin'].indexOf(x) === -1;
    })
    .forEach(function(mod) {
        nodeModules[mod] = 'commonjs ' + mod;
    });


let PATHS = {
    app: __dirname + '/src'
};

module.exports = {
    context: PATHS.app,
    entry: {
        app: PATHS.app+'/server.js'
    },
    target: 'node',
    output: {
        path: PATHS.app,
        filename: '../build/server.js'
    },
    externals: nodeModules,
    performance: {
        hints: "warning"
    },
    plugins: [
        jsonLoader
    ],
    resolve: {
        modules: [
            './node_modules',
            path.resolve(__dirname),
            path.resolve(__dirname + "/src"),
            path.resolve('./config')
        ]
    },
    node: {
        fs: "empty"
    }
};

Le serveur.js

let _ = require('lodash');
let modules = [ "modules/test" ];

require( 'modules/test' )();

_.map( modules, function( module ){
    require( module );
});

Le module dans modules/named test.js

module.exports = () => {
    console.log('hello world');
};

Mais le résultat est toujours le même ... les journaux pm2 disent juste bonjour le monde pour les besoins statiques ... mais pour la charge dynamique du même module

Erreur: impossible de trouver le module "."

Tout ce que je veux faire, c'est parcourir un tableau de chemins vers les modules et charger ensuite ...

11
John

Vous ne pouvez pas utiliser une variable comme argument pour require. Webpack doit savoir quels fichiers regrouper au moment de la compilation. Comme il ne fait aucune analyse de flux de programme, il ne peut pas savoir ce que vous passez à la fonction. Dans ce cas, cela pourrait être évident, mais cela pourrait aller jusqu'à l'utilisation de l'entrée utilisateur pour décider du module à exiger, et il n'y a aucun moyen pour webpack de savoir quels modules inclure au moment de la compilation, donc webpack ne le permet pas.

L'exemple que vous avez publié est un peu différent. Vous pouvez utiliser require avec une chaîne concaténée. Par exemple:

require(`./src/${moduleName}/test`);

Quels modules Webpack doit-il inclure dans le bundle? La variable moduleName peut être n'importe quoi, donc le module exact n'est pas connu au moment de la compilation. Au lieu de cela, il inclut tous les modules qui pourraient éventuellement correspondre à l'expression ci-dessus. En supposant la structure de répertoires suivante:

src
├─ one
│   └─ test.js
├─ two
│   ├─ subdir
│   │   └─ test.js
│   └─ test.js
└─ three
    └─ test.js

Tous ces test.js les fichiers seront inclus dans le bundle, car moduleName pourrait être one ou quelque chose imbriqué comme two/subdir.

Pour plus de détails, voir requis avec expression des documents officiels.

Vous ne pouvez pas parcourir un tableau et importer chaque module du tableau, à l'exception ci-dessus en concaténant une chaîne, mais cela a pour effet d'inclure tous les modules possibles et doit généralement être évité.

34
Michael Jungo

J'ai rencontré ce problème dans un environnement d'électrons. Mon cas d'utilisation était en mesure de require des fichiers créés dynamiquement dans une application similaire à IDE. Je voulais utiliser l'électron require, qui est essentiellement un NodeJS Common Après quelques allers-retours, j'ai atterri sur une solution qui utilise la configuration du module noParse de webpack.

Créez d'abord un module qui sera ignoré par l'analyseur de webpack:

// file: native-require.js
// webpack replaces calls to `require()` from within a bundle. This module
// is not parsed by webpack and exports the real `require`
// NOTE: since the module is unparsed, do not use es6 exports
module.exports = require

Dans ma configuration webpack, sous module, demandez au bundler de ne pas analyser ce module:

{
  module: {
    noParse: /\/native-require.js$/,
  }
}

Enfin, dans tout bundle où vous souhaitez accéder à l'original, vous devez:

import nativeRequire from './native-require`
const someModule = nativeRequire('/some/module.js') // dynamic imports
7
Josiah Ruddell

Un peu tard .... mais ... puisque vous vous regroupez sur target: 'node', il existe une solution de contournement aux modules dynamiques nécessitant, et en contournant "l'effet d'inclure tous les modules possibles" .

La solution est levée de:

tilisation de la demande dynamique sur des cibles de nœuds SANS résoudre ou regrouper le module cible · Problème # 4175 · webpack/webpack

Cité de ce commentaire:

const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
const foo = requireFunc(moduleName);

Offres groupées à:

const requireFunc = true ? require : require;
const foo = requireFunc(moduleName);
2
Gobot