Подтвердить что ты не робот

Плагин Webpack: как я могу изменить и повторно разобрать модуль после компиляции?

Я работаю над плагином webpack и не могу понять, как модифицировать модуль во время сборки. Что я пытаюсь сделать:

  • Соберите данные через пользовательский загрузчик (отлично)
  • После того, как все модули загружены, собирайте данные, собранные моим загрузчиком (отлично)
  • Вставить код, который я сгенерировал в существующий модуль в сборке (сделав это, как описано ниже, не уверен, что это лучший способ)
  • "обновить" этот модуль, чтобы код, который я добавил, анализировался, и его "требование превратилось в веб-пакет требует вызовов" (не может понять, как это сделать правильно).

В настоящее время я подключаюсь к "этой компиляции" в компиляторе, а затем "дополнительные-chunk-assets" в компиляции. Схватив первый кусок (единственный, в настоящее время, поскольку я все еще в разработке), итерации через модули в этом куске, чтобы найти тот, который я хочу изменить. Тогда:

  • Добавление моего сгенерированного источника в модуль _cachedSource.source._source._value (я также попытался добавить к модулю._source._value)
  • установка._cachedSource.hash в пустую строку (поскольку это кажется необходимым для следующего шага для работы)
  • Я передаю модуль в .rebuildModule()

Похоже, rebuildModule должен повторно проанализировать источник, восстановить зависимости и т.д. и т.д., но он не анализирует мои требования и не требует их изменения в webpack. Встроенный файл включает мой измененный источник, но требования ( "..." ) не изменяются.

Как я могу сделать модуль модифицированным "обновить", чтобы webpack обрабатывал мой добавленный источник так же, как и исходный анализируемый источник? Есть ли что-то, что мне нужно сделать в дополнение к rebuildModule()? Я делаю эту работу слишком поздно в процессе сборки? Или я собираюсь сделать это неправильно?

4b9b3361

Ответ 1

Я понял, как это сделать довольно безболезненным способом.

Вещи, в которых я ошибался:

  • возможно, слишком поздно? самый ранний плагин, в котором вы можете это сделать, - это плагин "печать". Несмотря на название, этот плагин-крючок выполняется как самая первая строка в функции уплотнения, поэтому уплотнения еще не произошло. На этом этапе все модули были загружены.
  • rebuildModule() не является хорошей идеей, потому что это перезагружает модуль с нуля: источник файла загружается и передается через любые применимые загрузчики, а свойство _source объекта module в конечном итоге переназначается когда этот процесс будет завершен.
    • Использование rebuildModule() в этом месте было бы действительно здорово, если бы был способ изменить источник модуля, поскольку он был загружен в этот вызов (т.е. динамически назначать функцию загрузчика, которая используется только при этом перестройке). Затем мы сможем использовать поведение sourceMap, которое происходит при загрузке источника модуля (см. Ниже).

Как я получил работу:

  • подключиться к плагину compilation 'seal', выполнить итерацию через компиляцию module и найти нужную
  • изменить источник модуля, например. module._source._value += extraCode;
  • повторите анализ модуля:

    module.parse.parse(module._source.source(), {
      current: module, 
      module.module,
      compilation: compilation,
      options: compilation.options
    });
    

Синтаксический анализ выполняется из метода NormalModule build, который называется более или менее сразу после того, как источник был загружен в процессе нормальной сборки модуля.

Эта реализация получает модифицированный и проанализированный источник в мой окончательный вывод. Так как там есть источник sourceMap в методе NormalModuleMixin doBuild, и, поскольку я добавляю к источнику после того, как эти функции были вызваны, я предполагаю, что sourceMap будет запутан сейчас. Итак, следующий шаг - заставить sourceMap отражать добавление кода. Не уверен, пытаться ли вручную обновить sourceMap или просмотреть описанную выше идею, пытаясь динамически применить загрузчик и вызвать rebuildModule() вместо разбора.

Если вы знаете лучший способ сделать что-либо из вышеперечисленного, пожалуйста, дайте мне знать!

Ответ 2

Другая мысль приходит мне на ум. Что делать, если делать предварительную обработку перед сборкой webpack?

  • Использовать babel + собственный плагин или даже собственный анализатор кода на основе babylon для сбора необходимых данных, а затем сохранить в файл temp.
  • Запустите webpack вместе с этим временным файлом.

Этот временный файл может быть виртуальным файлом. Может ссылаться на https://github.com/rmarscher/virtual-module-webpack-plugin/.

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