프로그래밍에서 모듈(Module)이라함은 외부에 영향을 받지 않는 독립된, 재사용 가능한 코드들의 묶음입니다.
이는 OOP의 Encapsulation과 동일한 개념입니다.
모듈로 API를 묶어줌에 변수나 함수들의 name space를 보장해주고, 모듈화를 통한 기능적인 코딩이 가능해집니다.
require()
// app.js
require('./some.js');
NodeJS에서는 require 메서드를 통해 외부 모듈을 가져올 수 있습니다. require 메서드는 node가 local object에 추가한 메서드로서 다음과 같이 파라미터로 추가할 모듈의 파일 경로값을 받습니다.
이때, some.js가 app.js와 같은 폴더에 있다면 경로값의 시작은 ./ 이 됩니다.
만일 ./를 해주지 않는다면 NodeJS 자체 라이브러리에서 모듈을 찾게 됩니다.
해당 모듈의 API에 접근할 권한이 바로 생기지는 않습니다.
밖으로 내보낼 API들을 module.exports의 object에 정의하는 절차를 거쳐야 합니다.
module.exports
// some.js
var greet = function() {
console.log('Greetings from some.js!');
};
// module.exports에 외부에 공유할 API 대입하기
module.exports = greet
// app.js
var greetFromSomeJS = require('./some.js');
greetFromSomeJS();
//즉시 실행 함수 표현(IIFE)로
여러 모듈 가져오기
// index.js
var english = require('./english');
var korean = require('./korean');
module.exports = {
english: english,
korean: korean
};
// app.js
var greet = require('./greet');
greet.english();
greet.korean();
모듈로 class export 하기
// Assigning to exports will not modify module, must use module.exports
module.exports = class Square {
constructor(width) {
this.width = width;
}
area() {
return this.width ** 2;
}
};
템플릿 모듈화하기
//text-field.template.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var template = "\n <div id=\"field-{{id}}\" class=\"mt-4\">\n <div class=\"flex items-start mb-1\">\n <span class=\"flex items-center\">\n <svg class=\"flex-shrink-0 h-5 w-5 {{#if valid}}{{#if updated}}text-green-500{{else}}text-gray-200{{/if}}{{else}}text-gray-200{{/if}}\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\" />\n </svg>\n </span>\n <label class=\"block text-sm\" for=\"name\">{{label}}</label>\n </div>\n <input id=\"{{id}}\" name=\"{{id}}\" type=\"{{type}}\" value=\"{{text}}\" {{#if require}}required{{/if}} \n placeholder=\"{{placeholder}}\" aria-label=\"Name\" class=\"w-full px-5 py-1 text-gray-700 {{#if valid}}bg-gray-200{{else}}bg-red-200{{/if}} rounded\">\n {{#unless valid}}\n <div class=\"flex items-start mb-1\">\n <label class=\"block text-sm text-red-300\" for=\"cus_email\">{{validateMessage}}</label>\n </div>\n {{/unless}}\n </div>\n";
exports.default = window.Handlebars.compile(template);
//# sourceMappingURL=text-field.template.js.map
text-field.js
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var utils_1 = require("../utils");
var text_field_template_1 = require("./text-field.template");
var constant_1 = require("../constant");
var DefaultProps = {
id: '',
text: '',
label: 'label',
type: 'text',
placeholder: '',
require: false,
};
var TextField = /** @class */ (function () {
function TextField(container, data) {
var _this = this;
this.template = text_field_template_1.default;
this.updated = false;
this.validateRules = [];
this.validate = function () {
var target = _this.data.text ? _this.data.text.trim() : '';
var invalidateRules = _this.validateRules
.filter(function (validateRule) { return validateRule.rule.test(target) !== validateRule.match; });
return (invalidateRules.length > 0) ? invalidateRules[0] : null;
};
this.buildData = function () {
var isInvalid = _this.validate();
if (_this.updated) {
return __assign(__assign({}, _this.data), { updated: _this.updated, valid: !isInvalid, validateMessage: !!isInvalid ? isInvalid.message : '' });
}
else {
return __assign(__assign({}, _this.data), { updated: _this.updated, valid: true, validateMessage: '' });
}
};
this.onChange = function (e) {
var _a = e.target, value = _a.value, id = _a.id;
if (id === _this.data.id) {
_this.updated = true;
_this.data.text = value;
_this.update();
}
};
this.attachEventHandler = function () {
var _a;
(_a = document.querySelector(_this.container)) === null || _a === void 0 ? void 0 : _a.addEventListener('change', _this.onChange);
};
this.update = function () {
var container = document.querySelector("#field-" + _this.data.id);
var docFrag = document.createElement('div');
docFrag.innerHTML = _this.template(_this.buildData());
container.innerHTML = docFrag.children[0].innerHTML;
};
this.addValidateRule = function (rule) {
_this.validateRules.push(rule);
};
this.render = function (append) {
if (append === void 0) { append = false; }
var container = document.querySelector(_this.container);
if (append) {
var divFragment = document.createElement('div');
divFragment.innerHTML = _this.template(_this.buildData());
container.appendChild(divFragment.children[0]);
}
else {
container.innerHTML = _this.template(_this.buildData());
}
};
this.container = container;
this.data = __assign(__assign({}, DefaultProps), data);
if (this.data.require) {
this.addValidateRule(constant_1.RequireRule);
}
utils_1.nextTick(this.attachEventHandler);
}
Object.defineProperty(TextField.prototype, "name", {
get: function () {
return this.data.id;
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "value", {
get: function () {
return this.data.text || '';
},
enumerable: false,
configurable: true
});
Object.defineProperty(TextField.prototype, "isValid", {
get: function () {
return !this.validate();
},
enumerable: false,
configurable: true
});
return TextField;
}());
exports.default = TextField;
//# sourceMappingURL=text-field.js.map
https://m.blog.naver.com/jdub7138/221022257248
[NodeJS] require()와 module.exports
모듈이란?프로그래밍에서 모듈(Module)이라함은 외부에 영향을 받지 않는 독립된, 재사용 가능한 코드들의...
blog.naver.com
댓글