Могу ли я получить дерево зависимостей, прежде чем webpack начнет строить?

Представляет ли webpack дерево зависимостей до того, как сборка будет запечатана? Я просмотрел весь экземпляр компилятора, но ничего не нашел о дереве зависимостей. Кажется, что в этом объекте должен быть один скрытый, потому что webpack должен знать, что это за дерево, чтобы впоследствии вывести stats.json.

Я пробовал использовать пакет npm файла dependency-tree, но он не поддерживает некоторые вещи, которые у меня есть в моей конфигурации webpack, поэтому дерево является неполным.

Ответ 1

TL; DR: Да, вы можете получить доступ к дереву зависимостей непосредственно перед его запечатыванием.

Для этого добавьте следующий код в ваш webpack.config.js:

class AccessDependenciesPlugin {
  apply (compiler) {
    compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
      compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
        /*
        |---------------------------------------------------
        | Here we go, 'modules' is what we're looking for!
        |---------------------------------------------------
        */
      })
    })
  }
}


module.exports = {
  // ...
  plugins: [
    new AccessDependenciesPlugin()
  ]
}

Для получения более подробной информации см. Объяснение ниже.


Крюк, который мы ищем

Мы можем получить доступ к предварительно запечатанному дереву зависимостей с помощью finishModules компиляции finishModules.


Откуда нам знать?

Поскольку документация о перехвате веб-пакетов очень минимальна (мягко говоря), нам пришлось прочитать исходный код веб-пакета, чтобы убедиться, что это то, что мы ищем:

Последнее, что делает компилятор перед закрытием дерева зависимостей, - это "заканчивает" его.

Завершение дерева зависимостей предлагает крючок для компиляции.


Пример кода

Мы создаем плагин с именем AccessDependenciesPlugin:

// Basic webpack plugin structure
class AccessDependenciesPlugin {
  apply (compiler) {

  }
}

Чтобы использовать хук компиляции, нам нужно сначала получить доступ к объекту compilation. Мы делаем это с помощью compilation:

class AccessDependenciesPlugin {
  apply (compiler) {
    compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
      // We have access to the compilation now!
    })
  }
}

Теперь нажмите на finishModules крючок compilation:

class AccessDependenciesPlugin {
  apply (compiler) {
    compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
      compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
        // Here we go, 'modules' is what we're looking for!
      })
    })
  }
}

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

И последнее, но не менее важное: нам нужно добавить плагин в нашу конфигурацию веб-пакета:

module.exports = {
  plugins: [
    new AccessDependenciesPlugin()
  ]
}

И мы сделали. 🎉


Надеюсь это поможет.


Бонусный контент: webpack 3

По запросу в комментариях: здесь версия AccessDependenciesPlugin для устаревшей системы плагинов webpack 3.

class AccessDependenciesPlugin {
  apply (compiler) {
    compiler.plugin('compilation', compilation => {
      compilation.plugin('finish-modules', modules => {
        /*
        |---------------------------------------------------
        | Here we go, 'modules' is what we're looking for!
        |---------------------------------------------------
        */
      })
    })
  }
}

Ответ 2

Возможно, строка кода из этого потока GitHub поможет вам:

"Скомпилировать с webpack --profile --json > stats.json

(node.js API: { profile: true } и stats.toJson())

Перейдите по адресу http://webpack.github.io/analyse/#modules.

Загрузите файл статистики (он не загружен, инструменты анализа - это клиентский инструмент).

Подождите немного, пока график не будет стабилизирован. "

Если это не то, что вам нужно, я бы заглянул в ответ @Loyo - более сложный, но, вероятно, больше того, что вам нужно.