web_bonsaiの日記

web開発の学習日記です。誰に見せるためでもないただの日記です。

Dependabotバージョンアップデートを有効化する | Mac + Docker + Rails + Next.js その0042

参考にさせていただいたページ

概要

基本的にマイクロソフトの「GitHub リポジトリで Dependabot セキュリティ アップデートを構成する - Learn | Microsoft Docs」を順を追って読んでいきながら設定するのが良さそうです。

Dependency graph(依存関係グラフ)

Dependency graph(依存関係グラフ)を有効化する

Dependency graph(依存関係グラフ)が有効化されていないとDependabotは有効化されないらしいので、「GitHub で依存関係を管理する - Learn | Microsoft Docs」に倣ってDependency graph(依存関係グラフ)を有効化します。

  • 「Settings」 > サイドメニュー内のSecurityセクションの「Code security and analysis」 > Dependency graphの「Enable」ボタンをクリック

Dependency graph(依存関係グラフ)を表示する

一度確認しておくと良いでしょう。

  • 「Insights」 > 「Dependency graph」 > いずれかのタブを選択

Dependabot alerts

Dependabot alertsを有効化する

  • 「Settings」 > サイドメニュー内のSecurityセクションの「Code security and analysis」 > DependabotセクションのDependabot alertsの「Enable」ボタンをクリック

Dependabot alertsを表示する

  • 「Security」 > 「Dependabot alerts」 の順にクリックすると一覧が表示されます。

Dependabot security updates

Dependabot security updatesを有効化する

  • 「Settings」 > サイドメニュー内のSecurityセクションの「Code security and analysis」 > DependabotセクションのDependabot security updatesの「Enable」ボタンをクリック

たぶんこれで自動的にPull requestsが作成されるようになると思います。

Dependabot version updates

Dependabot version updatesを有効化する

  • 「Settings」 > サイドメニュー内のSecurityセクションの「Code security and analysis」 > DependabotセクションのDependabot version updatesの「Enable」ボタンをクリック

そうすると、dependabot.yml作成ページに遷移します。

以下のdependabot.ymlのドキュメントなどを参考に記述してコミットすれば、自動的にPull requestsが作成されるようになると思います。

dependabot.ymlのドキュメント: 「https://docs.github.com/ja/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#about-the-dependabotyml-file

記述内容としては例えば以下のような感じですが、pull requestsが大量に作成され過ぎるのでversion updatesは無効のままでも良いかもしれません。
package-ecosystem, directory, schedule.interval は必須らしいです。schedule.timezoneは必須ではありませんが記述しています。

# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
  - package-ecosystem: "bundler"
    directory: "/rails"
    schedule:
      interval: "weekly"
      timezone: "Asia/Tokyo"
  - package-ecosystem: "npm"
    directory: "/frontend"
    schedule:
      interval: "weekly"
      timezone: "Asia/Tokyo"

ChakraUIを導入する | Mac + Docker + Rails + Next.js その0041

参考にさせていただいたページ

インストール

frontendディレクトリで作業をしていきます。

% cd frontend/

インストールします。

% yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^6

ChakraProviderコンポーネントの設置

公式ページに倣って、frontend/src/pages/_app.tsにChakraProviderコンポーネントを設置します。

開発環境を起動する

% docker-compose up

試しにButtonコンポーネントを使ってみる

Button - Chakra UI」を参考に frontend/src/pages/index.tsx 内で以下のようにButtonをインポートします。

import { Button } from '@chakra-ui/react';

Buttonを以下のような感じで適当な場所に設置します。

<Button colorScheme="blue">ボタン</Button>

以下の画像のようにButtonが設置できました。

Storybookを導入する | Mac + Docker + Rails + Next.js その0040

参考にさせていただいたページ

インストールする

frontendディレクトリで作業をしていきます。

% cd frontend/

インストールします。

% yarn add -D storybook

storybookを初期化

bundlerにwebpack5を指定して初期化してみます。

