[TailwindCSS] Next.js+TypeScript+styled-componentsの環境にTailwindCSSを導入する

# はじめに
本記事は、既存のプロジェクトにTailwindCSSを導入するところから反映までになります。
`Next.js`,`TypeScript`,`styled-components`などの各導入については別途参照お願いします。
# 環境
- Next.js: v9.3.6
- TypeScript: v3.8.3
- styled-components: v4.4.1
- tailwindCSS: v1.4.4

create-next-appで作成したプロジェクトをベースに説明します。
# 導入
## TailwindCSS Install
[TailwindCSS公式](https://tailwindcss.com)

```
$ npm install --save-dev @fullhuman/postcss-purgecss tailwindcss postcss-import
```
[tailwindcss](https://tailwindcss.com/docs/installation): TailwindCSSのインストールをしています。
[@fullhuman/postcss-purgecss](https://www.npmjs.com/package/@fullhuman/postcss-purgecss): TailwindCSSの使ってないCSSを削除してくれます。
[postcss-import](https://www.npmjs.com/package/postcss-import):  npmからインストールしたCSSのモジュールをインポート可能にしています。

## postcss.config.jsファイルの作成

TailwindCSSを使えるようにするためにします。

```javascript
// postcss.config.js

const purgecss = [
    '@fullhuman/postcss-purgecss',
    {
        content: ['./components/**/*.js', './pages/**/*.js'],
        defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [],
    },
]
module.exports = {
    plugins: [
        'postcss-import',
        require('tailwindcss')('./tailwindcss-config.js'),
        'autoprefixer',
        ...(process.env.NODE_ENV === 'production' ? [purgecss] : []),
    ],
}
```
## TailwindCSSのimport 
pagesフォルダの中に`styles.css`を作成し、Tailwind CSSの[base](https://tailwindcss.com/docs/adding-base-styles/)、[components](https://tailwindcss.com/docs/extracting-components)、[utilities](https://tailwindcss.com/docs/adding-new-utilities)をインポートします。

```css
/* style.css */

@tailwind base;
@tailwind components;
@tailwind utilities;
```

### _app.jsにstyles.cssをインポート
下記のように、import文を追加します。

```javascript
// _app.js

import './styles.css'
```
## styled-componentsと併用可能にする
[tailwind.macro](https://github.com/bradlc/tailwind.macro)というbabelプラグインをインストールします。

```
$ npm install --save-dev babel-plugin-macros tailwind.macro
```

インストールした、babelプラグインを.babelrcに

```
// .babelrc

{
    "presets": [
        "next/babel"
    ],
    "plugins": [
       "styled-components", 
    +  "macros"
    ]
}
```

これで、tailwind.macroをインポートして
`tw`の中にTailwind CSSのスタイルを入れれば反映できるはずでした。

こんな感じ

```typescript
import * as React from 'react'
import styled from 'styled-components'
import media from 'styled-media-query'
import tw from 'tailwind.macro'

const HeaderBox = styled.div`
    ${tw`bg-black`};
    ${media.lessThan('medium')`
    `};
`
```

エラーだらけなので、ひとつひとつ解消していきます。
# ハマった点
## 1.tailwind.macroモジュールに型定義

```
Could not find a declaration file for module 'tailwind.macro'. 
'node_modules/tailwind.macro/macro.js' implicitly has an 'any' type.
 Try `npm install @types/tailwind.macro` if it exists or add a new declaration (.d.ts) file containing 
 `declare module 'tailwind.macro';`
```

- tailwind.macroというmoduleは見つかりません
- `tailwind.macro`は暗黙的にany型であるので、型の定義をしてください。

とりあえず言われた通り`npm install @types/tailwind.macro`を実行してみます。

```
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@types%2ftailwind.macro - Not found
```

`@types/tailwind.macro`というpacakgeは存在しないようです。

これでは解決できないので
次に書いてある、型定義ファイルに`declare module 'tailwind.macro';`追記してみます。

```typescript

declare module 'tailwind.macro'
```
tailwind.macroが無事読み込まれました！
<img width="377" alt="スクリーンショット 2020-05-02 23.32.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384722/cec3426b-b2c3-d07c-b611-1af0bb7ec4cb.png">

エディタでのエラーは消えたので、実行してみます。

```
./src/components/organisms/MainHeader.tsx
Module not found: Can't resolve 'yumedeshinou-dev/tailwind.js' in '/workspace/yumedeshinou-dev/src/components/organisms'
```

実行時にModule not foundのエラー
書き方と設定周りが怪しいと感じたので調べました。

## 2.tailwindの設定
```
$ npx tailwindcss init
```
上記コマンドを実行すれば[tailwind.config.js](https://tailwindcss.com/docs/configuration/)は作られます。
とりあえず今回は導入して反映させるのが目的なので、公式からそのまま持ってきました。

```javascript
// tailwind.config.js

module.exports = {
  important: true,
  theme: {
    fontFamily: {
      display: ['Gilroy', 'sans-serif'],
      body: ['Graphik', 'sans-serif'],
    },
    extend: {
      colors: {
        cyan: '#9cdbff',
      },
      margin: {
        '96': '24rem',
        '128': '32rem',
      },
    }
  },
  variants: {
    opacity: ['responsive', 'hover']
  }
}
```

まだ実行時エラーは消えません。
babel-plugin-macrosの設定もしていないので、そちらもしてみます。

## 3.babel-plugin-macrosの設定

```javascript
// babel-plugin-macros.config.js

module.exports = {
    tailwind: {
        styled: 'styled-components',
        config: './tailwind.config.js',
        format: 'auto',
    },
}
```

tailwind.config.jsが読み込まれるように設定します。

## 4.styled-components+TailwindCSS

```typescript

import * as React from 'react'
import styled from 'styled-components'
import media from 'styled-media-query'
import tw from 'tailwind.macro'

const HeaderBox = styled('div')`
    ${tw`bg-black`};
    ${media.lessThan('medium')`
    `};
`
```

ブログ名的にヤバイ感じになってしまいましたが、無事反映されました！！！！！！！！
<img width="1440" alt="スクリーンショット 2020-05-02 23.58.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384722/f383f70e-1a1d-4357-b5de-4eedd764ef7d.png">

# まとめ
- TailwindCSSをインストールする
- TailwindCSSをstyled-componentsと併用可能にするためにtailwind.macroをインストール
- tailwind.macroモジュールの型定義をする
- tailwindの設定をする
- babel-pluguin-macrosの設定をする

以上で、無事Next.js+TypeScript+styled-componentsの環境に
TailwindCSSを導入することができました！

# 参考記事
- [Next.jsにTailwind CSSを導入する + styled-componentsと一緒に使う](https://code-log.hatenablog.com/entry/2020/02/20/213713)
- [Setup Tailwind with Styled-Components in Create-React-App in 5 Minutes](https://medium.com/@grobeldev/setup-tailwind-with-styled-components-in-create-react-app-in-5-minutes-50dd875f55c)
- [styled-componentsの中でTailwind CSSのクラスを使えるようになるtailwind.macroの紹介](https://qiita.com/hourglasshoro/items/a1dc20b3d8fe42730859)
- [Does tailwind.macro has typescript support ?](https://github.com/bradlc/tailwind.macro/issues/2)
- [next-starter-tailwind](https://github.com/taylorbryant/next-starter-tailwind/blob/master/src/pages/about.js)
- [babel-plugin-tailwind-components](https://github.com/bradlc/babel-plugin-tailwind-components)
- [初めてのtailwindcss (Vue.js + PurgeCSS)](https://qiita.com/hisako135/items/49c05633de4dadfcd627)
- [postcss-importでCSSモジュールを取り込む](https://tsukurite.github.io/notes/note/import-css-module-with-postcss-import/)
- [How to add a @tailwind CSS rule to css checker](https://stackoverflow.com/questions/47607602/how-to-add-a-tailwind-css-rule-to-css-checker)

至らない部分などありましたら、編集依頼などで教えていただければ幸いです！
ここまで、読んでいただきありがとうございました！