📖

Vite + Vue 3 + TypeScript + Tailwind CSS の簡易環境構築

2021/10/16に公開

Vite + Vue 3 + TypeScript + Tailwind CSS を用いた環境構築をメモしたく、本記事を作成しました。
それぞれの公式ページを見れば分かることではあるのですが、まとまったものをメモした方が、ちょっとしたプロジェクトの準備をする際に便利ですよね。
なお、本記事では yarn を用いてパッケージ管理する前提で進めますので、 npm などを用いる場合は適宜読み替えてください。

本記事で扱う内容

  • Vite + Vue 3 + TypeScript + Tailwind CSS を用いるプロジェクトの簡易的な環境構築

本記事で扱わない内容

  • Linter やテストツールの導入など

環境構築後のプロジェクトディレクトリ構成

my-app
├── node_modules
│   └── ...
├── README.md
├── index.html
├── package.json
├── postcss.config.js
├── public
│   └── favicon.ico
├── src
│   ├── App.vue
│   ├── assets
│   │   └── logo.png
│   ├── components
│   │   └── HelloWorld.vue
│   ├── env.d.ts
│   ├── index.css
│   └── main.ts
├── tailwind.config.js
├── tsconfig.json
├── vite.config.ts
└── yarn.lock

バージョン

筆者による動作確認時の各ツール・パッケージのバージョンを記載します。

name version
yarn 1.22.10
npx 6.14.8
vue 3.2.20
@vitejs/plugin-vue 1.9.3
autoprefixer 10.3.7
postcss 8.3.9
tailwindcss 2.2.17
typescript 4.4.4
vite 2.6.7
vue-tsc 0.3.0

環境構築手順

Vite を用いた Vue 3 + TypeScript プロジェクトのベースの作成

まず、 Vite を用いて Vue 3 + TypeScript のプロジェクトのベースを作成するため、下記コマンドを実行します。

$ yarn create vite my-app --template vue-ts

my-app は、任意の名前です。
--template vue-ts の指定により、 Vue 3 + TypeScript プロジェクトのベースを作成することができます。
他のテンプレート (React & TypeScript など) を利用することも可能ですので、適時 公式の GitHub リポジトリ をご確認ください。
このコマンドにより、 my-app/ ディレクトリ内に package.jsontsconfig.json などを含む Vue & TypeScript のプロジェクトのベースが作成されました。

ここで yarn dev コマンドを実行することにより、 localhost:3000 にサーバーが起動します。
ブラウザで開くと "Hello Vue 3 + TypeScript + Vite" などと表示されるかと思います。
ちなみに、ここで表示されるページに記載されている通り、 VSCode を用いる場合は Volar という拡張機能を活用することをお勧めします。

Tailwind CSS の導入

my-app/ ディテクトリに移動し、下記コマンドにより Tailwind CSS を利用するために必要なパッケージをインストールします。

my-app/$ yarn add --dev tailwindcss@latest postcss@latest autoprefixer@latest

この後、 Tailwind CSS を用いるための設定ファイルを (tailwind.config.js, postcss.config.js) を生成するため、下記コマンドを実行します。

my-app/$ npx tailwindcss init -p

以降、各設定ファイルを変更・追加していきます。

tailwind.config.js の purge オプションを下記のように変更します。また、適用するクラスによってはその他のオプション(variants オプションなど)も変更する必要がある場合があります。その場合は こちら などをご参照ください。

my-app/tailwind.config.js
  module.exports = {
-   purge: [],
+   purge: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
    darkMode: false, // or 'media' or 'class'
    theme: {
      extend: {},
    },
    variants: {
      extend: {},
    },
    plugins: [],
  }

my-app/src/index.css を下記内容で作成します。

my-app/src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;

上記設定ファイルを my-app/src/main.ts で import するために、下記のように追記します。

my-app/src/main.ts
  import { createApp } from 'vue'
  import App from './App.vue'
+ import './index.css'

  createApp(App).mount('#app')

以上で、Vite + Vue 3 + TypeScript + Tailwind CSS を用いるプロジェクトの簡易的な環境構築が完了しました。

動作確認

おまけの内容になりますが、動作確認のため、下記のようにファイルを作成・変更しました。
my-app/src/components/TopSection.vuetemplate タグ内は、 Tailwind UI のこちらのページ とほぼ同じですが、一部のテキストを props として渡すために {{ msg }} と変更しています。

my-app/src/components/TopSection.vue
<script setup lang="ts">
defineProps<{ msg: string }>()
</script>

