Мы обнаружили, что когда мы начали использовать балансировщик нагрузки, мы столкнулись с очень серьезной проблемой с нашими интерфейсными ресурсами.

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

Вот так это выглядело.

На картинке выше вы можете видеть, что у некоторых файлов просто разные хэши. Но содержимое файлов абсолютно одинаковое (см. Размер файлов).

Нам нужно было найти причину. Некоторые парни обвинили WebPack. Я хотел разобраться, что именно не так.

Я нашел несколько соответствующих статей и проблему на github.







Некоторые думают, что его дерьмо происходит из-за того, что WebPack делает что-то не так внутри метода, который вычисляет хеш-код MD5 для модулей во время компиляции. Спойлер: Это неправда. Внутри WebPack все нормально.

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

Я попытался установить webpack-md5-hash, как это рекомендовалось в статье выше. Этот плагин очень простой. Вкратце, что он делает:

compilation.plugin("chunk-hash", function(chunk, chunkHash) {
  ...
  var chunk_hash = md5(source)
  chunkHash.digest = function () { return chunk_hash }
})

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

Я использовал Mac OS и Debian. Мой товарищ по команде помог мне с тестированием.

Мы очистили наш webpack.config.js и удалили почти все точки входа, кроме единственной, которая имела различие в хэшах на разных машинах.

Мы сохранили переменную source на Mac и Debian. Мы обнаружили следующее:

Ой! Мой! Похоже, мы нашли проблему. Когда мы используем шаблонизатор JADE, метод require использует абсолютный путь. Безумная вещь! Как это возможно?

Но это был только первый шаг. После этого в другом файле мы нашли похожую вещь.

3 шага для решения проблемы

В итоге мы нашли 3 причины нашей проблемы:

  • JADE использует абсолютные пути в требованиях
  • script-loader плагин использует абсолютные пути в требуемых
  • expose-loader плагин использует абсолютные пути в требуемых

Мы даже нашли PR по этому поводу. К сожалению, они не были объединены.





Есть официальная рекомендация по написанию загрузчиков.



Чтобы решить проблему, нам пришлось:

  • Обновите JADE до PUG
  • Используйте пропатченный script-loader плагин #patch
  • Используйте плагин patchedexpose-loader #patch

История еще не закончена

Мы исправили несколько наиболее очевидных случаев, но это еще не все.

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

Этот очень странный случай происходит в разных операционных системах. В настоящее время мы думаем, что при использовании одной и той же ОС такой проблемы не возникает. Выглядит так, но я не уверен на 100%. Как пойдет, покажет время.

Еще одна интересная вещь: мы думаем, что эта проблема возникла после того, как мы заменили JADE на PUG.

Еще одна проблема, с которой мы столкнулись, выглядит так:

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

Ничего страшного, что у нас его сейчас нет, но я помню об этом и беспокоюсь по этому поводу.

Что я узнал?

  1. В экосистеме WebPack есть плагины, которые создают проблемы. Некоторые из них давно не обновляются, даже если они очень популярны и находятся в репозитории webpack-contrib.
  2. Если вы хотите написать загрузчик, вы всегда ДОЛЖНЫ использовать относительный путь в коде модуля.
  3. Есть некоторые неопределенные проблемы с WebPack и плагинами. Эти проблемы могут повлиять на хэши активов, и это может быть критической проблемой для производственной среды. Вот почему в настоящее время меня это беспокоит.
  4. В WebPack есть несколько странный способ определения хэшей для модулей.

ОБНОВЛЕНИЕ: май 2019 г.

В другом проекте я обнаружил, что правила линтера время от времени меняются. Пробелы добавляются и удаляются случайным образом после yarn install. Вы узнали кейс из «История еще не закончена»? Похоже, линтер может быть потенциальной причиной проблемы. Но этот шанс очень мал, и мы можем его просто упустить.