Next + TypeScript + MicroCMS でブログ作成。（環境構築〜一覧取得まで）

# Next.js + Typescript + MicroCmsで技術ブログ作成
## 前置き
普段の仕事では、Javaをメインとしてエンジニアをしているので、休日や隙間時間を利用して、フロントエンドの知識をInputしております。
※至らない部分も、多々あると思いますが、よろしくお願いたします。

その中で、Outputの為に、自分の日々勉強したことなどを発信する為の、技術ブログを作成しようと考えました。



__技術スタック__

- Next
- TypeScript
- tailwindCss
- MicroCms

ソースは以下（github）。詰まった際は、参照してみて下さい。

https://github.com/shuji-takeda/next-microCms-tutorial

それでは、環境構築から始めていきましょう。



### 1.環境構築
Next.jsのプロジェクト作成、TypeScript,TailwindCssの導入
※Nextのプロジェクトと、Tailwindのインストールを一発で出来るコマンドがあるので、こちらで作成していきましょう。

```
// create next.js project
// my-project部分を、ご自身に合わせて名前を変えて下さい。
npx create-next-app -e with-tailwindcss my-project

// typeScript install
# npmを使用している方は、こちら
npm install --save-dev typescript @types/react @types/node

# yarnを使用している方は、こちら
yarn add --dev typescript @types/react @types/node

cd プロジェクト名
touch tsconfig.json

// ここまでで、一度ローカル環境を立ち上げてみましょう。
yarn dev
```

問題なく、起動できていればOkです。現在のディレクトリ構成は画像の通りになっていると思います。

