Chapter 02無料公開

✅モノレポを採用する

たった
たった
2021.06.25に更新
プロジェクトルート
.
├── .github/workflows ... CI/CD
├── be     ... バックエンド
├── fe     ... フロントエンド
> ├── docker ... 開発環境
└── prettierrc.js ... コードフォーマット

このチャプターで使用するライブラリ

  • なし

モノレポとは?

モノレポは簡単に言うと、ひとつのリポジトリで関係するソースコードをまとめて管理する設計パターンです。プロジェクトルートに fe, beとディレクトリがあるのはまさにこれです。

今回の構成はモノレポと相性が良いのでこちらを採用します。
具体的にはGraphQLのスキーマを共有したり、スキーマに従ってフロントエンドのコードを自動生成したりする際に効果を発揮します。

モノレポそのものの考え方についてはこちらの動画が参考になると思います。

https://youtu.be/W71BTkUbdqE

フォルダ構成の例

node_modules, eslintなどはフロントエンドとバックエンドで分けるのがおすすめです。

プロジェクトルート
.
├── .github/workflows ... CI/CD
├── be     ... バックエンド
├── fe     ... フロントエンド
├── docker ... 開発環境
└── prettierrc.js ... コードフォーマット
バックエンド
be
├── src
├── tests
├── migrations   ... マイグレーションファイル(自動生成)
├── schema       ... GraphQLスキーマ(自動生成)
├── eslintrc.js  ... コーディングルール
├── ormconfig.js ... DBの接続設定
└── TypeOrmNamingStrategy.js ... 命名規則
アプリケーションコード
src
├── middleware     ... 認証・認可とGraphQLのコンテキスト
├── domain         ... ビジネスロジックの共通化
├── usecases       ... アプリケーションロジック
├── infrastructure ... 外部サービスとのやりとり
├── entities       ... エンティティとGraphQLのフィールド
├── resolvers      ... GraphQLのリゾルバー
└── inversify.config.ts ... 依存性の注入(以下、DI)の設定

設定ファイルの例

tsconfig.json
be/tsconfig.json
{
  "compilerOptions": {
    "noImplicitAny": true,
    "outDir": "./dist",
    "module": "commonjs",
    "target": "es2019",
    "types": ["reflect-metadata", "jest"],
    "lib": ["es2019", "esnext.asynciterable"],
    "esModuleInterop": true,
    "moduleResolution": "node",
    "removeComments": true,
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "strictPropertyInitialization": false,
    "noFallthroughCasesInSwitch": true,
    "strictFunctionTypes": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "baseUrl": "./"
  },
  "include": ["**/*.ts", "TypeOrmNamingStrategy.js"],
  "exclude": ["node_modules"]
}
nodemon.json
be/nodemon.json
{
  "watch": [
    "src"
  ],
  "ext": "ts",
  "ignore": [
    "tests/**/*.ts"
  ],
  "exec": "ts-node --files -r tsconfig-paths/register ./src/index.ts"
}
jest.config
be/jest.config.js
module.exports = {
  testMatch: ['**/tests/**/*.(spec|test).[jt]s?(x)', '/**/*.(spec|test).[jt]s'],
  moduleFileExtensions: ['ts', 'js'],
  globals: {
    'ts-jest': {
      tsconfig: 'tsconfig.json',
    },
  },
  transform: {
    '^.+\\.ts$': 'ts-jest',
  },
  moduleNameMapper: {
    '^src/(.*)$': '<rootDir>/src/$1',
  },
}
eslint
be/.eslintrc.js
module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/@typescript-eslint',
  ],
  plugins: ['@typescript-eslint'],
  parser: '@typescript-eslint/parser',
  parserOptions: { sourceType: 'module', ecmaVersion: 2020 },
  env: { es6: true, node: true },
  globals: {},
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
      },
      typescript: {},
    },
  },
  ignorePatterns: ['tests/**/*.ts'],
  rules: {
    '@typescript-eslint/ban-types': [
      'error',
      {
        types: {
          String: false,
          Boolean: false,
          Number: false,
          Symbol: false,
          '{}': false,
          Object: false,
          object: false,
          Function: false,
        },
        extendDefaults: true,
      },
    ],
    '@typescript-eslint/member-delimiter-style': [
      'error',
      {
        multiline: {
          delimiter: 'none',
          requireLast: false,
        },
        singleline: {
          delimiter: 'comma',
          requireLast: false,
        },
      },
    ],
  },
}

Dockerの構成の例

こんな感じでdocker-composeを使ってネットワークを1つにまとめてあげましょう。

docker-compose.yml
docker/dev/docker-copose.yml
version: '3.7'
services:
  fe:
    image: node:12-alpine
    volumes:
      - ../../fe:/app
    working_dir: /app
    command: yarn run dev
    ports:
      - 3000:3000
    environment:
 
  be:
    image: node:12-alpine
    volumes:
      - ../../be:/app
    working_dir: /app
    command: yarn run dev
    ports:
      - 4000:4000
    environment:
    depends_on:
      - db

  db:
    image: mysql:latest
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql/config:/etc/mysql/conf.d/my.cnf
    command: mysqld --collation-server=utf8mb4_bin
    ports:
      - 3306:3306
    environment:
volumes:
  mysql_data:
    driver: local