【2021年6月版】コピペだけでNext.js＋TypeScript＋Material-ui＋Tailwindcssの環境構築を行う

皆さんこんにちは！

最近ジメジメしてあまり気分が乗りません。

梅雨は人生で3番目くらいに嫌いです。

そんなことで最近学習し始めたNext.jsとTypeScriptですが、これからかなり流行るのではないかと感じました。

Next.jsなしではReactの環境構築を行いたくありませんし、TypeScriptが無ければコードが書けない体になっていしました。

また、最近インターンの募集で必須スキルにReactやTypeScriptなどが記載しているのを多く見かけます。

前置きはさておき、今回はNext.jsで環境構築を行う手順をご紹介します。

それぞれの用途(TypeScript、Material-ui、Tailwindcss)に分けて書いていくので、ご自分の好きな環境構築をお選びください。

# 注意事項

環境構築において特に説明は致しません。

コマンドやソースコードを書くだけなので、なにか気になる点があればご自分でお調べください。

それでは早速説明していきます！

# TypeScript付きのNext.jsプロジェクトの作成

```bash
# npxの場合
npx create-next-app next-app --example with-typescript
# yarnの場合
yarn create next-app next-app --example with-typescript
```

``material-ui``や``tailwindcss``を使用しないという方はここで終了です。

# material-uiの導入

```bash
npm i @material-ui/core @material-ui/icons @material-ui/styles @material-ui/lab
yarn add @material-ui/core @material-ui/icons @material-ui/styles @material-ui/styles
```

インストールし終えたら、以下の表をもとにファイルの作成を行って下さい。

ディレクトリ|ファイル名
---|---
components|Theme.ts
pages|_app.tsx
pages|_document.tsx

作成したそれぞれのファイルに以下をコピペ。

```Theme.ts
import { createTheme } from '@material-ui/core';
const Theme = createTheme();
export default Theme;
```

```_app.tsx
import React, { useEffect } from 'react';
import { AppProps } from 'next/app';
import { ThemeProvider } from '@material-ui/core/styles';
import { StylesProvider } from '@material-ui/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import Theme from '../components/Theme';


const CustomApp = ({ Component, pageProps }: AppProps): JSX.Element => {
  useEffect(() => {
    const jssStyles: Element | null = document.querySelector('#jss-server-side');
    if (jssStyles) {
      jssStyles.parentElement?.removeChild(jssStyles);
    }
  }, []);

  return (
    <StylesProvider injectFirst>
      <ThemeProvider theme={Theme}>
          <CssBaseline />
          <Component {...pageProps} />
      </ThemeProvider>
    </StylesProvider>
  );
};

export default CustomApp;
```

```_document.tsx
import Document, { DocumentContext, Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/core/styles';

class MyDocument extends Document {
  render(): JSX.Element {
    return (
      <Html lang='ja'>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

MyDocument.getInitialProps = async (ctx: DocumentContext) => {
  const sheets = new ServerStyleSheets();
  const originalRenderPage = ctx.renderPage;


  ctx.renderPage = () => originalRenderPage({
    enhanceApp: (App) => (props) => sheets.collect(<App {...props} />)
  });

  const initialProps = await Document.getInitialProps(ctx);
  
  return {
    ...initialProps,
    styles: (
      <>
        {initialProps.styles}
        {sheets.getStyleElement()}
      </>
    ),
  };
};
```

これで``material-ui``を使用することができます。

Tailwindcssを使用しない方はこれで終了となります。

# Tailwindcssの導入

```bash
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
```

※ エラーが出てインストールできない場合は、**1つずつ**インストールしてください

Tailwindの設定ファイルを作成

```
npx tailwindcss init -p
```

すると、``tailwind.config.js``と``postcss.config.js``が自動で作成されます。

``tailwind.config.js``で``purge``を以下に変更。

```tailwind.config.js
purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
```

