본문으로 바로가기

type-node-graphql boilerplate 제작

category Node, Nest, Deno/🆕 Node.TS 2020. 10. 20. 04:40

예전에 사용하던 typescript 기반 node가 부족해서 새로 제작하기로 했다.

eslint도 붙이고, prettier도 붙이고, yoga가 아닌 순수 graphql을 붙이기로 했다.

 

 

우선 javascript 기반 프로젝트를 시작하자. (npm에서 yarn으로 갈아탐 ㅎ)

yarn add

 

 

1. 우선 기본적인 TS 기반의 express를 구성해보자.

 

아래와 같이 의존성 설치를 하자. @types/[package] 설치를 개발 의존성 부분에 해야 하는 걸 잊지말자.

요거 설치 안하면 eslint 설정 후에 type을 못 찾겠다고 아우성을 치는 모습을 볼 수 있다.

{
  "name": "type-node-graphql-boilerplate",
  "version": "1.0.0",
  "description": "typesciprt + graphql boilerplate",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "dev": "cd src && nodemon --exec ts-node index.ts -e ts,graphql,json"
  },
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "morgan": "^1.10.0",
    "pg": "^8.4.1",
    "ts-node": "^9.0.0",
    "typeorm": "^0.2.28"
  },
  "devDependencies": {
    "@types/cors": "^2.8.8",
    "@types/dotenv": "^8.2.0",
    "@types/express": "^4.17.8",
    "@types/morgan": "^1.9.1",
    "@types/node": "^14.11.10",
    "@typescript-eslint/eslint-plugin": "^4.5.0",
    "@typescript-eslint/parser": "^4.5.0",
    "eslint": "^7.11.0",
    "nodemon": "^2.0.6",
    "tsc-watch": "^4.2.9",
    "typescript": "^4.0.3"
  }
}

 

tsconfig.json 세팅은 생략한다. 궁금하면 아래 포스트를 참고하면 좋다.

darrengwon.tistory.com/109?category=867626

 

./src/index.ts

import dotenv from "dotenv"
import path from "path"
dotenv.config({ path: path.resolve(__dirname, "../.env") }) 
import express from 'express';
import logger from "morgan";
import cors from "cors";

const PORT = process.env.PORT
const isProd = process.env.NODE_ENV === "development" ? false : true
const app = express();

// middleware
app.use(logger(isProd ? "combined" : "dev"))
app.use(cors());

// router
app.get("/", (req, res) => res.json("what"))

// listener
app.listen(PORT, () => console.log(`Listen on : http://localhost:${PORT}`))

 

여기까지 진행했다면 커서를 올려 타입 추론이 잘 되는지 확인합시다.

 

 

2. prettier와 eslint 세팅

eslint에 prettier 까지 같이 세팅합시다.

 

eslint 부분은 워낙 취향이 갈리는 터라 설치만 하자.

yarn add eslint --dev // 설치
eslint --init // lint 구성 (.eslintrc.json 만들어서 구성하면 고생합니다 ㅜㅜ)
{
    "env": {
        "browser": true,
        "es2020": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/eslint-recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "project": "./tsconfig.json",
        "ecmaVersion": 11,
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint"
    ],
    "ignorePatterns": ["node_modules/"],
    "rules": {
    }
}

 

그런데 만약 여기보다 더 나아가 prettier까지 같이 사용하고 싶다면?

 

eslint-config-prettier는 Prettier와 충돌되는 ESLint 규칙들을 무시하는 설정이고, eslint-plugin-prettier는 Prettier를 사용해 포맷팅을 하도록 ESLint 규칙을 추가하는 플러그인입니다.

yarn add prettier eslint-config-prettier eslint-plugin-prettier --dev

 

.prettierrc 설정은 취향껏 해줍시다. darrengwon.tistory.com/605

{
	"semi": true,
	"useTabs": false,
	"tabWidth": 2,
	"printWidth": 100
}

 

