본문 바로가기
리액트(React)

esm으로 ES 모듈 import/export 문법 사용하기

by 즐거운코딩 2023. 7. 13.
반응형

Node.js 에서 import/export 문법을 사용하면 VS Code에서 자동완성을 통해 모듈을 자동으로 불러 올 수 있고 코드도 깔끔해 지기 때문에 esm 라이브러리를 사용하여 해당 문법을 사용합니다.

 

esm을 yarn 으로 설치합니다.

$ yarn add esm

 

기존 src/index.js 파일의 이름을 main.js 로 변경하고, index.js 파일을 새로 만들어서 다음의 코드를 작성합니다.

// 이 파일에서만 no-global-assign ESLint 옵션을 비활성화 합니다.
/* eslint-disable no-global-assign */

require = require('esm')(module /*, options*/);
module.exports = require('./main.js');

다음으로 package.json 에서 만들었던 스크립트를 다음과 같이 수정합니다.

 "scripts": {
    "start": "node -r esm src",
    "start:dev": "nodemon --watch src/ -r esm src/index.js"
  }

ESLint에서 import/export 구문을 사용해도 오류로 간주하지 않도록 .eslint.json 에서 sourceType 값을 "module" 로 설정합니다.

{
  "env": {
    "commonjs": true,
    "es2021": true,
    "node": true
  },
  "extends": ["eslint:recommended", "prettier"],
  "globals": {
    "Atomics": "readonly",
    "ShareArrayBuffer": "readonly"
  },
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "rules": {
    "no-unused-vars": "warn",
    "no-console": "off"
  }
}

이제 프로젝트에서 import/export 구문을 자유롭게 사용할 수 있습니다.

설정 값이 변경되었으므로 서버를 다시 시작합니다. 

$ yarn start:dev

 

기존 코드 ES Module 형태로 바꾸기

 

api/posts/posts.ctrl.js 파일에서 exports 코드를 export const 로 모두 바꿉니다.

 


/* 포스트 작성
POST /api/posts
{ title, body }
*/
export const write = (ctx) => {
  // REST API 의 Request Body는 ctx.request.body에서 조회할 수 있습니다.
  const { title, body } = ctx.request.body;
  postId += 1; // 기존 postId 값에 1을 더합니다.
  const post = { id: postId, title, body };
  posts.push(post);
  ctx.body = post;
};

/* 포스트 작성
POST /api/posts
{title, body}
*/
export const list = (ctx) => {
  ctx.body = posts;
};

/* 특정 포스트 조회
GET /api/posts/:id
*/
export const read = (ctx) => {
  const { id } = ctx.params;
  // 주어진 id 값으로 포스트를 찾습니다.
  // 파라미터로 받아 온 값은 문자열 형식이므로 파라미터를 숫자로 변환하거나
  // 비교할 p.id 값을 문자열로 변경해야 합니다.
  const post = posts.find((p) => p.id.toString() === id);
  // 포스트가 없으면 오류를 반환합니다.
  if (!post) {
    ctx.status = 404;
    ctx.body = {
      message: '포스트가 존재하지 않습니다.',
    };
    return;
  }
  ctx.body = post;
};

/* 특정 포스트 제거
DELETE /api/posts/:id
*/
export const remove = (ctx) => {
  const { id } = ctx.params;
  // 해당 id를 가진 post가 몇 번째인지 확인합니다.
  const index = posts.findIndex((p) => p.id.toString() === id);
  // 포스트가 없으면 오류를 반환합니다.
  if (index === -1) {
    ctx.status = 404;
    ctx.body = {
      message: '포스트가 존재하지 않습니다.',
    };
    return;
  }
  // index번째 아이템을 제거합니다.
  posts.splice(index, 1);
  ctx.status = 204; // No content
};

/* 포스트 수정(교체)
PUT /api/posts/:id
{ title, body }
*/
export const replace = (ctx) => {
  // PUT 메서드는 전체 포스트 정보를 입력하여 데이터를 통째로 교체할 때 사용합니다.
  const { id } = ctx.params;
  // 해당 id를 가진 post가 몇번째인지 확인합니다.
  const index = posts.findIndex((p) => p.id.toString() === id);
  // 포스트가 없으면 오류를 반환합니다.
  if (index === -1) {
    ctx.status = 404;
    ctx.body = {
      message: '포스트가 존재하지 않습니다.',
    };
    return;
  }
  // 전체 객체를 덮어 씌웁니다.
  // 따라서 id를 제외한 정보를 날리고, 객체를 새로 만듭니다.
  posts[index] = {
    id,
    ...ctx.request.body,
  };
  ctx.body = posts[index];
};

/* 포스트 수정(특정 필드 변경)
PATCH /api/posts/:id
{ title, body }
*/
export const update = (ctx) => {
  // PATCH 메서드는 주어진 필드만 교체합니다.
  const { id } = ctx.params;
  // 해당 id를 가진 post가 몇번째인지 확인합니다.
  const index = posts.findIndex((p) => p.id.toString() === id);
  // 포스트가 없으면 오류를 반환합니다.
  if (index === -1) {
    ctx.status = 404;
    ctx.body = {
      message: '포스트가 존재하지 않습니다.',
    };
    return;
  }
  // 기존 값에 정보를 덮어 씌웁니다.
  posts[index] = {
    ...posts[index],
    ...ctx.request.body,
  };
  ctx.body = posts[index];
};

다음으로  const, require 로 정의하여 사용하는 대신 import ... from ..  로 모듈을 사용 하도록 다음 파일들을 수정합니다.

src/api/posts/index.js 파일

import Router from 'koa-router';
import * as postsCtrl from './posts.ctrl';

const posts = new Router();

posts.get('/', postsCtrl.list);
posts.post('/', postsCtrl.write);
posts.get('/:id', postsCtrl.read);
posts.delete('/:id', postsCtrl.remove);
posts.put('/:id', postsCtrl.replace);
posts.patch('/:id', postsCtrl.update);

export default posts;

추가로 다음 두개 파일도 다음과 같이 수정합니다.

src/api/index.js

import Router from 'koa-router';
import posts from './posts';

const api = new Router();

api.use('/posts', posts.routes());

// 라우터를 내보냅니다.
export default api;

src/main.js

require('dotenv').config();
import Koa from 'koa';
import Router from 'koa-router';
import bodyParser from 'koa-bodyparser';
import mongoose from 'mongoose';

import api from './api';

(...)

바뀐 코드가 정상적으로 수행되는지 http://localhost:4000/api/posts 에 요청을 보내 봅니다.

 

반응형