% yarn storybook init --builder webpack5

以下のような質問が表示されました。eslintPluginを使うのでyを選択しました。

? Do you want to run the 'eslintPlugin' migration on your project? › (y/N)

storybook initによって変更されたファイルなどの確認

.eslintrc.jsに以下の+行が追記されました。prettierが一番下になるように手で並べ替えています。

  extends: [
    'airbnb',
    'plugin:@typescript-eslint/recommended',
    'next/core-web-vitals',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:import/typescript',
    'next/babel',
+   'plugin:storybook/recommended',
    'prettier',
  ],

package.jsonのscriptsに以下の+行が追記されました。

  "scripts": {
    "dev": "next dev -p 3001",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "test": "jest --watch",
    "test:ci": "jest --ci",
+   "storybook": "start-storybook -p 6006",
+   "build-storybook": "build-storybook",
    "preinstall": "typesync || :"
  },

package.jsonのdevDependenciesに以下の+行が追記されました。たぶん @types/babel__core はstorybook initではなくtypesyncが自動実行されたことによる変更です。

  "devDependencies": {
+  "@babel/core": "^7.18.9",
+   "@storybook/addon-actions": "^6.5.9",
+   "@storybook/addon-essentials": "^6.5.9",
+   "@storybook/addon-interactions": "^6.5.9",
+   "@storybook/addon-links": "^6.5.9",
+   "@storybook/builder-webpack5": "^6.5.9",
+   "@storybook/manager-webpack5": "^6.5.9",
+   "@storybook/react": "^6.5.9",
+   "@storybook/testing-library": "^0.0.13",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^14.3.0",
+   "@types/babel__core": "^7.1.19",
    "@types/eslint": "8.4.5",
    "@types/node": "18.0.3",
    "@types/prettier": "^2.6.3",
    "@types/react": "18.0.15",
    "@types/react-dom": "18.0.6",
    "@types/testing-library__jest-dom": "^5.14.5",
    "@typescript-eslint/eslint-plugin": "^5.30.7",
+   "babel-loader": "^8.2.5",
    "eslint": "8.19.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-next": "12.2.1",
    "eslint-config-prettier": "^8.5.0",
+   "eslint-plugin-storybook": "^0.6.1",
    "jest": "^28.1.3",
    "jest-environment-jsdom": "^28.1.3",
    "prettier": "^2.7.1",
    "storybook": "^6.5.9",
    "stylelint": "^14.9.1",
    "stylelint-config-recess-order": "^3.0.0",
    "stylelint-config-standard": "^26.0.0",
    "stylelint-order": "^5.0.0",
    "typescript": "4.7.4",
    "typesync": "^0.9.2"
  }

当然のことながらyarn.lockも変更されていますが割愛します。