그리고 eslint와 충돌하지 않도록 extends 쪽에 다음 두 extension들을 달아줍시다. extends들은 하단에 있는 것부터 올라가며 적용되기 때문에 이 두 설정은 아래에 두어야 합니다.

"extends": [
      ... 중략
      "plugin:prettier/recommended",
      "prettier/@typescript-eslint"
],

 

결론적으로는 아래와 같이 구성할 수 있습니다. .prettierrc를 밖에 꺼내놔도 좋지만, 같이 내장하고 있는 모습이 더 관리하기 편하네요.

// .eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
  ],
  plugins: ['prettier', '@typescript-eslint'],
  rules: {
    'prettier/prettier': [
      'error',
      {
        singleQuote: true,
        semi: true,
        useTabs: false,
        tabWidth: 2,
        printWidth: 80,
        bracketSpacing: true,
        arrowParens: 'avoid',
      },
    ],
  },
  parserOptions: {
    parser: '@typescript-eslint/parser',
  },
};

 

graphQL 세팅

 

yarn add graphql 
yarn add express-graphql
yarn add graphql-tools

// @types/graphql은 deprecated되었습니다. 자체적으로 d.ts를 제공합니다

 

graphql-tools를 활용하여 graphql와 resolvers를 하나로 몰아버리자.

import { GraphQLSchema } from "graphql";
import { makeExecutableSchema } from "graphql-tools";
import { mergeTypeDefs, mergeResolvers } from "@graphql-tools/merge";
import { loadFilesSync } from "@graphql-tools/load-files";
import path from "path";

const allTypes: GraphQLSchema[] = loadFilesSync(path.join(__dirname, "./api/**/*.graphql"));

const allResolvers = loadFilesSync(
  path.join(__dirname, "./api/**/*.resolvers.*") // 배포시에 ts는 js로 변환되므로 확장자는 *로
);

const mergedTypes = mergeTypeDefs(allTypes);
const mergedResolvers = mergeResolvers(allResolvers);

const schema = makeExecutableSchema({ typeDefs: mergedTypes, resolvers: mergedResolvers });

export default schema;

 

 

graphql.org/code/#javascript

 

GraphQL: A query language for APIs.

GraphQL provides a complete description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

graphql.org

 

공식문서가 말하는대로 찹찹 구성해줍시다.

import { graphqlHTTP } from "express-graphql";
import schema from "./schema";

// router
app.use(
  "/graphql",
  graphqlHTTP({
    schema: schema,
    graphiql: true,
  })
);

 

graphql 경로로 접속하보면 성공적으로 graphql이 구성된 것을 확인할 수 있습니다.

 

 

그런데 저는 playground가 더 친숙하고 좋습니다. playground를 부착해봅시다.

 

github.com/graphql/graphql-playground

 

graphql/graphql-playground

🎮 GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration) - graphql/graphql-playground

github.com

 

현재 express를 사용 중이므로 graphql-playground-express를 사용하면 되겠군요.

www.npmjs.com/package/graphql-playground-middleware-express

 

설치 후 다음과 같이 구성합시다.

yarn add graphql-playground-middleware-express

 

import expressPlayground from "graphql-playground-middleware-express";

app.use(
  "/graphql",
  graphqlHTTP({
    schema: schema,
    graphiql: true,
  })
);

app.get("/playground", expressPlayground({ endpoint: "/graphql" }));

 

구성된 것을 확인할 수 있습니다.

 

 

 

 

 

 

참고하면 좋은 글)

 

https://novemberde.github.io/node/2017/10/22/Express-Typescript.html

https://github.com/Microsoft/TypeScript-Node-Starter

https://velog.io/@jhj46456/Node-with-Ts-simple-express

velog.io/@das01063/VSCode%EC%97%90%EC%84%9C-ESLint%EC%99%80-Prettier-TypeScript-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0#3-2-eslintrcjson-%ED%8C%8C%EC%9D%BC-%EC%84%A4%EC%A0%95


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체