Выполните NormalModule во время сборки, после того как он будет собран загрузчиками, затем сохраните в файл json - PullRequest
0 голосов
/ 12 мая 2018

Я пишу плагин, который для определенных модулей будет пытаться выполнить модуль, сгенерированный во время сборки, чтобы сохранить результат в файле json.

Для этого я подключаюсь к compilation.hooks.succeedModule, который получает NormalModule объект, уже построенный.Затем я пытаюсь вычислить источник, заменив переменные веб-пакета, такие как __webpack_public_path__.

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

Есть ли хороший способ выполнить модули во время сборки из объекта NormalModule, имеющего базовый доступ к переменным, таким как __webpack_public_path__?Может быть, Webpack предлагает лучший способ сделать такие вещи?

1 Ответ

0 голосов
/ 12 мая 2018

Хорошо, да, звучит так, как будто вы можете решить эту проблему другим способом, я делал подобные вещи, где мне нужно было изменить то, что выводит модуль, записать материал на диск, вызвать побочные эффекты и т. Д. Похоже, вам нужны скорее загрузчикичем плагин.run-loader (https://www.npmjs.com/package/webpack-run-loader) выполняет модуль, который загружает и экспортирует или возвращает результат.

Вы можете написать пользовательский загрузчик, который вы запускаете по цепочке после responsive-loader и run-loader,и который получает JSON от run-loader и записывает его на диск, где вы хотите его (в качестве побочного эффекта), а затем возвращает пустую строку, чтобы ничего не было добавлено в сборку. Конечный результат будет то, что требуется этот модуль вваше приложение получает созданные вами файлы изображений (responsive-loader) и записывает JSON на диск там, где вам это нужно (с помощью своего пользовательского загрузчика). Вы также можете пропустить run-loader, а в своем пользовательском загрузчике использовать regex, чтобы просто получитьJSON из вывода responsive-loader. Использование регулярных выражений в коде, сгенерированном зависимостью проекта, кажется хрупким, но пока у вас заблокированы версии зависимостей, на практике это может работать просто отлично, и концептуально это немного проще, чем добавление run-loader в конвейер.

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

// img-info-logging-loader.js
// regex version, expects source arg to be output of responsive-loader
import * as fs from 'fs';

export const imgInfoLoggingLoader = (source) => {
  const jsonFinderRegex = /someregexto(match)onsource/;
  const desiredJSON = source;
  const matchArr = jsonFinderRegex.exec(desiredJSON);
  if (!matchArr[1]) {
    throw new ReferenceError('json output not found in loader source.');
  } else {
    const imgConfigJsonString = matchArr[1];

    // you would write a fn to generate a filename based on the 
    // source, or based on the module's filename, which is available
    // via the webpack loader api
    const fileNameToWrite = getFileNameTowrite(); 

    try {
      // async might be preferable depending on your webpack 
      // performance needs
      fs.writeFileSync(fileNameToWrite, imgConfigJsonString); 
    } catch (err) {
      throw new Error(`error writing ${fileNameToWrite}`);
    }
  }

  // what the loader inserts into your JS asset: empty string
  return ''; 
}

РЕДАКТИРОВАТЬ: Поскольку в соответствии с вашим комментарием вы хотите вывести один объект JSON со всей информацией об изображении в нем, вы хотели бы немногодругой подход, который использует плагин (это самый элегантный способ, который я знаю, могут быть и другие).Насколько я знаю, плагин - это единственный способ «сделать что-то», когда веб-пакет завершает загрузку модулей.

  1. Вам все еще нужен пользовательский загрузчик, который извлекает JSON из вывода responsive-loader, как описано выше.Это не будет писать каждый на диск, хотяВместо этого ваш загрузчик вызовет метод для следующего модуля:
  2. Вы также напишите json-collector.js, который является просто небольшим модулем узла, который вы будете использовать для удержания объекта JSON, который вы строите.Этот бит неудобен, потому что он отделен от загрузчика, но загрузчик нуждается в нем.Этот модуль коллектора, тем не менее, прост, и если вы хотите быть чище, вы можете превратить его в более общий модуль и рассматривать его как правильную, отдельную зависимость от узла.Все это объект с методом добавления данных JSON, который добавляет его к внутреннему объекту JSON, и один для чтения собранных данных, который возвращает JSON.
  3. И затем у вас есть плагин, которыйв конце сборки (я думаю, что есть один для «сборки запечатан», который я использовал).Когда этот хук достигнут, вы знаете, что в webpack больше нет модулей для загрузки, поэтому плагин теперь вызывает метод 'read' для json-collector, получает из него объект JSON и записывает его на диск.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...