29
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Nuxt開発におけるTailwindcssをv1系からv2系にアップグレードして解決した課題やそのメリット

Last updated at Posted at 2021-12-01

はじめに

株式会社じげんのユウです。
現在はチームリーダー兼フロントエンドエンジニアで不動産サービススモッカの開発を担当しております。
この度アドベントカレンダー1日目を担当することになりました。どうぞよろしくお願いします。

今回はNuxtのTailwindcssのモジュール、@nuxtjs/tailwindcssをバージョンに伴い、Tailwindcssをv1系からv2系にアップグレードすることで解決した問題とバージョンアップによるメリットを紹介します。

以下に当てはまる方に向けた記事です

  1. nuxtjs/tailwindcssのv3.1以前を使ってる方。(v3.1以降を使ってるなら本記事の問題が起きないかもしれません)
  2. nuxtjs/tailwindcssの初心者でどうやってバージョンアップすれば良いのかわからない方
  3. Tailwincssのユーティリティークラスはなぜか本番環境では効かない悩みがある方。
  4. 開発環境のビルド時間を短縮したい方。

開発環境の前提

すでに以下の環境で開発している前提

  • 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>

開発環境を立ち上げて結果を確認します。

1. 開発環境ではtailwindのクラスは当たる.png

chrome dev toolからスタイルを確認してみます。

2. dev toolで当たってるクラスを確認する.png

スタイルはちゃんと当たってますね。

次にローカルでproduction buildして、再度確認してみます。

3. productionではdom要素で直に書くtailwindcssが当たらない.png

残念なことに...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点のいずれかを対応すれば解決とのことです。

  1. tailwind.config.jsファイルを srcDir に定義されてるディレクトリに入れる。
  2. 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.jsonnuxtjs/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

ちゃんとアップグレードされました。

最後はバージョンアップ後の確認

無事にバージョンアップしたところでまずはローカルでビルドして動作確認してみます。

そしたら下記みたいにたくさんエラーが出てきました…

バージョンアップ後のエラー_flex_no_wrapのエラー(投稿用).png
バージョンアップ後のエラー_whitespace_no_wrap(投稿用).png
バージョンアップ後のエラー_text-orange-500(投稿用).png

アップグレード後のエラー対応

まず最初の2件のエラーを確認すると、whitespace-no-wrapflex-no-wrap が存在しないと…公式サイトのv1 → v2に移行する説明にも書いてあった通り、いくつかのユーティリティークラス名は改名されていました。

改名されたクラス.png

なので合わせて修正すれば解消できます。

最後のエラーは 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,
    }
  }
}

これでエラーをすべて解消しました。
再度ビルド試して、完了後に結果を確認する。

8. tailwindアップデート後のproduction環境.png

念の為 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;
      }
    }
  }
}

下記画像の赤い枠は効かないところです。

入れ子の記法が効かない問題.png

dev toolで確認した結果はこれです。入れ子のスタイルは何もかも消えてしまう残念な結果に…

入れ子のCSSは全く当たらない.png

入れ子問題の解決方法

解決方法はかなり簡単で、公式のissueでも言及されてます。
Nested CSS not compiled correctly

nuxt configファイルで下記設定を追加すればいいです。

// nuxt.config.js
export default {
build: {
    postcss: {
      plugins: {
        'postcss-nested': {},
      },
    },
  },
}

これでpostcss-nestedの入れ子の書き方(sassを踏襲してる)ができるようになり、もう一度確認するとスタイルがちゃんと効くようになりました。

本番環境でも入れ子のスタイルも当たる.gif

アップグレードのメリットその1 - ビルドタイム改善

今回のビルド時間を解決するためではないのですが、公式サイトではv2のほうがビルドが早くなると聞いてバージョンアップ前後のビルドタイムを比較しました。

アップグレード前: 428秒

バージョンアップ前のローカル環境yarn build時間.png

アップグレード後: 203秒
バージョンアップ後のローカル環境yarn build時間.png

半分以上短縮できました!

アップグレードのメリットその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番いいメリットだと思います。

  • JITモードOFFのビルドタイム
    JITモードをoffの開発環境のビルトタイム.png

  • JITモードONのビルドタイム
    JITモードをonにして開発環境のビルトも早くなる(投稿用).png

最後に

いかがでしたか?正直アップグレードしかやってないのに、課題の解決もできた上にビルドタイムの短縮までできるなんて嬉しいです。
もしまだアップグレードしてないプロジェクトがあって、今回紹介した課題やビルドタイムが長すぎる悩みがあったらぜひv2にアップグレードしてみてください。

29
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?