monorepo로 구성되어 React 응용 프로그램과Firebase Function 동거

TL;DR


monorepo 구성에서 React 응용과Firebase Function은 같은 창고로 관리하여 공통된 논리와 형식을 사용하도록 한다.
https://github.com/Alesion30/monorepo-react-app

단일 보고서란?


단일 보고서는 같은 창고에서 여러 응용 프로그램과 포장을 관리하는 방법을 가리킨다.여러 앱의 PR과 코드 차이 등이 한 창고에서 관리되기 때문에 복잡한 단점을 만들기 쉽지만, 공통의 논리를 사용해 단일한 종속 파일로 관리할 수 있다는 장점도 있다.
동서 보고서에 관하여CircleaCI의 블로그에서 간단명료하게 총결하였다.
https://circleci.com/ja/blog/monorepo-dev-practices/
이번에는 yarn의 workspaces 기능을 사용하여 리포트 응용 프로그램과Firebase Function을 관리하고 싶습니다.
https://classic.yarnpkg.com/lang/en/docs/workspaces/

설정

monorepo-react-app의 이름으로 설치를 계속합니다.또한yarn의 버전은 3.0.0을 사용합니다.
$ mkdir monorepo-react-app
$ cd monorepo-react-app
monorepo-react-app:$ yarn init -y
monorepo-react-app:$ yarn set version 3.0.0
.yarnrc.yml
# nodeLinkerを追加する
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-3.0.0.cjs
. gitignore 파일을 만듭니다.
monorepo-react-app:$ touch .gitignore
.gitignore
# dependencies
**/node_modules
**/.pnp
**/.pnp.js

# testing
**/coverage

# yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# misc
**/.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

# log
**/npm-debug.log*
**/yarn-debug.log*
**/yarn-error.log*
폴더에서 개별 응용 프로그램(React Firebase Function)을 관리합니다.
monorepo-react-app:$ mkdir packages
./package.json
{
  "name": "monorepo-react-app",
  "private": true,
  // workspacesを追加する
  "workspaces": {
    "packages": [
      "packages/*"
    ]
  },
  "packageManager": "[email protected]"
}

React 환경 구축


이 글은create-react-app가 아니라vite로 응용 프로그램을 구축합니다.
https://ja.vitejs.dev/
monorepo-react-app:$ yarn create vite packages/client --template react-ts
!
lock 파일은 루트에서 관리하기 때문에 패키지/client 이하에서 생성된 패키지 lock입니다.제이슨과 yarn.먼저 lock을 삭제합니다.
package.제이슨의 nameclient인 것을 확인하다.
packages/client/package.json
{
  "name": "client",
  "private": true,
  "version": "0.0.0",
  // ...
}
!
package.json의name 값은workspace에서 사용하는 이름입니다.
(e.g. yarn workspace ワークスペース名 dev )
monorepo-react-app:$ yarn install
monorepo-react-app:$ yarn workspace client dev

Firebase Function 환경 구성


Firebase cli를 가져오지 않은 사람은 먼저 설정해야 합니다.
https://firebase.google.com/docs/cli
다음 명령을 클릭하면 functions 폴더, .firebaserc, firebase.json가 생성됩니다.
monorepo-react-app:$ firebase init functions
functions 폴더를 packages 폴더로 이동합니다.
firebase.다음은 json을 수정합니다.
firebase.json
{
  "functions": {
    "predeploy": "yarn workspace functions run build",
    "source": "packages/functions"
  }
}
src/index.ts에 Hello World 함수를 추가합니다.
packages/functions/src/index.ts
import * as functions from "firebase-functions";

// Start writing Firebase Functions
// https://firebase.google.com/docs/functions/typescript
export const helloWorld = functions.https.onRequest((request, response) => {
  functions.logger.info("Hello logs!", {structuredData: true});
  response.send("Hello from Firebase!");
});
monorepo-react-app:$ yarn workspace functions build

통합 Type Script 버전


client와 functions의 Type Script의 버전이 일치하지 않기 때문에 패키지를 라우팅합니다.json에서 Type Script 버전을 관리합니다.
먼저 설치된 Type Script를 제거합니다.
monorepo-react-app:$ yarn workspace client remove typescript
monorepo-react-app:$ yarn workspace functions remove typescript
Type Script를 설치합니다.
monorepo-react-app:$ yarn add -D typescript

eslint prettier 가져오기


monorepo-react-app:$ yarn add -D eslint eslint-config-prettier eslint-plugin-import eslint-plugin-react eslint-plugin-sort @typescript-eslint/eslint-plugin @typescript-eslint/parser prettier prettier-plugin-sort-json
eslint와prettier의 설정 파일을 만듭니다.
monorepo-react-app:$ touch .eslintrc .eslintignore .prettierrc .prettierignore
.eslintrc
{
  "env": {
    "browser": true,
    "es2017": true,
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:import/recommended",
    "plugin:react/recommended",
    "plugin:sort/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2021,
    "sourceType": "module"
  },
  "plugins": ["import", "sort", "@typescript-eslint"],
  "root": true,
  "rules": {
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        "argsIgnorePattern": "^_"
      }
    ],
    "import/no-unresolved": [
      "error",
      {
        "ignore": ["\\?raw$"]
      }
    ],
    "import/order": [
      "error",
      {
        "alphabetize": {
          "order": "asc"
        },
        "newlines-between": "always"
      }
    ],
    "react/jsx-sort-props": [
      "error",
      {
        "reservedFirst": true,
        "shorthandFirst": true
      }
    ],
    "react/prop-types": ["off"],
    "react/react-in-jsx-scope": "off",
    "sort/imports": ["off"]
  },
  "settings": {
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"]
      }
    },
    "react": {
      "version": "detect"
    }
  }
}
**/node_modules/*
**/dist/*
**/lib/*
.yarn
.prettierrc
{
  "jsonRecursiveSort": true,
  "trailingComma": "all"
}
**/node_modules/*
**/dist/*
**/lib/*
.yarn
*.md

참고 문장


https://ito-u-oti.com/react-monorepo/
https://zenn.dev/takanori_is/articles/tsconfig-in-monorepo
https://qiita.com/sisisin/items/954cf6b3464233e2d010
https://blog.cybozu.io/entry/2020/04/21/080000

좋은 웹페이지 즐겨찾기