Next.jsではじめるTypescript環境

# NextJSではじめるTypescript環境

###### Table of Contents

0  Next.jsとは 
1. Next.jsの開発環境作成
2. Typescriptの有効化
3. CircleCIでbuildを実行

## 0. Next.jsとは

[Zeit](https://zeit.co/docs)社が提供しているReactを用いたSSR(SST)のOpen Source Projectです。
Vueで言うところのNuxtくらいの認識です。

![Next js - The React Framework.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/46ab3eef-73e8-5b0d-33cf-c32e3482411d.png)


## 1.Next.jsの開発環境作成

プロジェクトとpackage.jsonを作成していきます。

```terminal
$ mkdir next-sample && cd next-sample
$ npm init -y
{
  "name": "next-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

```

次に、ReactとNextJSを依存関係に追加していきます。

```terminal
$ npm install react react-dom next
```

パッケージが保存されると、_package.json_は以下のように更新されます。

```package.json
{
  "name": "next-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "next": "^9.2.1",
    "react": "^16.12.0",
    "react-dom": "^16.12.0"
  }
}

```

次にnextのコマンドが使えるように、package.jsonを編集します。

```package.json
{
  "name": "next-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
// ここから
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
// ここまで編集
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "next": "^9.2.1",
    "react": "^16.12.0",
    "react-dom": "^16.12.0"
  }
}
```

Nextjsで表示するためにroutingを追加していきます。
Nextjsのroutingはpagesというディレクトリを作成すると勝手にroutingが生成されます。

```terminal
$ mkdir pages
$ npm run dev
> next-sample@1.0.0 dev /your/project/next-sample
> next

[ wait ]  starting the development server ...
[ info ]  waiting on http://localhost:3000 ...
[ ready ] compiled successfully - ready on http://localhost:3000
[ wait ]  compiling ...
[ ready ] compiled successfully - ready on http://localhost:3000
```

pages内部に何も作成していないため、404ページが以下のように表示されますが、[localhost:3000](http://localhost:3000/)を確認すると以下のような表示になります。

![404.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/7406c4b0-1d17-1bbb-4b24-22f7bff5257c.png)

routingが正常に行われるかの確認のため、pages/index.jsxを追加していきます。

```terminal
$ touch pages/index.jsx
```

```pages/index.jsx
import React from 'react'

export default () => (<div>Hello World</div>)
```

作成後、[localhost:3000](http://localhost:3000/)を再読み込みさせると以下のページが表示されれば完璧です。

![localhost-3000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/b8e908cd-7514-733c-fb38-6afe57f83fef.png)

## 2. Typescriptの有効化

次に作成した_next-sample_へTypescriptの有効化をしていきます。

```terminal
$ npm install -D typescript @types/react @types/react-dom @types/node
$ touch tsconfig.json
```

作成したtsconfig.jsonを加筆していきます。
注意して欲しいのはincludeプロパティにsrc/**/*と追加したため、typescriptはsrc以下にあるファイルしか読み込まないように設定しました。


```tsconfig.json
{
  "compilerOptions": {
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "esnext",
    "target": "es6",
    "jsx": "preserve",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "moduleResolution": "node"
  },
  "include": ["src/**/*"], 
  "exclude": ["node_modules"]
}
```

次に、srcフォルダを作成しpagesをsrc以下に移動させます。

```terminal
$ mkdir src
$ mv pages src
$ npm run dev
```

_npm run dev_を動かすと、typescriptファイルコンパイルされ、先ほどと同じ以下の画面が表示されれば、あとはjsxファイルをtsxに変更します。

![localhost-3000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/ae25b2a8-b009-1039-c6a5-22d53b834799.png)

ファイルの変更は以下の感じです。

```terminal
$ mv src/pages/index.jsx src/pages/index.tsx
```

ファイルを変更し、もうサイドdevコマンドをうちうえと同じ画面が表示されればTypescript化は完了です。

```terminal
$ npm run dev
```
このあとは、自分好みにtsconfigを変更したり下に書いたcircleCiの設定などを変更したり遊んでください。

## 3. CircleCIでbuildを実行

特段CirclCIを使う必要性はないのですが、とりあえず使いたいなーと考えている方がいましたら、コピペとかで初期設定をしてみてください。

[circleci](https://circleci.com/)はCI/CDツールです。
一例でいうと、githubにpushしたブランチをそのままデプロイしたり、testを回したりなどできるCI/CDツールです。
今回は何もしないですが、初期設定を記載しておきます。

```terminal
$ mkdir .circleci
$ touch .circleci/config.yml
```

config.ymlは以下のようにbuildまでが正常に行われるかの設定のみ記載いたします。

```.circleci/config.yml
version: 2.1
executors:
  node:
    working_directory: ~/project
    docker:
      - image: circleci/node:10.12-browsers
jobs:
  build:
    executor:
      name: node
    steps:
      - checkout
      - run:
          name: update-npm
          command: "sudo npm install -g npm@latest"
      - restore_cache:
          key: node-{{ .Branch }}-{{ checksum "package-lock.json" }}
      - run:
          name: npm install on ci
          command: npm ci
      - save_cache:
          key: node-{{ .Branch }}-{{ checksum "package-lock.json" }}
          paths:
            - ./node_modules
      - persist_to_workspace:
          root: .
          paths:
            - .
      - run:
          name: build flat
          command: npm run build
workflows:
  version: 2
  build-and-cache:
    jobs:
      - build

```

参考までに、うえの実装をレポにしておきました。
[Nextjsのサンプルレポジトリ](https://github.com/Ntakuya/react-sample/tree/contents/next-react-typescript)