Hugo и Tailwind
Репозиторий с готовым решением: https://gitlab.com/zina.design/hugo-tailwind
Tailwind работает как плагин PostCSS. Hugo умеет выполнять PostCSS через Hugo Pipes, но не всё — например, не умеет postcss-extract-media-query.
Задача: настроить работу с Tailwind по схеме:
- в режиме
development— только генерация полного CSS и максимально быстрая отзывчивость; - в режиме
production— обработка полного CSS:purgecssдля очистки от неиспользуемых классовpostcss-extract-media-queryдля разбивки CSS на отдельные файлы по Media Query (пример: https://gitlab.com/zina.design/zina-tailwind)- минификация всех HTML и CSS файлов.
Используем связку: Hugo + Tailwind CLI + NPM Scripts
Сборка Tailwind скриптами NPM — делается до запуска Hugo:
- в режиме dev — средствами Tailwind, чтобы можно было использовать JIT,
- в режиме prod — средствами PostCSS, чтобы можно было использовать
postcss-extract-media-query(см. ниже).
package.json:
"config": {
"csspath": "./assets/tailwind/tailwind.css -o ./assets/css/tailwind.css"
},
"scripts": {
"css:dev": "tailwindcss -i $npm_package_config_csspath",
"css:prod": "cross-env NODE_ENV=production postcss $npm_package_config_csspath",
}
В Hugo только минифицируем и добавляем fingerprint.
{{- $tailwind := resources.Get "css/tailwind.css" -}}
{{- if eq hugo.Environment "production" -}}
{{- $tailwind = $tailwind | minify | fingerprint -}}
{{- end -}}
<link rel="stylesheet" href="{{ $tailwind.RelPermalink }}" />
Media Query CSS
Если в postcss.config.js включен плагин postcss-extract-media-query, то во время сборки CSS средствами PostCSS генерируются отдельные файлы вида min-width-1024-px.css с кодом типа:
@media (min-width: 1024px) {
...
}
В Hugo мы берем все эти файлы из папки, указанной в postcss.config.js — типа:
path: path.join(__dirname, 'assets/css/mq')
сортируем их в естественном порядке (чтобы min-width-1024-px.css был после min-width-768-px.css, а не наоборот), минифицируем и добавляем fingerprint.
{{- if eq hugo.Environment "production" -}}
{{- $mqFilesSorted := slice -}}
{{- $mqSizes := slice 0 -}}
{{- range $index, $element := (sort (readDir "assets/css/mq") "Name") -}}
{{ $mqSizes = $mqSizes | append (replaceRE "^min-width-(.+)-px.css$" "$1" .Name) -}}
{{- end -}}
{{- range $index, $element := (after 1 (sort $mqSizes)) -}}
{{- $mqFile := resources.Get (printf "css/mq/min-width-%s-px.css" . ) | resources.ExecuteAsTemplate (printf "css/min-width-%s-px.css" .) $ | minify | fingerprint -}}
{{- $mqFilesSorted = $mqFilesSorted | append $mqFile -}}
{{- end -}}
{{- range $mqFilesSorted }}
<link rel="stylesheet" href="{{ .RelPermalink }}" media="screen and (min-width: {{ replaceRE "^css/mq/min-width-(.+)-px.css$" "$1" .Name }}px)" />
{{ end }}
{{- end -}}
{{- $tailwind := resources.Get "tailwind/tailwind.css" -}}
{{- $options := dict "inlineImports" true -}}
{{- $tailwind = $tailwind | resources.PostCSS $options -}}
{{- if eq hugo.Environment "production" -}}
{{- $tailwind = $tailwind | minify | fingerprint -}}
{{- end }}
<link href="{{ $tailwind.RelPermalink }}" rel="stylesheet" />
- Install Tailwind on Hugo | Praveen Juge — есть минимальная конфигурация шаблонов Hugo
- A mininal Hugo blogging workflow — NPM скрипты и Hugo