Понимание вашей системы сборки

По мере перехода от устаревших систем с ванильным кодом к расширенным системам сборки и одностраничным приложениям вы можете заметить некоторые изменения, которые не имеют немедленного смысла. Есть дополнительные шаги, которые немного не интуитивно понятны, и неясно, какая проблема решается. Одно из таких различий состоит в том, что <img src="./file.gif" /> больше не работает. Теперь вам нужно использовать import image from './file.gif';. Почему?

С такой системой сборки, как Webpack, ваше приложение больше не работает в том же каталоге, что и ваш HTML, например ваш src каталог. Он проходит через процесс «сборки», который сначала оптимизирует файлы перед выводом окончательного результата в другой каталог. Webpack обычно начинается с вашего index.js или index.ts файла. Он объединяет и минимизирует каждый найденный файл JavaScript, чтобы создать один гигантский оптимизированный файл JavaScript, содержащий весь ваш код. Этот единственный файл JS вставляется в ваш index.html, и этот index.html файл - это то, что вы видите в своем браузере. Это завершенное приложение запускается из вашего каталога build в производственной сборке или из памяти в сборке для разработки, а не из вашего каталога src. Для приложения React ваш каталог сборки, за исключением файлов CSS и JavaScript, которые генерирует Webpack, будет выглядеть примерно так же, как ваш каталог public.

Если Webpack никогда не видит ваш файл изображения, он не помещает его в каталог build. Насколько ему известно, это просто неиспользуемый файл, поэтому его не следует помещать в окончательный вывод. Точно так же, если вы создаете my-file.js в своем src каталоге, но никогда не используете его нигде, Webpack не включит его в окончательный пакет. Это хорошая вещь! Это было бы пустой тратой места!

Webpack не проверяет каталог src на наличие файлов. Webpack начинается с точки входа (index.js) и следует операторам import и require для поиска файлов для объединения. Когда вы import изображение, Webpack теперь знает, что вы его используете. Теперь Webpack «видит» это изображение.

Для импорта изображений используется пользовательский загрузчик изображений. Это отличается от импорта файла JavaScript. Когда вы импортируете файл JavaScript, загрузчик JavaScript предлагает включить весь этот JavaScript прямо здесь, прямо сейчас. Когда вы импортируете файл изображения, загрузчик изображения предлагает добавить изображение в окончательную сборку (чего бы вы не делали с <img src="..." />) и вернуть строку с URL-адресом изображения. Вы просто говорите ему: «Я хочу blank.gif», а он говорит: «Хорошо, я переместлю этот blank.gif файл в каталог сборки, а вот путь в каталоге сборки: /blank.some-unique-hashed-filename.gif». Вы используете этот путь к файлу в качестве атрибута src изображения, и браузер сможет получить доступ к этому файлу, потому что ваш браузер ищет файлы в build каталоге, а не в src!

Уникальный хеш, добавленный к URL-адресу изображения, решает две проблемы. Во-первых, он предотвращает перезапись image.gif из src/a/image.gif на src/b/image.gif. Во-вторых, он не позволяет клиенту увидеть устаревший кеш при обновлении изображения. Если клиент просматривает и постоянно кэширует image.gif, который был связан с src/a/image.gif, то вы, как разработчик, обновляете этот файл изображения, клиент по-прежнему видит их постоянно кэшированную версию. Постоянный кеш - отличный инструмент для повышения скорости загрузки и повышения качества обслуживания клиентов. Вместо отключения постоянного кеша лучшей альтернативой является предоставление и изменение уникального хеша при каждом изменении исходного файла изображения. Каждый раз, когда вы создаете свой image.gif файл, вы будете генерировать image.unique-hash-1.gif. Как только вы измените этот исходный image.gif файл, он станет image.unique-hash-2.gif, минуя клиентский кеш с image.unique-hash-1.gif и предоставляя им обновленное изображение.

Скорее всего, вы можете добиться аналогичного поведения, поместив свои статические (неизменные, удобные для кеширования) файлы в каталог public. Каталог public копируется в каталог сборки почти дословно. Единственное исключение - index.html переопределяется для включения вышеупомянутого пакета JavaScript. Если вы поместите blank.gif в свой public каталог, вы сможете ссылаться на него как на просто blank.gif, потому что, когда он копируется в каталог сборки, вы сможете найти его в каталоге сборки. Это отличается от файлов в src, которые копируются в каталог сборки только в том случае, если Webpack находит их через файл точки входа (index.js). Все остальное в src игнорируется.

Заключение 🔚

Если у вас есть какие-либо вопросы или вы хорошо разбираетесь в процессах сборки, оставьте их в комментариях ниже.

Чтобы читать больше моих колонок, вы можете подписаться на меня в LinkedIn и Twitter или посмотреть мое портфолио на CharlesStover.com.