Nuxt.jsによるフロントエンド開発CI設定手順(2020/10/24バージョン)

# 各ツールのバージョン

Visual Studio Code, Docker を使用します。各バージョンは以下の通りです。
今回はWindows10を使用していますが、MacOSでも同様に操作できます。

- Windows 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/6ce9ff8c-d710-445d-7e0e-7630b25c3180.png)

- Visual Studio Code

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/96cc4f6d-e947-3a9c-00a5-3440197f2a01.png)

- Docker
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/31d7a0b9-13f3-c034-44b2-9ca66821be47.png)

※以前Windowsのバージョンが1909だとDockerが入らなかったのですが、現在はインストール可能となったようです。

# 開発環境作成

Nuxt プロジェクトを作成し、GitHub で main ブランチに push したら自動で GitHub Pages に公開するよう準備します。

1) Visual Studio Code を起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/a40d9d37-7618-6e79-6020-23bf542ba67c.png)

2) 作業フォルダを作成し開きます。（今回は C:\dev\nuxt20201024 としました）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/c6080c34-eb46-f45b-34f7-898cff0c9fbd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/70315e67-eaf9-dc56-a8ca-6a9775c4e241.png)

3) 新規ファイル作成で Dockerfile という名前のファイルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/f5a84411-7e2d-cad4-c291-efd77d649c6a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/a32afbaf-4c90-b8e7-24ff-9e881a855799.png)

※![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/9476afbe-9963-3bde-2444-8c51d18a9d8d.png) がファイル作成ボタン


4) Dockerfile に Node.js 環境を作る内容を記載します。

```docker:Dockerfile
FROM node:lts-alpine
ENV CHOKIDAR_USEPOLLING=true NUXT_TELEMETRY_DISABLED=1
RUN apk update && apk add git
```
1行目：alpine OS の Node.js 入りイメージをベースにします。node:alpineだと Nuxt プロジェクトを作るときエラーとなったのでltsにしています。
2行目：開発時の自動更新を有効にし、Nuxt 実行時の統計確認を無効にします。
3行目：パッケージを更新し、gitをインストールします。

5) Visual Studio Code の Remote Development を使って Dockerコンテナを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/d9f9bf46-a2b6-e20a-e896-02ea3a1555a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/7dfa8a4f-498a-5c0c-0b46-1e2a7659aca1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/d25d8912-2d34-f50a-e8f1-c67a3ba4909f.png)
※Remote Development 拡張機能が入っていない場合はインストールしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/72c319c9-7995-0402-6dd0-b1f88789f2c9.png)

6) Vuter 拡張機能をインストールする設定("octref.vetur")を追加し、Docker環境をリビルドします。

```json:.devcontainer/devcontainer.json
{
(...省略)
	// Add the IDs of extensions you want installed when the container is created.
	"extensions": ["octref.vetur"]
(...省略)
}

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/b8cbc765-e81b-37a6-439c-1fc97712be73.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/558c3f62-725c-17cc-d552-c84f2517e063.png)

7) Nuxtプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/c1c33695-ecde-1758-6749-72a7fd8790b4.png)

```shell:Terminal
yarn create nuxt-app my-nuxt
```
※my-nuxt はプロジェクト名なので自由に名前を付けられます。

```
? Project name: (my-nuxt)
```
プロジェクト名を聞かれますので、そのまま Enter

```
? Programming language: (Use arrow keys)
❯ JavaScript 
  TypeScript
```
使用する言語を聞かれますので JavaScript のまま Enter

```
? Package manager: (Use arrow keys)
❯ Yarn 
  Npm
```

パッケージマネージャを聞かれますので、Yarn のまま Enter

```
? UI framework: (Use arrow keys)
❯ None 
  Ant Design Vue 
  Bootstrap Vue 
  Buefy 
  Bulma 
  Chakra UI 
  Element 
  Framevuerk 
  iView 
  Tachyons 
  Tailwind CSS 
  Vuesax 
  Vuetify.js 
```

UI フレームワークを聞かれますがあとから追加可能なので None のまま Enter

```
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◯ Axios
 ◯ Progressive Web App (PWA)
 ◯ Content
```

インストールするモジュールを聞かれますがあとから追加可能なのでそのまま Enter

```
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◯ ESLint
 ◯ Prettier
 ◯ Lint staged files
 ◯ StyleLint
 ◯ Commitlint
```

インストールする構文チェックツールを聞かれますがあとから追加可能なのでそのまま Enter

```
? Testing framework: 
  None 
❯ Jest 
  AVA 
  WebdriverIO 
```

テストツールを聞かれますので、Jest を選択し Enter

```
? Rendering mode: (Use arrow keys)
  Universal (SSR / SSG) 
❯ Single Page App 
```

レンダリングモードを聞かれますので、Single Page App を選択し Enter

```
? Deployment target: (Use arrow keys)
  Server (Node.js hosting) 
