Fusic Tech Blog

Fusicエンジニアによる技術ブログ

Tailwind CSS (Vue3 + Vite)の環境構築とか、使ってみた感想
2024/02/19

Tailwind CSS (Vue3 + Vite)の環境構築とか、使ってみた感想

おそらく、タイトル通りの構築をちょこちょこやってる人もいるかと思います。

Tailwind CSSに関して言えば、去年くらいから気にはなりつつも、一度も触ったことがありませんでした。

今回、触ってみる機会が訪れたのでその感想とか調べたことを書いてみます。

導入

Install Tailwind CSS with Vue 3 and Vite - Tailwind CSSを元に、npm init @vitejs/app <project名>から簡単に導入することができます。 今回は以下の構成で行いました。

 npm init @vitejs/app app       
Need to install the following packages:
  @vitejs/create-app
Ok to proceed? (y) y
 Select a framework: vue
 Select a variant: vue-ts

Scaffolding project in /path/to/vite-vue3-tailwindcss/app...

Done. Now run:

  cd app
  npm install
  npm run dev

そのまま、「Setting up Tailwind CSS」と「Include Tailwind in your CSS」まで進めると、使えるようになっているかと思います。

起動時、hostやportを指定したい場合、package.jsonのdevの部分で--port--hostオブションが準備されています。


{
  "version": "0.0.0",
  "scripts": {
    "dev": "vite --host 0.0.0.0 --port 3000",
    "build": "vue-tsc --noEmit && vite build",
    "serve": "vite preview"
  },
  ...
}

Viteでaliasの設定

公式のとおりにやると、どうもimport file from /@/path/to/fileとやらなきゃいけないようです。

けどこの書き方が嫌だったので、webpackでやっていた@/components/Hoge.vueのようにaliasを設定したい。

その場合、vite.config.jsで以下の設定をすれば、利用できます。(ちょっとめんどくさい)


import path from "path";

const aliasRegx = /^@\//;

const resolver = {
  alias(id) {
    if (id.match(aliasRegx)) {
      return path.resolve("/src", id.replace(aliasRegx, ""));
    }
  },
};

module.exports = {
  resolvers: [resolver],
};

Vueでの利用

VueでTailwind CSSを利用する時は、コンポネントごとにクラスを集約して、画面を構成していくことになります。

.
├── App.vue
├── components
   └── Button.vue
├── main.ts
├── views
   └── Page.vue

<!-- components/Button.vue -->

<template>
  <button class="inline-block p-3 ..." @click="clicked">
    ボタン
  </button>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  props: {
    clicked: {
      type: Function,
      default: {}
    }
  }
</script> 
<!-- views/Page.vue -->

<template>
  <div class="flex">
    <div class="relative w-full">
      <Button :clicked="clicked" />
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import Button from "@/components/Button.vue"

export default defineComponent({
  components: {
    Button,
  },
  setup() {
    const clicked = () => alert("click!")

    return {
      clicked
    }
  },
})
</script>

Tailwindでは、cssの影響範囲を極めて小さく収めることができます。

従来のやり方だと、cssの名前つけに苦労したり、影響範囲を考えたりと少し気を使うところがあったかと思いますが、気にしなくて良いのがいいですね。

コンセプト

これまでは、利用したいCSSフレームワークに追加でカスタマイズして、画面を作成していく形だったと思います。

しかし、Tailwind CSSでは最小単位のクラスをかき集め、一つのコンポネントとして管理していきます。

例:

  • 従来
<template>
  <a class="btn" href="https://example.com">
    click
  </a>
</template>

<style scoped>
.btn {
  display: inline-block;
  padding: 0.5em 1em;
  background: #63B3ED;
  color: #FFF;
  border-bottom: solid 4px #BEE3F8;
  border-radius: 3px;
  cursor: pointer;
}
.btn:active {
  transform: translateY(4px);
  border-bottom: none;
}
</style>

  • Tailwind CSS
<template>
  <a class="inline-block px-2 py-4 text-white bg-blue-400 border-b-4 border-blue-200 rounded-md cursor-pointer active:translate-y-4 active:border-0"
     href="https://example.com">
    Click
  </a>
</template>

小さなクラスを一つ一つ指定していき、コンポネントを構成していきます。

こう言った実装に対して、Tailwindでは以下の利点が上げられています。

  • ヘンテコなクラス名を考えることに時間を使わなくても良くなること
  • CSSファイルの記述量が格段におちること
  • グローバルな空間を汚染するわけではないので、安全な変更ができるようになること

これを導入したあと、CSSの記載はほとんどなくなりました。

とはいえ、Vueを使うときは、cssがコンポーネント単位で独立するように書いたりするので、あまりグローバルに影響するってことは考えなかったとは思いますが。。。

それでも、設計思想が生まれるくらいには、考えることがあってめんどくさかったりします。

その辺り、「CSSを書かない縛り」を通せば、めんどくさいこと抜きにして開発をすすめることができて、ストレスフリーですね。

一方、よくあることとして、インラインスタイルでもいいんじゃないかという疑問があるようですが、以下のように回答されています。

インラインスタイルでは

  • マジックナンバーになってしまう
  • メディアクエリを利用できない
  • 擬似クラスを指定できない

例えば、Tailwindではmd:class-nameforcus:class-nameというような形式でレスポンシブや、フォーカスなどを定義できます。

感想

と、ここまで色々と利点ばかり上げましたが、全てがいいとも実は思ってなかったりもしています。

たとえば、管理画面にTailwindを導入する場合、ボタンやテキストフォーム、アラートのようなよくあるものを組み合わせて構築するようなものにはまだ少し、面倒だなあと思うこともありました。

adminテンプレートもあったりしますが、十分に揃っているとは言い難いですし。。。

GitHub - tailwindcomponents/dashboard: 🛩 🧶 Dashboard template built with Tailwind CSS.

なので、結局TailwindUIやTailwindComponentsから検索して、構築したりっていうことをやっていかないと行かないと思います。

一方で、ECサイトなど、要件に対して固有のコンポーネントを1から構築していくものについては、とても使いやすいんじゃないかなあというのが所感です。

まだ、使ったことない人は、Tailwind Playで試せるので、是非。

Tsukamoto Makoto

Tsukamoto Makoto

Company: Fusic CO., LTD. お仕事はRuby 趣味ではJulia jl.devというJuliaのユーザーグループの管理人しています。Juliaが好きな方は是非に〜