.storybook/*src/stories/* が自動生成されています。

storybookを実行してみる

% yarn storybook

自動でブラウザが起動して、「http://localhost:6006/?path=/story/example-introduction--page」を開き、以下のような画面が表示されます。

画面の左側にあるメニューから、storybook initによって自動生成されたサンプルのコンポーネントが確認できます。

.storybookディレクトリの中身の確認

以下の2ファイルが生成されています。

これらはstorybookの設定ファイルです。

公式ページを確認すると良いでしょう。
Configure Storybook

src/storiesの中身の確認

この中にはButtonなどのサンプルコンポーネントとそれに対応するstories.tsxが生成されています。

frontendのテストをGitHubActionsで実行できるようにする | Mac + Docker + Rails + Next.js その0039

参考にさせていただいたページ

actions/cache公式

その他

.github/workflows/frontend_workflow.ymlの作成とその記述内容

% vim .github/workflows/frontend_workflow.yml

記述内容は以下の通りです。

name: Rails Test Workflow
on: push
jobs:
  frontend-spec:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Get yarn cache directory path
        id: yarn-cache-dir-path
        run: echo "::set-output name=dir::$(yarn cache dir)"
      - uses: actions/cache@v3
        id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
        with:
          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-yarn-
      - name: Install Dependencies
        run: yarn --cwd frontend install --prefer-offline
      - name: yarn test:ci
        run: yarn --cwd frontend test:ci

Jestを導入してコンポーネントのテストをする | Mac + Docker + Rails + Next.js その0038

参考にさせていただいたページ

インストールする

frontendディレクトリで作業を行っていきます。

% yarn add -D jest jest-environment-jsdom  @testing-library/react @testing-library/jest-dom @testing-library/user-event

frontend/jest.config.jsの作成とその記述内容

npx create-next-app@latest --example with-jest with-jest-app でcreateした場合に生成されるjest.config.jsをベースにして、以下の通り作成しました。

const nextJest = require('next/jest');

const createJestConfig = nextJest({
  // next.config.jsとテスト環境用の.envファイルが配置されたディレクトリをセット。基本は"./"で良い。
  // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
  dir: './',
});

// Add any custom config to be passed to Jest
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  moduleNameMapper: {
    // Handle module aliases (this will be automatically configured for you soon)
    // '^@/components/(.*)$': '<rootDir>/components/$1',
    // '^@/pages/(.*)$': '<rootDir>/pages/$1',
    '@/(.*)$': '<rootDir>/$1',
  },
  testEnvironment: 'jest-environment-jsdom',
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);

frontend/jest.setup.jsの作成とその記述内容

npx create-next-app@latest --example with-jest with-jest-app でcreateした場合に生成されるjest.setup.jsに倣って、以下の通り作成しました。

// Optional: configure or set up a testing framework before each test.
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`

// Used for __tests__/testing-library.js
// Learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect'

Parsing error: Cannot find module 'next/babel' を解決する

このとき frontend/jest.config.js の1行目の1文字目にeslint のエラーが以下のように出ています。

Parsing error: Cannot find module 'next/babel'

frontend/.eslintrc.js に以下の+されている行を追記します。
検索すると'next/babel'を追記するという古い情報もありますが、'next'を追記します。

  extends: [
    'airbnb',
    'plugin:@typescript-eslint/recommended',
    'next/core-web-vitals',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:import/typescript',
+   'next',
    'prettier',
  ],

これで解消されました。

frontend/package.jsonのscriptsを追加する

npx create-next-app@latest --example with-jest with-jest-app でcreateした場合に生成されるjest.setup.jsに倣って、frontend/package.json に以下の+されている行を追記します。

  "scripts": {
    "dev": "next dev -p 3001",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
+   "test": "jest --watch",
+   "test:ci": "jest --ci",
    "preinstall": "typesync || :"
  },

テストの準備と実行

frontend/src/components/JestSample.tsxの作成とその記述内容

% mkdir src/components/
% vim src/components/JestSample.tsx

以下の通り記述しました。

export const JestSample = () => {
  return (
    <main>
      <h1>JestSampleコンポーネント</h1>
      <p>Jest導入の動作確認用サンプル</p>
    </main>
  );
};

frontend/src/components/JestSample.spec.tsxの作成とその記述内容

% mkdir src/components
% vim src/components/JestSample.spec.tsx

以下の通り記述しました。

import { JestSample } from '@/src/components/JestSample';
import { render } from '@testing-library/react';

describe('JestSampleコンポーネント', () => {
  test('内包する要素が描画されている', () => {
    const { getByText } = render(<JestSample />);
    expect(getByText('JestSampleコンポーネント')).toBeTruthy();
    expect(getByText('Jest導入の動作確認用サンプル')).toBeTruthy();
  });
});

実行してみる

以下のコマンドを実行します。

% yarn test

以下のような感じで成功しました。

ひとつ上の階層から実行してみる

% cd ../
% yarn --cwd ./frontend test

成功しました。

フロントエンドの開発環境を整える | Mac + Docker + Rails + Next.js その0037

frontendディレクトリに移動

今回の手順はfrontendディレクトリで行なっていくので、移動します。

% cd frontend/

絶対パスインポートの設定

絶対パスインポートが使えるように、frontend/tsconfig.jsonのcompilerOptionsに設定を追加します。

  "compilerOptions": {
    〜省略〜
    "baseUrl": ".",
    "paths": {
      "@/*": ["./*"]
    },
    〜省略〜
  },

typesyncをインストール

インストールします。

% yarn add -D typesync

実行できるか確認します。

% yarn typesync
% yarn install

package.jsonのscriptsにpreinstallを追記します。

  "scripts": {
    〜省略〜
    "preinstall": "typesync || :"
  },

ESLintとPrettierをインストールして設定

package.jsonのeslint関連パッケージを確認

package.jsonを確認すると、eslint-config-nextが既にインストールされています。

.eslintrcの拡張子を変更

まず.eslintrc.jsonが生成されているので、.eslintrc.jsに拡張子を変更します。

以下のように、module.exports = { にします。

module.exports = {
  extends: "next/core-web-vitals",
};

eslint-config-nextの中身を確認

どのようなpuluginが既に含まれているか、 node_modules/eslint-config-next/index.js を確認すると良いでしょう。

パッケージをインストール

prettier, eslint-config-prettier と その他のeslintパッケージをインストールします。

% yarn add -D prettier eslint-config-prettier eslint-config-airbnb @typescript-eslint/eslint-plugin

.eslintrc.jsの編集

extends

extendsを以下の通り編集します。各プラグインルールの推奨設定を適用しています。プラグインは読み込んだだけでは有効化されないので、有効化したいものをextendsで指定します。

module.exports = {
  extends: [
    'airbnb',
    'plugin:@typescript-eslint/recommended',
    'next/core-web-vitals',
    'plugin:import/errors',
    'plugin:import/warnings',
    'plugin:import/typescript',
    'prettier',
  ],
};

parserOptionsの設定を追加する

.eslintrc.jsにperserOptionsを追加します。

module.exports = {
  〜省略〜
  parserOptions: {
    project: './tsconfig.eslint.json',
    tsconfigRootDir: __dirname,
  },
};

tsconfig.eslint.jsonを新規作成します。

% vim tsconfig.eslint.json

以下の通り記述します。

{
  "extends": "./tsconfig.json",
  "include": [
    "src/**/*.js",
    "src/**/*.jsx",
    "src/**/*.ts",
    "src/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

