Динамический модуль загрузки веб-пакетов по требованию

Хорошо, я выполнил поиск по максимуму и минимуму, но не могу точно определить, возможно ли это с помощью веб-пакета.

https://github.com/webpack/webpack/tree/master/examples/require.context Появляется, чтобы указать, что можно передать строку в функцию и загрузить модуль...

Но моя попытка просто не работает: 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"
    }
};

Сервер.js

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

require( 'modules/test' )();

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

Модуль в модулях / с именем test.js

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

Но результат всегда один и тот же... журналы pm2 просто говорят "привет, мир" для статической потребности... но для динамической загрузки одного и того же модуля

Ошибка: не удается найти модуль "."

Все, что я хочу сделать, это перебрать массив путей к модулям и загрузить потом...

2 ответа

Решение

Вы не можете использовать переменную в качестве аргумента require, Webpack должен знать, какие файлы связывать во время компиляции. Так как он не выполняет анализ потока программы, он не может знать, что вы передаете функции. В этом случае это может быть очевидным, но это может пойти до использования пользовательского ввода, чтобы решить, какой модуль требовать, и нет никакого способа, которым webpack может знать, какие модули включить во время компиляции, поэтому webpack не позволяет этого.

Пример, который вы опубликовали, немного другой. Вы могли бы использовать require со связанной строкой. Например:

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

Какие модули необходимо включить в пакет? Переменная moduleName может быть что угодно, поэтому точный модуль не известен во время компиляции. Вместо этого он включает все модули, которые могут соответствовать приведенному выше выражению. Предполагая следующую структуру каталогов:

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

Все из этого test.js файлы будут включены в комплект, потому что moduleName может быть one или что-то вроде вложенного two/subdir,

Для более подробной информации см. Требуется с выражением официальных документов.

Вы не можете циклически проходить по массиву и импортировать каждый модуль массива, с вышеупомянутым исключением, объединяя строку, но это приводит к включению всех возможных модулей и, как правило, этого следует избегать.

Я столкнулся с этой проблемой в электронной среде. Мой вариант использования был в состоянии require динамически создаваемые файлы в IDE-подобном приложении. Я хотел использовать электрон require, который в основном является загрузчиком модулей NodeJS Common. После некоторого взад и вперед я нашел решение, которое использует noParse Конфигурация модуля.

Сначала создайте модуль, который будет игнорироваться парсером 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 = global.require

В моем конфиге webpack, под module, дайте указание сборщику не анализировать этот модуль:

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

Наконец, для любого пакета, к которому вы хотите получить доступ к оригиналу, требуются:

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

Немного поздно.... но... так как вы связываетесь с target: 'node'Существует обходной путь для динамических требующих модулей и обходящих "эффект включения всех возможных модулей".

Решение снято с:

Использование динамического требования на целевых узлах БЕЗ разрешения или связывания целевого модуля. Проблема № 4175.

Цитируется из этого комментария:

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

Связки с:

const requireFunc = true ? require : require;
const foo = requireFunc(moduleName);
Другие вопросы по тегам