![](https://images.microcms-assets.io/assets/b7c43d0b3f1b486686b81049ed4728f7/efcf90d4d4a94add8c4d53b4d01f69e3/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202021-06-13%2016.37.20.jpg)


ディレクトリ構成が複雑になっても、大丈夫なように、srcディレクトリを作成し、そちらに纏めて行きます。

```
mkdir src &&　mv pages/ src/pages &　mv styles/ src/styles
```

tailwind.config.jsを変更したディレクトリ構成に合わせて修正します。

```
module.exports = {
  mode: 'jit',
  purge: [
// こちらを修正してください。
    './src/pages/**/*.{js,ts,jsx,tsx}',
    './src/components/**/*.{js,ts,jsx,tsx}',
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
```

```
tsconfig.json

{
  "compilerOptions": {
 // javascriptファイルへコンパイルされる時の形式を指定
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
// ファイルを探しに行く際の開始地点を指定します。
    "baseUrl": "./",
// ｊｓファイルのインポートを許容します
    "allowJs": true,
// 型定義ファイルのチェックをスキップします。
    "skipLibCheck": true,
// 型チェックの挙動を有効化
    "strict": true,
// TypeScript はプログラムがディスク上の大文字小文字と異なるファイルをインクルードしようとした場合にエラーを発生させます。
    "forceConsistentCasingInFileNames": true,
// JavaScript ソースコード、ソースマップ、型定義のファイルを出力しないようにします。
    "noEmit": true,
// すべてのインポートに対して Namespace オブジェクトを生成することによって、
// CommonJS と ES Modules 間で相互運用可能なコードを出力します。
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve"
  },
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

```

prettier/eslintの設定

```
// prettierのインストール
	yarn add -D prettier
    touch .prettierrc.js
作成した、構成ファイルに以下を記載して下さい。

// .prettierrc.js
module.exports = {
  semi: false,
  arrowParens: 'always',
  singleQuote: true,
}


// eslintのインストール
yarn add -D eslint eslint-plugin-react \
              eslint-config-prettier eslint-plugin-prettier \
	      @typescript-eslint/parser @typescript-eslint/eslint-plugin
touch .eslintrc.js

```

構成ファイルに以下を記載して下さい。

```
// .eslintrc.js
module.exports = {
  ignorePatterns: ['!.eslintrc.js', '!.prettierrc.js'],
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:prettier/recommended',
    'prettier/prettier',
    'prettier',
  ],
  plugins: ['@typescript-eslint', 'react', 'prettier'],
  parser: '@typescript-eslint/parser',
  env: {
    browser: true,
    node: true,
    es6: true,
    jest: true,
  },
  parserOptions: {
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true,
    },
  },
  settings: {
    react: {
      version: 'detect',
    },
  },
  rules: {
    'react/prop-types': 'off',
    'react/react-in-jsx-scope': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    'prettier/prettier': 'error',
    'no-tabs': ['error', { allowIndentationTabs: true }],
  },
}
```

続いて、_app.js , index.jsをTypeScriptに書き換えていきましょう。まずは、それぞれファイル拡張子をtsxへ変更しましょう。

app.js		→	__app.tsx__

index.js	→	__index.tsx__

```
// app.tsx
import 'tailwindcss/tailwind.css'
import React from 'react'
import { AppProps } from 'next/app'

function MyApp({ Component, pageProps }: AppProps): JSX.Element {
  return <Component {...pageProps} />
}

export default MyApp
```

```
// index.tsx
import Head from 'next/head'
import React from 'react'

export default function Home(): JSX.Element {
  return ( ~ここは、変更無し。
```

ここまでで、一度ローカル環境を立ち上げてみましょう。問題無く、起動できていればOKです。

```
yarn dev
```



###2.MicroCmsの導入
公式が提供している、microcms-js-sdkをインストールします。

yarn add microcms-js-sdk
※MicroCmsのセットアップについては、公式サイトを参照しながら、APIの作成までは、各自で行ってください。

https://document.microcms.io/tutorial/next/next-getting-started



環境変数を設定していきます。

プロジェクトのトップディレクトリに .env.development.localを作成してください。(APIプレビューより、確認出来ます。）

```
NEXT_PUBLIC_SERVICE_DOMAIN = "xxxxxx" (https://xxxxxxx.microcms.~のxxxx部分)
NEXT_PUBLIC_API_KEY = "xxxxxxxxxxxxxx"
```

次に、src配下にlibsというフォルダを作成し、そこにclient.jsを作成して下さい。
ここに、createClientというAPIをインポートし、API_KEY、SERVER＿DOMAINを利用して、データ取得するfunctionを記載していきます。

```
// src/libs/client.js

import { createClient } from 'microcms-js-sdk'

export const client = createClient({
  serviceDomain: process.env.NEXT_PUBLIC_SERVICE_DOMAIN,
  apiKey: process.env.NEXT_PUBLIC_API_KEY,
})
```

一覧ページを作成していきます。index.tsxを開いて下さい。

```
// src/page/index.tsx

import Head from 'next/head'
import React from 'react'
import { client } from '../libs/client'

interface Article {
  id: string
  title: string
  publishedAt: string
}

interface Contents {
  contents: Article[]
}

export default function Home({
  blog,
}: {
  blog: { id: string; title: string; publishedAt: string }[]
}): JSX.Element {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen py-2">
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <div>
        <ul>
          {blog.map((blog) => (
            <li key={blog.id}>
              <p>{blog.title}</p>
            </li>
          ))}
        </ul>
      </div>
    </div>
  )
}

export const getStaticProps = async () => {
  const data: Contents = await client.get({ endpoint: 'blog' })
  return {
    props: {
      blog: data.contents,
    },
  }
}
```

![](https://images.microcms-assets.io/assets/b7c43d0b3f1b486686b81049ed4728f7/aa76bcadc0004f4a99f3ff6d5c488133/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202021-06-13%2023.25.39%EF%BC%882%EF%BC%89.jpg)

このように、あなたが投稿したブログの記事のタイトルが全件取得出来ていると思います。（公開している記事に限る）
各詳細ページについては、src/page/blog/[id].tsxとか言う感じで、ダイナミックルーティングを利用してやれば、実装出来ますね。

https://nextjs.org/docs/routing/dynamic-routes

今回は、ここまでとします。お疲れさまでした！！！

PreviewModeの実装、各ブログページについても、今後備忘がてら、書いていきます。


「参考ドキュメント」
・https://zenn.dev/higa/articles/d7bf3460dafb1734ef43#15.-%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E8%BF%BD%E5%8A%A0

・https://zenn.dev/hiro08gh/articles/a953f46a839ee7

・https://www.typescriptlang.org/ja/tsconfig#skipLibCheck

・https://document.microcms.io/tutorial/next/next-top