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.exports
는 Module
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 = linksController
로 exports
객체에 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
가 빈객체이고, 이것을 재할당하거나 프로퍼티를 추가할 수 있다는 것을 배웠다.