Суббота, 22 апреля 2017 г.
Срок действия ваших ресурсов CSS и JS в далеком будущем гарантирует, что посетители загружают их из кеша как можно чаще, повышая скорость страницы и снижая затраты на пропускную способность. Но бывает сложно заставить посетителей загрузить новую версию до истечения срока действия старой. CDN усиливает проблему. Когда вы распространяете свои активы в CDN, такой как Cloudfront, серверы CDN по всему миру запрашивают новую копию только после истечения срока действия активов. Если вы хотите распространить новую версию файла в CDN до истечения срока действия старой, вам необходимо отправить запрос на аннулирование; аннулирование не происходит мгновенно и может даже стоить денег.
Вы можете решить эту проблему, добавив хэш содержимого файла к имени файла, например:
app-bundle-902805999c154c77880d.js
Таким образом, каждая новая версия будет иметь другое имя файла, поэтому вам не нужно заменять старые.
Сборщик ресурсов webpack может генерировать хэш содержимого исходного файла и добавлять его к выходному файлу, но теперь вам нужно изменить теги <script>
, чтобы они указывали на новое имя файла. HTMLWebpackPlugin решает эту проблему, также генерируя тег <script>
. Это также работает для включения ваших ресурсов в файл, который использует язык шаблонов, такой как Freemarker или Go templates, вместо простого HTML.
Установите HTMLWebpackPlugin:
npm i html-webpack-plugin
В файле конфигурации веб-пакета измените выходное имя, чтобы оно содержало хэш содержимого файла:
module.exports = {
...
output: { filename: '[name]-bundle-[chunkhash].js' }
...
}
Затем импортируйте HTMLWebpackPlugin вверху конфигурации веб-пакета:
const HTMLWebpackPlugin = require('html-webpack-plugin');
и добавьте новую запись в массив plugins
:
module.exports = { output: {...}, module: {...}, plugins: [new HtmlWebpackPlugin({ template: 'static/scripts-template.html', inject: false, filename: 'scripts.html'})] }
template
задает путь к шаблону, который HTMLWebpackPlugin использует для создания файла, содержащего тег <script>
. inject: false
указывает плагину не вставлять теги include в вывод автоматически. filename
задает путь, по которому HTMLWebpackPlugin генерирует собственный вывод.
В static/scripts-template.html
используйте собственный интегрированный язык шаблонов HTMLWebpackPlugin для вывода нужных <script>
тегов:
<% htmlWebpackPlugin.files.js.forEach(function(file) { %> <script src="<%= file %>"></script> <% }); %>
Это выводит тег <script>
для каждого сгенерированного файла JavaScript. В качестве альтернативы, если вы просто хотите вывести каждый файл, который генерирует веб-пакет, включая CSS, вы можете оставить шаблон полностью пустым и установить inject: true
, а HTMLWebpackPlugin автоматически вставит соответствующие теги <style>
и <script>
.
После запуска сборки веб-пакета сгенерированный файл scripts.html
будет содержать только теги сценария. Затем вы можете импортировать его на любом языке шаблонов на стороне сервера, например, с помощью Go:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
<link href="styles.css" rel="stylesheet"></head>
<body>
<div id="app">
</div>
{{ template "scripts.html" }}
</body>
</html>
Таким образом, вы получаете преимущества кэширования хешированных имен файлов, не заменяя вручную пути в ваших HTML-файлах.
Если вы хотите узнать больше о настройке сборки веб-пакета с нуля, вы можете прочитать мою книгу.
Первоначально опубликовано на www.ludovf.net.