Как написать плагин Webpack, который добавляет модули в пакет на лету на основе других модулей?
У меня возникла проблема с написанием плагина Webpack для службы перевода.
Цель состоит в следующем:
- Получите имена (и исходный код) всех необходимых модулей во время компиляции. Мне нужно иметь возможность сканировать исходный код для специального использования функции
t()
, но я хочу сканировать только те модули, которые будут включены в комплект (который, в зависимости от конфигурации сборки, может быть подмножеством всех модулей проекта).
- На основе собранных модулей я хочу создать дополнительные модули (с переводами) "на лету" и добавить их в комплект. Эти модули должны иметь возможность импортировать собственные зависимости.
Дополнительным требованием является то, что функция разделения кода Webpack должна работать с модулями, создаваемыми "на лету" (я хочу извлечь их для разделения файлов - например, bundle.[lang].js
). Кроме того, это может быть вне сферы действия этого вопроса, я должен сделать эти куски с необязательными переводами (так что вам не нужно загружать все языки, но только один).
Более подробную информацию можно найти в https://github.com/ckeditor/ckeditor5/issues/387.
Я пытаюсь несколько решений, но документация Webpack 2 не очень полезна. Я могу получить все модули, прослушивая крючки разрешения модуля (before-resolve
), но я не знаю, когда разрешены все зависимости, и я не знаю, смогу ли я добавить после этого дополнительные модули (и как это сделать - есть addEntry
ok и когда я могу его использовать?).
Я также думал о подключении плагина Webpack и загрузчика Webpack (потому что эта функция мне очень похожа на стиль-загрузчик Webpack), но из уровня плагина я может только добавить путь к загрузчику, а не самому загрузчика, поэтому я не могу передать объект конфигурации в качестве параметра - я не прав?
PS. Я использую Webpack 2. Если вам кажутся вам странные требования, см. https://github.com/ckeditor/ckeditor5/issues/387:).
Ответы
Ответ 1
Это очень сложный вопрос, но я могу показать, как вы можете добавлять дополнительные зависимости к определенным модулям, как если бы они требовались от этого модуля. Это гарантирует, что ваши добавленные модули будут в правильных кусках, а также будут удалены, если родительский модуль будет удален из пакета.
const CommonJsRequireDependency = require("webpack/lib/dependencies/CommonJsRequireDependency")
class MyPlugin {
apply(compiler) {
compiler.plugin("compilation", compilation => {
compilation.plugin("succeed-module", module => {
// this will be called for every successfully built module, but before it parsed and
// its dependencies are built. The built source is available as module._source.source()
// and you can add additional dependencies like so:
module.dependencies.push(new CommonJsRequireDependency("my-dependency", null))
}
}
}
}
Это только одна его часть. Вам также, вероятно, потребуется написать собственный загрузчик, чтобы на самом деле генерировать переводы (вы можете заменить my-dependency
выше на my-loader!path/to/module
, чтобы вызвать его немедленно), и некоторый шаг после создания кусков, чтобы, возможно, извлечь их в новый актив и загружайте их, поскольку они на самом деле не являются require
d в любом месте.