はじめに
株式会社じげんのユウです。
現在はチームリーダー兼フロントエンドエンジニアで不動産サービススモッカの開発を担当しております。
この度アドベントカレンダー1日目を担当することになりました。どうぞよろしくお願いします。
今回はNuxtのTailwindcssのモジュール、@nuxtjs/tailwindcssをバージョンに伴い、Tailwindcssをv1系からv2系にアップグレードすることで解決した問題とバージョンアップによるメリットを紹介します。
以下に当てはまる方に向けた記事です
- nuxtjs/tailwindcssのv3.1以前を使ってる方。(v3.1以降を使ってるなら本記事の問題が起きないかもしれません)
- nuxtjs/tailwindcssの初心者でどうやってバージョンアップすれば良いのかわからない方
- Tailwincssのユーティリティークラスはなぜか本番環境では効かない悩みがある方。
- 開発環境のビルド時間を短縮したい方。
開発環境の前提
すでに以下の環境で開発している前提
- nuxt v2.15以上
- nuxtjs/tailwindcss v3.1以下
- nuxt.config.jsには
srcDir
が設定されてる
もしnuxtjs/tailwindcssを使ったことない方なら、公式のガイド通りインストールすれば今回紹介する問題は起きないはずです。
どういう問題が起きてるのか?
DOM要素のclassにtailindcssのクラスをそのまま書くと、開発環境ではスタイルが当たるのですが、本番環境ではスタイルが当たらないです。
まず問題を再現してみます。下記のコードはpタグにTailwindcssのユーティリティークラスをそのまま書いてます。
<template>
<div>
<p class="text-xl text-red-600 p-10 m-10 font-bold">テスト用の文字列</p>
<div>
<template>
開発環境を立ち上げて結果を確認します。
chrome dev toolからスタイルを確認してみます。
スタイルはちゃんと当たってますね。
次にローカルでproduction buildして、再度確認してみます。
残念なことに...Tailwindcssのスタイルは当たらなかったです。
ではこの問題を解決しましょう!
原因&解決方法を調査
これを解決するために色々と調べました。本番環境でTailwindcssが当たらない事例はいくつもの記事はありますが、どのケースも微妙に違うので、結局nuxt/tailwindの公式githubでissueを探すことに。
githubでissueを漁ることが割と大事なのでネット記事でググっても解決策を見つからなかったら腹を括って公式githubにダイブしましょう
同じ事例のIssueが見つかりました!
Some styles are not applied in production mode with "srcDir" nuxt.config.js option.
issueのタイトルはまさに現状環境の設定と同じでした。nuxt configファイルには srcDirを定義していて、nuxtのファイルを置くディレクトリを設定するプロパティです。
それが設定されると、本番ではsrcDirの値をうまく取れず、TailwindcssのPurge機能(ソースコード上に使われてるクラスを判断して、該当クラスだけ注入するプロセス)がうまく行われないから今回の問題を起きるわけです。
解決方法に関しては簡単です、公式ではすでにこのissueを修正してリリースしているので
nuxt/tailwindcssをバージョンアップするだけで解決できます。
公式の修正PR:
tailwindcss-module: feat(purge): handle custom srcDir and support TS
公式のリリースノート: 上記のPRはv3.1にてリリースされてることを確認できます。
Release Note
公式コメントからの注意点としては、バージョンアップ後に下記の2点のいずれかを対応すれば解決とのことです。
-
tailwind.config.js
ファイルをsrcDir
に定義されてるディレクトリに入れる。 -
nuxt.config.js
ファイルに configPath: '~~/tailwind.config.js' を設定する必要があります。下記みたいに。
// nuxt.config.js
export default {
tailwindcss: {
configPath: '~/config/tailwind.js'
}
}
今回はもともとtailwind.config.js
はすでに srcDir
に定義されてるディレクトリに入れてるので、2の設定を追加しなくて解決できました。
ではアップグレードの手順から行きましょう。
いざ、アップグレード
まず現状のバージョンを確認する
バージョンを確認する方法はふたつあります
- 方法1.yarnコマンドで確認する
yarn list --pattern @nuxtjs/tailwindcss
これを叩けばこんな感じに現在インストールされているバージョンが表示されます。
yarn list v1.22.5
└─ @nuxtjs/tailwindcss@2.1.x
- 方法2. package.jsonの
devDependencies
を確認
// package.json
"devDependencies": {
"@nuxtjs/tailwindcss": "^2.1.x",
}
上記の方法でnuxt/tailwindcssのバージョンを確認できましたが、このバージョンはTailwindcssのどのバージョンに依存してるのかを確認したい場合は yarn.lock
ファイルの dependencies
を確認すればわかります。
// yarn.lock
"@nuxtjs/tailwindcss@^2.1.0":
version "2.1.x"
resolved "https://registry.yarnpkg.com/@nuxtjs/tailwindcss/-/tailwindcss-2.1.1.tgz#7120a269b5a43d4a9d60947f7f734458cf86c180"
integrity sha512-9DC7Adds1AKvxMbfW0Jd2EPpDUh3pVVE4wwiuJ45CiwOcz9EIU3Lc02h+bjnb1QFf07ZxJVO2xkN00IwQEFp8w==
dependencies:
consola "^2.14.x"
fs-extra "^9.0.x"
tailwindcss "^1.6.x"
dependencies
のところは tailwindcss
の1.6系に依存してますね。(記事上ではマイナーバージョンを隠しております)
次はアップグレードする
バージョンアップする前にまず確認してほしいのはnuxtのバージョンです。
公式サイトにも書いた通りnuxtは最低でも2.15.3以上じゃないとだめらしいので、それ以下の場合はアップグレードしましょう。
ではアップグレードしていきます。
まずpackage.json
のnuxtjs/tailwindcss
のバージョンを変更。
今回は4.2系にしてます。
// package.json
"devDependencies": {
"@nuxtjs/tailwindcss": "^4.2.0",
}
あとは下記コマンドを叩けばアップグレードできます。
yarn upgrade @nuxtjs/tailwindcss
終わった後に再度下記コマンドでバージョン確認
yarn list --pattern @nuxtjs/tailwindcss
yarn list v1.22.5
└─ @nuxtjs/tailwindcss@4.2.x
ちゃんとアップグレードされました。
最後はバージョンアップ後の確認
無事にバージョンアップしたところでまずはローカルでビルドして動作確認してみます。
そしたら下記みたいにたくさんエラーが出てきました…
アップグレード後のエラー対応
まず最初の2件のエラーを確認すると、whitespace-no-wrap
と flex-no-wrap
が存在しないと…公式サイトのv1 → v2に移行する説明にも書いてあった通り、いくつかのユーティリティークラス名は改名されていました。
なので合わせて修正すれば解消できます。
最後のエラーは text-orange-500
は存在しないエラーですが、これはTailwindcssのv1ではあったカラークラスですが、v2ではorangeはデフォルトカラーから外されたので、tailwind configファイルにカスタマイズカラーとして設定する必要はあります。
v1と同じユーティリティークラスを使いたかったら下記みたいに適宜に設定すれば使えます。
// tailwind.config.js
const colors = require('tailwindcss/colors')
module.exports = {
theme: {
colors: {
// Build your palette here
transparent: 'transparent',
current: 'currentColor',
// orange色を追加する
orange: colors.orange,
}
}
}
これでエラーをすべて解消しました。
再度ビルド試して、完了後に結果を確認する。
念の為 NODE_ENV
も画面上に出力してみました。production環境でもちゃんとスタイルが当たってることを確認できました👍
ついでに解決したい課題: CSSクラスを入れ子の記法で書いたらうまくCSS化されない問題。
これはtailwindのバージョンとか関係なく、nuxt/tailwindcssの初期の設定では下記コードのスタイルクラスはうまくCSS化できなかったです。
<template>
<div>
<p class="text-xl text-red-600 p-10 m-10 font-bold">テスト用の文字列</p>
<div class="wrapper">
<p class="wrapper-text">テスト用の文字列</p>
<p>テスト用の文字列</p>
<a :href="`https://google.com/`">テスト用のリンク</a>
<div class="innter">
<p class="text-xl text-red-600 p-10 m-10 font-bold">テスト用の文字列</p>
<p class="text-xl text-red-600 p-10 m-10 font-bold">テスト用の文字列</p>
<p class="text-xl text-red-600 p-10 m-10 font-bold">テスト用の文字列</p>
<a :href="`https://google.com/`">テスト用のリンク</a>
</div>
</div>
</div>
</template>
<style lang="postcss" scoped>
.wrapper {
@apply w-full bg-gray-500;
.wrapper-text {
@apply text-green-300 text-2xl p-10 font-bold;
}
p {
@apply text-5xl;
}
a {
@apply inline-block border border-base-gray text-secondary p-8px bg-white m-md;
&:hover {
@apply bg-yellow;
}
}
.innter {
a {
&:hover {
@apply bg-orange-base;
}
}
}
}
.innter {
@apply w-1/2 m-auto bg-red-200;
}
</style>
効かないスタイルを説明します。主に入れ子のスタイルが効かなくなります。
.wrapper {
// wrapper-textは効かない
.wrapper-text {
@apply text-green-300 text-2xl p-10 font-bold;
}
// aタグのスタイルもhover時のスタイルも効かない
a {
@apply inline-block border border-base-gray text-secondary p-8px bg-white m-md;
&:hover {
@apply bg-yellow;
}
}
.innter {
// aタグのhover時スタイルは効かない
a {
&:hover {
@apply bg-orange-base;
}
}
}
}
下記画像の赤い枠は効かないところです。
dev toolで確認した結果はこれです。入れ子のスタイルは何もかも消えてしまう残念な結果に…
入れ子問題の解決方法
解決方法はかなり簡単で、公式のissueでも言及されてます。
Nested CSS not compiled correctly
nuxt configファイルで下記設定を追加すればいいです。
// nuxt.config.js
export default {
build: {
postcss: {
plugins: {
'postcss-nested': {},
},
},
},
}
これでpostcss-nestedの入れ子の書き方(sassを踏襲してる)ができるようになり、もう一度確認するとスタイルがちゃんと効くようになりました。
アップグレードのメリットその1 - ビルドタイム改善
今回のビルド時間を解決するためではないのですが、公式サイトではv2のほうがビルドが早くなると聞いてバージョンアップ前後のビルドタイムを比較しました。
アップグレード前: 428秒
半分以上短縮できました!
アップグレードのメリットその2 - JIT(Just-In-Time)モードで開発環境のビルドタイムを短縮
Tailwindcss v2では新たにJITモードを搭載しました。
JITモードを使うと色んなメリットはありますが、ここでは説明を割愛します。気になる方は公式サイトを見てください。
tailwind configファイルで下記設定を追加するとJITモードを使えます。
// tailwind.config.js
module.exports = {
mode: 'jit',
purge: [
`~/components/**/*.{vue,js}`,
`~/layouts/**/*.vue`,
`~/pages/**/*.vue`,
`~/plugins/**/*.{js,ts}`,
`~~/nuxt.config.{js,ts}`
]
}
JITモードはまだpreview
段階で本番環境では使わないようにしてますが、開発環境でのビルドタイムがさらに短縮ができるのが1番いいメリットだと思います。
最後に
いかがでしたか?正直アップグレードしかやってないのに、課題の解決もできた上にビルドタイムの短縮までできるなんて嬉しいです。
もしまだアップグレードしてないプロジェクトがあって、今回紹介した課題やビルドタイムが長すぎる悩みがあったらぜひv2にアップグレードしてみてください。