require와 exports

Creating the dots·2021년 9월 2일
0

Node js

목록 보기
2/3

require (id)

  • id: <string> module name or path
  • Returns: <any> exported module content
//파일이 저장된 현재 혹은 폴더이름을 상대경로로 접근해서 로컬 모듈 import   
const myLocalModule - require('./path/myLocalModule');

//JSON 파일 import
const jsonData = require('./path/filename.json');

//node-modules 또는 node.js 내장 모듈 import
const crypto = require('crypto');

https://nodejs.org/api/modules.html#modules_require_id

require (dirname)

폴더를 require하면, models 폴더 안의 index.js 파일에서 module.exports하는 객체를 가져오게 된다.

그 동안 require의 인자로는 상대경로/파일명 또는 모듈이름 등을 썼다. 그런데, shortly-mvc 스프린트를 하면서 폴더(models)를 require 해오는 다음과 같은 상황을 보고 어려움을 겪었다.

파일 구조는 다음과 같다
models > index.js, urls.js, users.js
controllers > links > index.js

//models > index.js
//이하 생략
module.exports = db;
//controllers > links > index.js
const { url } = require('../../models');

require('../../models')는 폴더를 require하고 있으므로 models 폴더안의 index.js파일에서 module.exports하는 객체인 db를 가져온다.

이때 db라는 객체는 url, user를 키로 갖고 각각의 model이 키값으로 저장되어있으므로 { url }과 같이 객체를 구조분해 할당하여 사용할 수 있다.

module.exports = 변수이름

exports 객체(빈객체)에 재할당하기

공식문서에 따르면, module.exportsModule system으로 생성된 object이다. module이라는 객체에는 exports라는 프로퍼티가 있고, 빈 객체를 키값으로 갖는다.

그리고 우리는 a.js라는 파일에서 생성한 내용(변수,객체,함수 등)을 exports 프로퍼티에 할당해주고, b.js라는 파일에서 불러와서(require) 사용할 수 있다.

//controllers/links/index.js
const linksController = {
  get: async (req, res) => {
    if (!req.params.id) {
      const allUrls = await url.findAll();
      res.status(200).json(allUrls);
    }
    else {
      const existingUrl = await url.findOne({ where: { id: req.params.id } });   
      url.update(
        { visits: existingUrl.visits + 1 },
        { where: { id: req.params.id } }
      );
      res.redirect(existingUrl.url);
    }
  },
  //이하생략
};
module.exports = linksController;

//routes/links.js
const express = require("express");
const linksController = require("../controllers/links");
const router = express.Router();

/* GET links listing. */
router.get("/", linksController.get);
router.get("/:id", linksController.get);
router.post("/", linksController.post);
module.exports = router;

module.exports = linksControllerexports객체에 linksController가 할당되었다.

다른 파일routes/links.js에서 require해왔고, linksController에는 객체가 담겨있는 상태이다.

따라서 linksController내의 함수를 사용하기 위해 linksController.get, linksController.post로 접근하고 있음을 확인할 수 있다.

exports.함수명 = 함수

exports 객체에 프로퍼티 추가하기

//moduels/utils.js
const request = require("request");
const rValidUrl =
  /^(?!mailto:)(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/[^\s]*)?$/i;

exports.getUrlTitle = (url, cb) => {
  request(url, function (err, res, html) {
    if (err) {
      console.log("Error reading url heading: ", err);
      return cb(err);
    } else {
      const tag = /<title>(.*)<\/title>/;
      const match = html.match(tag);
      console.log(match.length);
      const title = match ? match[1] : url;
      return cb(err, title);
    }
  });
};

exports.isValidUrl = (url) => {
  return url.match(rValidUrl);
};

//controllers/links/index.js
const { getUrlTitle } = require("../../modules/utils");

exports.getUrlTitle=함수, exports.isValidURl=함수와 같이 작성하면, exports객체는 다음과 같아진다.

exports = {
  getUrlTitle: //함수,
  isValidUrl: //함수
} 

따라서 controllers/links/index.js에서 exports객체를 구조분해할당하여 getUrlTitle함수를 가져오는 것을 확인할 수 있다.

배운 내용

그동안은 exports와 modules를 잘 이해하지 못한채 사용하기만 했는데, 이번 shortly 스프린트를 하면서 정리해볼 수 있었다.
특히 require(폴더명)을 한 경우, index.js파일에서 export하는 객체를 가져온다는 것과, exports가 빈객체이고, 이것을 재할당하거나 프로퍼티를 추가할 수 있다는 것을 배웠다.

profile
어제보다 나은 오늘을 만드는 중

0개의 댓글