❯ Static (Static/JAMStack hosting) 
```

デプロイ先を聞かれますが、今回 GitHub Pages を使うので Static (Static/JAMStack hosting) を選択し Enter

```
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◯ jsconfig.json (Recommended for VS Code if you're not using typescript)
 ◯ Semantic Pull Requests
 ◯ Dependabot (For auto-updating dependencies, GitHub only)

```

インストールするデプロイ用ツールを聞かれますがあとから追加可能なのでそのまま Enter

```
? Continuous integration: (Use arrow keys)
  None 
❯ GitHub Actions (GitHub only) 
```

インストールする CI ツールを聞かれますが、今回 GitHub Actions を使うので GitHub Actions (GitHub only) を選択し Enter

```
? What is your GitHub username?
```

GitHub のユーザ名を聞かれますので自分のユーザ名を入力します。

```
? Version control system: (Use arrow keys)
❯ Git 
  None 
```

使用するバージョン管理ツールを聞かれますので、Git を選択し Enter

```
🎉  Successfully created project my-nuxt
```

Successfully が出れば作成完了です。

8) 実行してブラウザで確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/1fd172e1-0632-9053-4128-e62e7312c9d0.png)

NPM SCRIPTS の dev - my-nuxt の右に出る三角ボタンで実行できます。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/8d7df41b-d876-94d8-dc6b-1dbd636864a4.png)

リモートエクスプローラタブに切り替えると FORWARDED PORTS がひょうじされ、3000 のところの地球儀のマークをクリックするとブラウザが起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/bb25d8d1-ac44-2a97-ab67-f7490c57574c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/107c7adb-cce9-97ec-63d7-8e6ccb1612fd.png)

9) Git リポジトリ管理を開始します。

ソースコントロールタブに切り替えると変更ファイル一覧が表示されているので、Message 欄にコミットコメントとして first と入力してチェックボタンを押しコミットします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/a2d2e7c7-9028-5d50-6356-da87b699f1c3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/ac2c77d9-d0a5-a396-b70e-4b7150239418.png)

10) GitHub にリポジトリを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/ad22f431-02a5-4967-81cc-9de329ff74dc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/37405f97-7790-150e-e5e1-9fbd6eccc78a.png)

Repository name を入力し、Public で作成します。（Private だと GitHub Pages を使うとき有料になります。）

11) リポジトリを GitHub に紐づけて Push します。

SOURCE CONTROL の・・・メニューから Remote / Add Remote... を選択し、Add Remote from GitHub を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/c4aa944f-b1dd-3812-fddd-3ab7d025bc95.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/37667b27-22bc-7eb8-a280-fbf8770c453c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/beab1a05-a12d-ffa7-0fa3-ecedea08b53c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/8e2ddc25-0451-f900-70ec-b0212ec2a2a2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/9bc2ed29-c52f-c3bd-10e8-2d8d13100be3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/19732227-6a45-b6a6-1788-9f5d1e5df721.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/5d6915bc-0d74-5f53-3576-c1a54ca79511.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/aff7cfde-b528-9e6d-9b61-71faadcb202f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/973e248d-15a0-3614-2517-7e9b32c14e03.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/53f9c487-31e6-af51-cba5-e29dc9d83ebc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/a2c852fb-5558-a31b-5ed5-856e9700c105.png)

12) GitHub Actions で GitHub Pages にデプロイする設定を追加します。

my-nuxt/.github/workflows/ci.yml を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/e894599b-7a1e-d374-4b61-b6cc5749f286.png)

テスト用の設定は入っているので、そのあとに GitHub Pages にデプロイする処理を追加し保存します。

```yaml:my-nuxt/.github/workflows/ci.yml
(...省略)
      - name: Run tests 🧪
        run: yarn test
(以下追加)
      - run: yarn generate

      - uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist
```

13) コミット、Push して GitHub Actions の動作ログを確認し、デプロイされたページも確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/3bb4f271-b0d5-8ee1-8dbb-eb35f5526e3c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/6eeafbc5-3b60-aa2e-4aa5-f67792a347b2.png)

GitHub の Actions ページを見て先ほど Push したコメントの workflow が完了していればデプロイ完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/208f736c-82da-1916-19ba-779e6361c7d3.png)

デプロイ完了していれば gh-pages ブランチができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/69306883-99b0-f76c-3436-8f098db13e69.png)

gh-pages ブランチに index.html があれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/167bdecb-6784-4c50-bd08-83ccfb686f6d.png)

GutHub の Settings ページの中にある GitHub Pages の設定に行きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/a0984619-bb4a-db7e-0c19-535699fd6d7a.png)

Source を gh-pages に切り替えて Save ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/3c3687af-a9c6-42c0-8d37-323d08971789.png)

Your site is ready to be published at の後の URL が公開ページになります。

14) ベースフォルダを調整します。

公開 URL が https://～.github.io/my-nuxt/ となっていて、Nuxt は既定では / ベースのパス後世になっているので、 /my-nuxt/ がベースになるよう設定を追加します。

```js:my-nuxt/nuxt.config.js変更前
(...省略)
  // Build Configuration (https://go.nuxtjs.dev/config-build)
  build: {
  }
}
```

```js:my-nuxt/nuxt.config.js変更後
(...省略)
  // Build Configuration (https://go.nuxtjs.dev/config-build)
  build: {
  },

  router: {
    base: process.env.BASE
  }
}
```

```yaml:my-nuxt/.github/workflows/ci.yml変更前
      - run: yarn generate
