Как динамически разделить по каталогам с помощью плагина Webpack/SplitChunks?

Я пытаюсь разделить код React (созданный с помощью create-реагировать-приложение) с помощью плагина splitChunks следующим образом:

У меня есть следующие компоненты (JSX) структура:

  • Сервисы
    • serviceA
      • ComponentA1
      • ComponentA2
      • пОДПАПКА
        • ComponentA3
      • ...
    • serviceB
      • ComponentB1
      • ComponentB2
      • ...
    • serviceC
      • ComponentB1
      • ComponentB2
      • ...
    • ...

и я хочу иметь следующий вывод (сборка):

  • статические / JS
    • serviceA
      • serviceA.bundle.chunkhash.js
    • serviceB
      • serviceB.bundle.chunkhash.js
    • serviceC
      • serviceC.bundle.chunkhash.js

(другие среды выполнения / сети находятся в корне / static/js)

Другое ограничение заключается в том, что компоненты загружаются динамически с

const Component = lazy(() => import(componentPath));
...
<Suspense fallback={..}>Component</suspense>

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

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

static/js/serviceA/  ==> js served by Docker container running service A
static/js/serviceB/  ==> js served by Docker container running service B
static/js/serviceC/  ==> js served by Docker container running service C

До сих пор я пытался:

  • установите для output.chunkFilename значение [name]/[name].[chunkhash].js
  • используйте webpackChunkName с [name] и [request]:

    • [имя], похоже, не работает (буквально буквально "[имя]" является частью моего имени каталога).

    • [request] выравнивает название каталогов:

      serviceA-ComponentA1 serviceA-ComponentA2 serviceA-subFolder-ComponentA3 serviceB-компонент B1 сервис B-компонент B2 ...

Затем я попытался использовать плагин splitChunks со следующим:

  splitChunks: {
    chunks: 'all',
    name: function(module) {
      let serviceName = module.rawRequest ? module.rawRequest : 'default';
      serviceName = serviceName.replace('../', '').replace('./', '');
      serviceName = serviceName.split('/')[0];
      return serviceName;
    },
    cacheGroups: {
      vendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10
      },
      default: {
        minChunks: 2,
        priority: -20,
        reuseExistingChunk: true
      },
      serviceA: {
        test: /[\\/]serviceA[\\/]/,
        priority: -10
      },
      serviceB: {
        test: /[\\/]serviceB[\\/]/,
        priority: -10
      },
      serviceC: {
        test: /[\\/]serviceC[\\/]/,
        priority: -10
      },              
    }
  },

Этот подход выглядит как работающий, так как все мои сервисы находятся в своих собственных каталогах. Но у меня все еще есть некоторые дополнительные каталоги в виде чисел (вероятно, идентификатор пакета), которые я бы предпочел включить в стандартную.

Итак, вопрос в том, правильный ли мой подход?

0 ответов

Я не уверен, подойдет ли вам следующий вариант. У меня была аналогичная проблема, когда мне нужно было, чтобы разные папки выводились в разных пакетах.

В моем случае я начал с предложенного здесь решения glob. Затем, зная, что мне нужен массив входных данных для каждого желаемого результата, я придумал следующее:

const path = require('path');
const glob = require('glob');

const plugins = [...];

module.exports = {
    entry: glob.sync('./src/**/*.js').reduce((acc, item) => {
        const path = item.split('/');
        path.pop();
        const rootFolder = path[2] ? `${path[0]}/${path[2]}` : path[0];
        if (acc[rootFolder]) {
            acc[rootFolder].push(item);
        } else {
            acc[rootFolder] = [item];
        }
        return acc;
    }, {}),
    output: {
        filename: '[name]/main.js',
        path: path.resolve(__dirname, 'dist'),
    },
  module: { ... },
    plugins,
};

Это упрощенная версия моей конфигурации, и ее, вероятно, можно было бы улучшить, но она отлично подходит для моих нужд.:)

Дополнительная информация о библиотеке glob: https://github.com/isaacs/node-glob

Другие вопросы по тегам