Next.js Tailwindcss 導入編

2020年10月14日

こんにちは、Yuuichi(@WestHillWorker)です。

前回Tailwindcssでボタンを表示する部分まで実施しましたが、今回はNext.jsにTailwindcssをインストールして、ヘッダー・フッター・メインなどに分けて土台を作成していく点についてまとめました。

成果物のイメージ

導入編ということで、ヘッダー・フッター・ナビゲーション・メインのコンテンツの土台作成が中心となります。この後簡単な自己紹介ページを作成する前段階にしようと考えています。

スポンサーリンク

ベースプロジェクト作成

// お好きなプロジェクトフォルダを作成ください
$ mkdir next_tailwind_first
$ cd next_tailwind_first
$ yarn init

利用パッケージ追加

$ yarn add react react-dom next tailwindcss
// コードフォマット用にprettierを入れていますが、お好みで
$ yarn add -D postcss-preset-env prettier

postcss-preset-env:https://www.npmjs.com/package/postcss-preset-env

Prettier:https://prettier.io/

package.jsonにscriptsを追加

Nextを起動するために、scriptsを追加します。

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
// ローカル環境で起動するか試してみましょう
$ yarn dev

tailwindcssの設定ファイルを追加

tailwindcssのパッケージを追加するとnpxでtailwindcssの設定ファイルが作成できるようになります。

以下のコマンドで設定ファイルを作成します。

$ npx tailwindcss init

実行するとtailwind.config.jsが作成されます。

module.exports = {
  purge: [],
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
}

プロジェクトのデフォルトのtheme・variants・purgeをカスタマイズするために利用します。

設定ファイルに関する情報:https://tailwindcss.com/docs/configuration

tailwind.config.jsの編集

今回tailwindcss v1.8.5を利用しています。

v2.0で非推奨になるユーティリティgapなどは削除しておきます。

module.exports = {
  future: {
    removeDeprecatedGapUtilities: true,
    purgeLayersByDefault: true
  },
  purge: {
    layers: ['utilities'],
    content: [
      './components/**/*.{js,ts,jsx,tsx}',
      './pages/**/*.{js,ts,jsx,tsx}'
    ]
  },
  theme: {
    extend: {}
  },
  variants: {},
  plugins: []
}

tailwindcssのファイルサイズは大きいため、purgeのcontentにtailwwindcssを使う予定のファイルパスを設定します。

これにより利用していないスタイルを削減することができるようです。

NODE_ENVを本番環境に設定してCSSをコンパイルすると、TailwindはCSSから未使用のスタイルを自動的に削除してくれるとのことです。

もし他のファイルパスでもtailwindcssを利用する場合、contentに追記が必要です。

https://tailwindcss.com/docs/upcoming-changes#purge-layers-by-default

https://tailwindcss.com/docs/upcoming-changes#remove-deprecated-gap-utilities

postcss.config.jsの作成

$ touch postcss.config.js
module.exports = {
  plugins: ['tailwindcss', 'postcss-preset-env']
}

tailwindcssと最新のcssを各種ブラウザで利用可能にするためにpostcss-preset-envを追加します。

各種フォルダ・ファイル作成

Next.js用のpagesフォルダ・pulblicやReactのコンポーネント・スタイルを格納するためのフォルダを作成します。

$ mkdir pages components public styles

Next.jsでルートにアクセスした際に必要なファイルを用意しておく。

$ touch pages/index.jsx pages/_app.jsx pages/_document.jsx

cssファイル作成

$ touch styles/index.css
/* purgecss start ignore */
@tailwind base;
@tailwind components;
/* purgecss end ignore */
/* my custom css start */
/* my custom css end */
@tailwind utilities;

自前のstyleを記述したい場合は、componentsとutilitiesの間に記述。

compontensファイル作成

pages配下で共通して利用できるようにヘッダー・フッター・レイアウト用のjsxファイルを用意します。

$ touch components/Header.jsx components/Footer.jsx components/Layout.jsx

ページを作成していきましょう