<template>
<div class="relative bg-white overflow-hidden">
  <div class="max-w-7xl mx-auto">
    <div class="relative z-10 pb-8 bg-white sm:pb-16 md:pb-20 lg:max-w-2xl lg:w-full lg:pb-28 xl:pb-32">
      <svg class="hidden lg:block absolute right-0 inset-y-0 h-full w-48 text-white transform translate-x-1/2" fill="currentColor" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
        <polygon points="50,0 100,0 50,100 0,100" />
      </svg>

      <div>
        <div class="relative pt-6 px-4 sm:px-6 lg:px-8">
          <nav class="relative flex items-center justify-between sm:h-10 lg:justify-start" aria-label="Global">
            <div class="flex items-center flex-grow flex-shrink-0 lg:flex-grow-0">
              <div class="flex items-center justify-between w-full md:w-auto">
                <a href="#">
                  <span class="sr-only">Workflow</span>
                  <img class="h-8 w-auto sm:h-10" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg">
                </a>
                <div class="-mr-2 flex items-center md:hidden">
                  <button type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" aria-expanded="false">
                    <span class="sr-only">Open main menu</span>
                    <!-- Heroicon name: outline/menu -->
                    <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
                    </svg>
                  </button>
                </div>
              </div>
            </div>
            <div class="hidden md:block md:ml-10 md:pr-4 md:space-x-8">
              <a href="#" class="font-medium text-gray-500 hover:text-gray-900">Product</a>

              <a href="#" class="font-medium text-gray-500 hover:text-gray-900">Features</a>

              <a href="#" class="font-medium text-gray-500 hover:text-gray-900">Marketplace</a>

              <a href="#" class="font-medium text-gray-500 hover:text-gray-900">Company</a>

              <a href="#" class="font-medium text-indigo-600 hover:text-indigo-500">Log in</a>
            </div>
          </nav>
        </div>

        <div class="absolute z-10 top-0 inset-x-0 p-2 transition transform origin-top-right md:hidden">
          <div class="rounded-lg shadow-md bg-white ring-1 ring-black ring-opacity-5 overflow-hidden">
            <div class="px-5 pt-4 flex items-center justify-between">
              <div>
                <img class="h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="">
              </div>
              <div class="-mr-2">
                <button type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
                  <span class="sr-only">Close main menu</span>
                  <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                  </svg>
                </button>
              </div>
            </div>
            <div class="px-2 pt-2 pb-3 space-y-1">
              <a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50">Product</a>

              <a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50">Features</a>

              <a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50">Marketplace</a>

              <a href="#" class="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50">Company</a>
            </div>
            <a href="#" class="block w-full px-5 py-3 text-center font-medium text-indigo-600 bg-gray-50 hover:bg-gray-100">
              Log in
            </a>
          </div>
        </div>
      </div>

      <main class="mt-10 mx-auto max-w-7xl px-4 sm:mt-12 sm:px-6 md:mt-16 lg:mt-20 lg:px-8 xl:mt-28">
        <div class="sm:text-center lg:text-left">
          <h1 class="text-4xl tracking-tight font-extrabold text-gray-900 sm:text-5xl md:text-6xl">
            <span class="block xl:inline">{{ msg }}</span>
            <span class="block text-indigo-600 xl:inline">online business</span>
          </h1>
          <p class="mt-3 text-base text-gray-500 sm:mt-5 sm:text-lg sm:max-w-xl sm:mx-auto md:mt-5 md:text-xl lg:mx-0">
            Anim aute id magna aliqua ad ad non deserunt sunt. Qui irure qui lorem cupidatat commodo. Elit sunt amet fugiat veniam occaecat fugiat aliqua.
          </p>
          <div class="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-start">
            <div class="rounded-md shadow">
              <a href="#" class="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 md:py-4 md:text-lg md:px-10">
                Get started
              </a>
            </div>
            <div class="mt-3 sm:mt-0 sm:ml-3">
              <a href="#" class="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-indigo-700 bg-indigo-100 hover:bg-indigo-200 md:py-4 md:text-lg md:px-10">
                Live demo
              </a>
            </div>
          </div>
        </div>
      </main>
    </div>
  </div>
  <div class="lg:absolute lg:inset-y-0 lg:right-0 lg:w-1/2">
    <img class="h-56 w-full object-cover sm:h-72 md:h-96 lg:w-full lg:h-full" src="https://images.unsplash.com/photo-1551434678-e076c223a692?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80" alt="">
  </div>
</div>
</template>
my-app/src/App.vue
<script setup lang="ts">
import TopSection from './components/TopSection.vue'
</script>

<template>
  <TopSection msg="Custom Message!!!" />
</template>

上記を反映した後、 localhost:3000 にて下記のように表示されていたら、動作は問題なしです。

まとめ

Vite + Vue 3 + TypeScript + Tailwind CSS の簡易環境構築をする場合は、下記コマンドを実行し、その他下記ファイルを編集・追加する。

  • 実行するコマンド
    • yarn create vite my-app --template vue-ts
    • cd my-app
    • yarn add --dev tailwindcss@latest postcss@latest autoprefixer@latest
    • npx tailwindcss init -p
  • その他編集・追加するファイル
    • my-app/tailwind.config.js
    • my-app/src/index.css
    • my-app/src/main.ts

以上です。閲覧ありがとうございました!

参考

Discussion