``purge``というのは``purgecss``というものを使って、使わないCSSをビルド時に自動的に消去してくれます。特に、Tailwindcssのファイルは重いので、これを設定しないとビルド時にCSSファイルだけでもMBを超える要領になってしまいます。

なので、必ず設定しましょう！

そしたら以下の表をもとにファイルを作成。

ディレクトリ|ファイル名
---|---
styles|global.css

``global.css``に以下をコピペ

```global.css
/* ./styles/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

h1 {
    font-size: 48px;
    line-height: 1;
}
h2 {
    font-size: 36px;
    line-height: 1.333;
}
h3 {
    font-size: 24px;
    line-height: 1;
}
h4, h5, h6 {
    font-size: 16px;
    line-height: 1.5;
}
```

Tailwindを導入すると、h1タグなどのフォントがリセットされてしまうためh1などのCSSも追加してください。

先ほど作成した``pages/_app.tsx``に作成したCSSファイルを読み込んでください。

```_app.tsx
import "../styles/global.css";
```

これでTailwindを使用することができます。

# 番外編

Tailwindcssの設定方法がいまいち分からないという方は、以下のコードをもとに作成した見てください。

```tailwind.config.js
const colors = require("tailwindcss/colors.js");

module.exports = {
  mode: "jit",
  purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
  darkMode: false, // or 'media' or 'class'
  preserveHtmlElements: false,
  important: true,
  options: {
    defaultExtractor: (content) => {
      const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, "")
      return contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) || []
    },
    whitelist: [
      /-(leave|enter|appear)(|-(to|from|active))$/,
      /^(?!cursor-move).+-move$/,
      /^router-link(|-exact)-active$/
    ]
  },
  theme: {
    screens: {
      sm: { max: "560px" },
      md: { max: "769px" },
      tb: { max: "960px" }
    },
    colors: {
      black: colors.black,
      current: "currentColor",
      gray: colors.gray,
      green: colors.green,
      google: "#c6594b",
      indigo: colors.indigo,
      main: "#1976d2",
      pink: colors.pink,
      transparent: "transparent",
      red: colors.rose,
      white: colors.white,
      yellow: colors.yellow,
      link: "#0366d6"
    },
    extend: {}
  },
  variants: {
    textColor: ["responsive", "hover", "focus", "group-hover"],
    backgroundColor: ["responsive", "hover", "focus", "group-hover"],
    extend: {}
  },
  plugins: [
    function ({ addUtilities }) {
      const newUtilities = {
        ".flex-100": {
          flex: "0 0 100%"
        },
        ".flex-90": {
          flex: "0 0 90%"
        },
        ".flex-80": {
          flex: "0 0 80%"
        },
        ".flex-70": {
          flex: "0 0 70%"
        },
        ".flex-50": {
          flex: "0 0 50%"
        },
        ".flex-45": {
          flex: "0 0 45%"
        },
        ".flex-40": {
          flex: "0 0 40%"
        },
        ".flex-30": {
          flex: "0 0 30%"
        },
        ".flex-20": {
          flex: "0 0 20%"
        }
      }
      addUtilities(newUtilities, {
        variants: ["responsive", "hover"]
      })
    }
  ]
}
```

これは私のテンプレートです。

また、Tailwindの公式ドキュメントにも非常に分かりやすく書いているので、そちらもご覧ください。

このようにしてNext.jsの環境構築を行うことができました。

皆さんもぜひコピペだけで環境構築を行いましょう！！

以上、「【2021年6月版】コピペだけでNext.js＋TypeScript＋Material-ui＋Tailwindcssの環境構築を行う」でした！

Thank you for reading

# 参考記事

・[5分で出来るかな? React/TypeScript/Next.js/Material-ui プロジェクトテンプレートの簡単な作り方](https://qiita.com/ytamayose/items/5eb416feda7374077bb7)
・[Install Tailwind CSS with Next.js](https://tailwindcss.com/docs/guides/nextjs#include-tailwind-in-your-css)