```

```yaml:my-nuxt/.github/workflows/ci.yml変更後
      - run: BASE=/my-nuxt/ yarn generate
```

コミット、Push してブラウザで確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/6264b394-1797-ae08-140f-3383bd1d1c69.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/7cb3213e-713c-c7e1-e87e-e1669ff916df.png)

以上で、Push すれば自動で公開される仕組みが完成しました。

# おまけ：FTPを使ってサーバに公開する設定

レンタルサーバ等にデプロイする場合の GitHub Actions の設定を紹介します。

ci.yml に以下の内容を追加します。

```yaml:my-nuxt/.github/workflows/ci.yml
(省略...)
      - run: yarn generate_ftp

      - name: FTP-Deploy-Action
        uses: SamKirkland/FTP-Deploy-Action@3.1.1
        with:
          ftp-server: ftp://FTPサーバのIPアドレスまたはDNS名/転送先のパス
          ftp-username: FTPユーザ名
          ftp-password: ${{ secrets.FTP_PASSWORD }}
          local-dir: dist/
```

今回は [FTP-Deploy-Action](https://github.com/marketplace/actions/ftp-deploy) を使っています。
FTPのパスワードは直接書いてしまうと公開されてしまうので、secrets という環境変数のようなもので指定します。
実際のパスワードは GitHub の Settings ページの Secrets に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/5b8fb10b-bf5f-8aab-7d80-3f9f7ed85f9f.png)

New secret ボタンを押して、Name には ci.yml に記載した FTP_PASSWORD を、Value にはパスワードを入力し、Add Secret ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/475ca652-4a6c-df3d-7dbf-ff4a55ebdc55.png)

以下のようになれば設定完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/ec62af9e-5af2-8d43-ca76-38d073d4b3b8.png)

また、GitHub Pages の yarn generate は /my-nuxt/ ベースになっているので、FTP ように yarn generate_ftp でビルドするようにします。

package.json にを編集します。

```js:my-nuxt/package.json変更前
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "BASE=/my-nuxt/ nuxt generate",
    "test": "jest"
  },
```

```js:my-nuxt/package.json変更後
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "BASE=/my-nuxt/ nuxt generate",
    "generate_ftp": "DIR=dist_ftp/ BASE=/user01/ nuxt generate",
    "test": "jest"
  },
```

ビルドしたファイルを dist_ftp フォルダに出力するよう DIR 環境変数を用意しています。
また、FTPユーザ名がサーバの公開パスになる場合は BASE 環境変数でそのパスを指定します。（上記では user01 で転送すると /user01 に入る想定）

DIRで指定したフォルダに出力されるよう nuxt.config.js も編集します。

```js:my-nuxt/nuxt.config.js変更前
{
(省略...)
  router: {
    base: process.env.BASE
  }
}
```


```js:my-nuxt/nuxt.config.js変更前
{
(省略...)
  router: {
    base: process.env.BASE
  },

  generate: {
    dir: process.env.DIR
  }
}
```

最後に dist_ftp フォルダは以下を git 管理から外すために .gitignore を編集します。

```shell:my-nuxt/.gitignore変更前
# Nuxt generate
dist
```

```shell:my-nuxt/.gitignore変更後
# Nuxt generate
dist
dist_ftp
```

これで、コミット・Push するとFTPサーバ経由でデプロイされるようになると思いましたが、実行するとファイルがアップロードされません。
調べると、アップロード対象ファイルは git 管理されているファイルの差分になるようです。

> My files aren't uploading
> V3+ uses github to determine when files have changes and only publish differences. This means files that aren't > committed to github will not upload by default.
> To change this behavior please see .git-ftp-ignore documentation.

ビルドした dist_ftp 配下のフォルダは git 管理外のため、アップロード対象とするには、.git-ftp-include を作成します。

```shell:my-nuxt/.git-ftp-include
!dist_ftp/
```

これで、FTPで転送されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/c37f63ad-2f21-6f93-1c3e-691c5a27b882.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82535/c3b75714-ad8a-acc8-14cf-2363f452f51f.png)

この仕組みを使えばレンタルサーバさえあればWebサービスを公開できます。
これまで手動でホームページを管理していたものも GitHub 管理にでき、アップロードが自動化できます。
そして、GitHub Pages とは違って、PHP やデータベースを使ったバックエンドも合わせて作れるので個人で開発するときに有用かと思います。