必要となるフォルダ・ファイルの配置が完了しました。

ここからはpagesからファイルを編集していきます。

ページの共通部分の作成

_app.jsxでスタイルシートを読み込みます。

import React from 'react'
import App from 'next/app'
// 作成したスタイルを読み込みましょう
import '../styles/index.css'
class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props
    return <Component {...pageProps} />
  }
}
export default MyApp

ページでスタイルが使えるようになりました。

_document.jsxの作成

import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }
  render() {
    return (
      <Html lang="ja">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}
export default MyDocument

なくても大丈夫なのですが、あとでDOMのベース構成をカスタマイズするかもしれないので、今回は作成しました。

index.jsxの作成

ルートアクセスでLayout・サンプルで表示するHellow Next.js を記述します。

import Head from 'next/head'
import Layout from '../components/Layout'
const Index = () => (
  <Layout>
    <Head>
      <title>MyProfile</title>
    </Head>
    <div className="text-center text-teal-700">Hellow Next.js</div>
  </Layout>
)
export default Index

ここまででpages配下の作成は、完了しました!

複数ページで共有して利用するための、Layoutを作成していきましょう。

componentsの作成

pagesで共通で利用するLayoutコンポーネントにHeader ・Footerのコンポーネントを作成します。

Headerのコンポーネント

共通のナビゲーションなどを追記します。

まだpages/index.jsxのみなので、Homeだけを用意しました。

import Link from 'next/link'
const Header = () => (
  <header>
    <nav className="flex items-center justify-between flex-wrap bg-teal-500 p-6">
      <div className="flex items-center flex-shrink-0 text-white mr-6">
        <span className="font-semibold text-xl tracking-tight">My Profile</span>
      </div>
      <div className="w-full block flex-grow lg:flex lg:items-center lg:w-auto">
        <div className="text-sm lg:flex-grow">
          <Link href="/">
            <a className="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-white mr-4">
              Home
            </a>
          </Link>
        </div>
      </div>
    </nav>
  </header>
)
export default Header

tailwindcssナビゲーションに関しては、こちらのもサンプルがありますので他にも試してみても良いかと思います。

ナビゲーションのサンプル:https://tailwindcss.com/components/navigation

Footerのコンポーネント

ひとまずコピーライトだけFooterに記述しました。

const Footer = () => (
  <footer>
    <p className="text-center">© 2020 sample </p>
  </footer>
)
export default Footer

Layoutのコンポーネント

Header ・ Footerはページでは共通にしたいため、Layoutに読み込ませます。

import Head from 'next/head'
import Header from '../components/Header'
import Footer from '../components/Footer'
const Layout = ({ children }) => (
  <>
    <Head>
      <link rel="icon" href="/favicon.ico" />
      <meta name="viewport" content="initial-scale=1.0, width=device-width" />
    </Head>
    <Header />
    <main role="main">{children}</main>
    <Footer />
  </>
)
export default Layout

メインのコンテンツは、pages/index.jsxでLayoutで囲った中身がchildrenとしてレンダリングされます。

// mainタグのchildren
<main role="main">{children}</main>

ここまでで、pages・components・stylesの設定完了しました。

プロジェクトを起動

土台に必要となるフォルダ・ファイルの配置が完了しましたのでNextを起動してみましょう!

$ yarn dev

ブラウザでhttp://localhost:3000で確認できたらOKです!

http://localhost:3000

その他

今回作成したリポジトリを以下となります。(ご参考までに)

https://github.com/yuugure/next_tailwind_first

.vscode・.prettierrcなど利用したい方

まとめ

最近Next.jsを触る機会が増えたため、前回学習したtailwindcssを導入してみました。

今回は、Hellow Next.jsまで表示するための土台部分まで作成したので、次回はメインのコンテンツを作成して、自己紹介ページのようなものを作成しようと思います。

ありがとうございました!!

自己紹介ページのサンプルページを作成致しました。

興味が湧いた方がいましたら、チェックいただければと思います。