plugins

.eslintrc.jsにpluginsを追加します。pluginsの配列に加えることで、ルールが使用可能になります。

module.exports = {
  〜省略〜
  plugins: [
    '@typescript-eslint',
  ],
};

root: trueにする

frontendサービスのrootディレクトリなので、root: true,にしておきます。

module.exports = {
  〜省略〜
  root: true,
};

rulesで少し調整する

このままだと frontend/src/pages/index.tsx などでeslintのエラーが出ているのでrulesで少し調整します。

module.exports = {
  〜省略〜
  rules: {
    'react/function-component-definition': [
      2,
      { namedComponents: 'arrow-function' },
    ],
    'react/jsx-filename-extension': [
      'error',
      {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    ],
    'react/jsx-props-no-spreading': 'off',
  },
};

.eslintignoreの作成

% vim .eslintignore

以下の通り記述します。

build/
public/
**/coverage/
**/node_modules/
**/*.min.js
*.config.js
.*lintrc.js

.prettierrcの作成

% vim .prettierrc

以下の通り記述します。

{
  "singleQuote": true,
  "trailingComma": "all",
  "endOfLine": "auto"
}

eslintとprettierのルールが衝突していないか確認

以下のコマンドで確認できます。

% npx eslint-config-prettier 'src/**/*.{js,jsx,ts,tsx}'

stylelintをインストールして設定

stylelintをインストール

インストールします。

% yarn add -D stylelint stylelint-config-standard stylelint-order stylelint-config-recess-order

.stylelintrc.jsの作成

% vim .stylelintrc.js

以下の通り記述します。

module.exports = {
  extends: [
    'stylelint-config-standard',
    'stylelint-config-recess-order',
  ],
  plugins: [
    'stylelint-order',
  ],
  ignoreFiles: [
    '**/node_modules/**',
  ],
  rules: {
    'string-quotes': 'single',
  },
};

VSCodeの設定

ディレクトリに移動する

docker-compose.ymlがある階層に移動します。

% cd ../

VSCode用の.eslintignoreの作成

% vim .eslintignore

以下の通り記述します。

frontend/build/
frontend/public/
frontend/**/coverage/
frontend/**/node_modules/
frontend/**/*.min.js
frontend/*.config.js
frontend/.*lintrc.js

Prettierの拡張をVSCodeにインストールしていると、Prettierによるコード成形は動作しますが、ESLintによるチェックは動作しなくなるはずです。

.vscodeディレクトリの作成

% mkdir .vscode/

.vscode/settings.jsonの作成

% vim .vscode/settings.json

以下の通り記述します。(これらが何なのか理解不足なので後でちゃんと読む必要あり。)

{
  "css.validate": false,
  "less.validate": false,
  "scss.validate": false,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.fixAll.stylelint": true
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": false,
  "[graphql]": {
    "editor.formatOnSave": true
  },
  "[javascript]": {
    "editor.formatOnSave": true
  },
  "[javascriptreact]": {
    "editor.formatOnSave": true
  },
  "[json]": {
    "editor.formatOnSave": true
  },
  "[typescript]": {
    "editor.formatOnSave": true
  },
  "[typescriptreact]": {
    "editor.formatOnSave": true
  },
  "editor.lineNumbers": "on",
  "editor.rulers": [
    80
  ],
  "editor.wordWrap": "on",
  "eslint.packageManager": "yarn",
  "files.insertFinalNewline": true,
  "files.trimTrailingWhitespace": true,
  "npm.packageManager": "yarn",
  "typescript.enablePromptUseWorkspaceTsdk": true
}

.vscode/extensions.jsonの作成

% vim .vscode/extensions.json

以下の通り記述します。

{
  "recommendations": [
    "CoenraadS.bracket-pair-colorizer-2",
    "dbaeumer.vscode-eslint",
    "donjayamanne.githistory",
    "esbenp.prettier-vscode",
    "msjsdiag.debugger-for-chrome",
    "oderwat.indent-rainbow",
    "stylelint.vscode-stylelint",
    "VisualStudioExptTeam.vscodeintellicode",
    "vscode-icons-team.vscode-icons",
    "wix.vscode-import-cost"
  ],
  "unwantedRecommendations": []
}

package.jsonのscriptsを編集する

scriptsに以下の行を追加...とりあえずしないですが、後でするかもしれません。

  "scripts": {
    〜省略〜
    "fix": "npm run -s format && npm run -s lint:fix",
    "format": "prettier --write --loglevel=warn 'src/**/*.{js,jsx,ts,tsx,html,gql,graphql,json}'",
    "lint": "npm run -s lint:style; npm run -s lint:es",
    "lint:fix": "npm run -s lint:style:fix && npm run -s lint:es:fix",
    "lint:es": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:es:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:conflict": "eslint-config-prettier 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:style": "stylelint 'src/**/*.{css,less,sass,scss}'",
    "lint:style:fix": "stylelint --fix 'src/**/*.{css,less,sass,scss}'",
    〜省略〜
  },

Next.jsのpagesとstylesをsrcディレクトリに移動させる | Mac + Docker + Rails + Next.js その0036

参考にさせていただいたページ

Next.jsのソースコードをsrcディレクトリに移動させる

srcディレクトリを作成します。

% mkdir frontend/src/

srcディレクトリに移動させます。

% mv frontend/pages frontend/src
% mv frontend/styles frontend/src

publicディレクトリは移動させません。

動作確認する

upします。

% docker-compose up

https://localhost/」にアクセスしてNext.jsのスタートページが表示できることを確認しました。