๐Ÿ’ป Programming

[ Node.js in Action ] 3์žฅ ์š”์•ฝ

3์žฅ์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.


๏‚ก Organizing your code into modules
๏‚ก Coding conventions
๏‚ก Handling one-off events with callbacks
๏‚ก Handling repeating events with event emitters
๏‚ก Implementing serial and parallel flow control
๏‚ก Leveraging flow-control tools


3.1 ๋ชจ๋“ˆ์„ ์ด์šฉํ•œ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ ๋ฐ ์ •๋ฆฌ


PHP๋‚˜ Ruby๊ฐ™์€ ์–ธ์–ด์—์„œ importํ•˜๋ฉด global scope์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค.

์ด๋Ÿฐ ๊ฒƒ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ PHP๋Š” namespaces๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , Ruby๋Š” modules๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

ํ•˜์ง€๋งŒ namespaces๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด๋„ overwrite์˜ ๊ฐ€๋Šฅ์„ฑ์„ ์™„์ „ํžˆ ๋ฐฐ์ œํ•  ์ˆ˜๋Š” ์—†๋‹ค.

Node์—์„œ๋Š” ์ด๋Ÿฐ ์œ„ํ—˜์„ ์™„์ „ํžˆ ๋ฐฐ์ œํ•œ๋‹ค.

์šฐ์„  Node์˜ module์€ gloabl scope๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋˜ํ•œ, module์„ ๋งŒ๋“ค ๋•Œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์–ด๋–ค ๊ธฐ๋Šฅ, ๋ณ€์ˆ˜๋ฅผ ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅ ํ•˜๊ฒŒ ํ• ์ง€ ์„ ํƒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ( ์ด๊ฑด ์ž๋ฐ”์—์„œ ์ ‘๊ทผ์ œํ•œ์ž, public ๋˜๋Š” private,๋ฅผ ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. )

Node์—์„œ๋Š” ์™ธ๋ถ€์— ๋…ธ์ถœ์‹œํ‚ค๋Š” ๊ฒƒ์„ exportํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. ( public์œผ๋กœ ๋งŒ๋“ ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ )

export์˜ ๋ฐฉ๋ฒ•์€ ์ฒซ์งธ, ๋‘˜ ์ด์ƒ์˜ ๊ธฐ๋Šฅ ๋ฐ ๋ณ€์ˆ˜๋ฅผ exportํ•  ๋•Œ์—๋Š” exports๊ฐ์ฒด์˜ ์†์„ฑ์„ ์„ธํŒ…ํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ๋‘˜์งธ, ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์ด๋‚˜ ๋ณ€์ˆ˜๋งŒ exportํ•  ๋•Œ์—๋Š” module.exports ์†์„ฑ์„ ์ด์šฉํ•œ๋‹ค.


3.1.1 ๋ชจ๋“ˆ ์ƒ์„ฑํ•˜๊ธฐ


๋ชจ๋“ˆ์€ a.ํ•˜๋‚˜์˜ ํŒŒ์ผ์ด๊ฑฐ๋‚˜, b.๋””๋ ‰ํ† ๋ฆฌ๋‚ด์— ํ•˜๋‚˜ ์ด์ƒ์˜ ํŒŒ์ผ๋กœ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ๋‹ค.

๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ์ผ ๊ฒฝ์šฐ์—๋Š” ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด๋ถ€์— index.jsํŒŒ์ผ์„ mainํŒŒ์ผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ( ์ด ํŒŒ์ผ ๋ช…์€ overridden ๊ฐ€๋Šฅํ•˜๋‹ค. )


ํ•˜๋‚˜์˜ ํŒŒ์ผ์„ ๋ชจ๋“ˆ๋กœ ๋งŒ๋“ค ๋•Œ์—๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ์ •์˜ํ•œ๋‹ค.

--------------- convert.js -------------

var num = 0.5;

exports.convertNum = function(myNum) {
     return Math.round(myNum / num);
}

----------------------------------------

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด exports์˜ ์†์„ฑ์œผ๋กœ convertNum ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ–ˆ๋‹ค. ์ด๋Š” ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ public ํ•จ์ˆ˜์ด๋‹ค. ํ•˜์ง€๋งŒ num ๋ณ€์ˆ˜๋Š” exports์†์„ฑ์œผ๋กœ ์ •์˜ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ convert.jsํŒŒ์ผ ๋‚ด์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ private ๋ณ€์ˆ˜์ด๋‹ค.


์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ๋ชจ๋“ˆ์„ test-convert.js ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ํ•  ์ˆ˜ ์žˆ๋‹ค.


--------------- test-convert.js -------------

var convert = require('./convert');

console.log(convert.convertNum(5));

-----------------------------------------

์—ฌ๊ธฐ์„œ require()์— ๋ช…์‹œํ•œ "./convert"๋Š” ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์˜ convert.jsํŒŒ์ผ์„ importํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. "./"๋ฅผ ๋ถ™์ด์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋‚œ๋‹ค. requireํ•  ๋•Œ core module์— ๋Œ€ํ•ด์„œ๋Š” ์ƒ๋Œ€๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋ชจ๋“ˆ๋ช…๋งŒ ๋ช…์‹œํ•˜๋„๋ก ๋˜์–ด์žˆ๋Š”๋ฐ convert.js๋Š” core module์ด ์•„๋‹ˆ๋ผ ๋ฐฉ๊ธˆ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  module์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

require()๋Š” convert.js์— ๋ช…์‹œํ•œ exports์˜ ์†์„ฑ์„ returnํ•œ๋‹ค. ๋”ฐ๋ผ์„œ var convert์—๋Š” convert.js(๋ชจ๋“ˆ)์—์„œ ์ •์˜ํ•œ exports ๊ฐ์ฒด์˜ ๋‚ด์šฉ,์ฆ‰, convertNum ํ•จ์ˆ˜๊ฐ€ ํ• ๋‹น๋˜์—ˆ๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค. 


3.1.2 module.exports ์‚ฌ์šฉํ•˜๊ธฐ ( single ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ๊ฐ์ฒด export ์‹œ ์‚ฌ์šฉ ) 


module์„ ๊ฐ์ฒด์ง€ํ–ฅ ๊ด€์ ์—์„œ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•  ๋•Œ์—๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ returnํ•˜๋„๋ก ํ•œ ๋’ค ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ์ด๋‹ค.


---------------- convert.js --------------

var Convert = function (num){

     this.num = num;

}

Convert.prototype.convertNum = function(myNum) {
     return Math.round(myNum / num);
}

// exports = Convert; ( ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉ ๊ธˆ์ง€ )

module.exports = Convert; 

---------------------------------------

------------- test-convert2.js ------------

var Convert = require('./convert');

var num = 0.5

var convert = new Convert(num);

console.log(convert.convertNum(5));

---------------------------------------

์œ„ ์ฝ”๋“œ์—์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ module.exports = Convert; ๋ผ์ธ์ด๋‹ค.


์ฒซ ์˜ˆ์ œ์—์„œ exports๋ฅผ ์ด์šฉํ•ด์„œ property๊ฐ’์„ ์„ค์ •ํ•จ์œผ๋กœ์จ convert๋ชจ๋“ˆ์—์„œ ์ •์˜ํ•œ convertNum() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด๋Š” exports๊ฐ€ module.exports๋ฅผ ์ฐธ์กฐํ•˜๋Š” global๋ณ€์ˆ˜์˜€๊ธฐ์— ๊ฐ€๋Šฅํ–ˆ๋‹ค. ๋”ฐ๋ผ์„œ exports = Convert; ๋ผ๊ณ  ํ•ด๋ฒ„๋ฆฌ๋ฉด exports๋Š” ๋”์ด์ƒ module.exports๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹Œ๊ฒƒ์ด ๋œ๋‹ค. 


3.1.3 node_modules ๋””๋ ‰ํ† ๋ฆฌ


์•ž์—์„œ module์„ requireํ•  ๋•Œ core module์ด ์•„๋‹ˆ๋ฉด ์ƒ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ์ ์–ด์ฃผ๊ณ , core module์ด๋ฉด ๊ทธ๋ƒฅ ์ด๋ฆ„์„ ์จ๋„ ๋œ๋‹ค๊ณ  ํ–ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ค ๋กœ์ง์„ ํƒ€๊ธธ๋ž˜ core module์€ ์ด๋ฆ„๋งŒ ์ ์–ด๋„ ๋˜๋Š” ๊ฑธ๊นŒ? Node๊ฐ€ module์„ ์ฐพ๋Š” ๋กœ์ง์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.



 

์ž, ๊ทธ๋Ÿผ ๋‚ด๊ฐ€ ๋งŒ๋“  ๋ชจ๋“ˆ์„ ์ƒ๋Œ€๊ฒฝ๋กœ ์ง€์ •์„ ํ•˜์ง€ ์•Š๊ณ  ์“ฐ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋ ๊นŒ?

๊ทธ๋ƒฅ node_modules ์•ˆ์— ๋„ฃ์–ด๋ฒ„๋ฆฌ๋ฉด ๋œ๋‹ค. ์‹ค์ œ๋กœ npm(Node Package Manager)๋ฅผ ์ด์šฉํ•˜์—ฌ install์„ ํ•˜๋ฉด node_modules ๋””๋ ‰ํ† ๋ฆฌ์— ์„ค์น˜๊ฐ€ ๋œ๋‹ค.


3.1.4 ์ฃผ์˜์‚ฌํ•ญ

์ฒซ๋ฒˆ์งธ ์ฃผ์˜์‚ฌํ•ญ์€ ๋””๋ ‰ํ† ๋ฆฌ module ์‚ฌ์šฉ์ƒ ์ฃผ์˜์‚ฌํ•ญ์ด๋‹ค.

๋””๋ ‰ํ† ๋ฆฌ ๋ฌถ์Œ์œผ๋กœ module์„ ๋งŒ๋“ค์—ˆ์„ ๋•Œ์—๋Š” package.json์— ๋ช…์‹œํ•˜์ง€ ์•Š๋Š”ํ•œ index.jsํŒŒ์ผ์ด ์กด์žฌํ•ด์•ผํ•œ๋‹ค.

์•„๋ž˜ ๊ทธ๋ฆผ์€ connect module์„ ์„ค์น˜ํ–ˆ์„ ๋•Œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ํŒจํ‚ค์ง€ ํŠธ๋ฆฌ์ด๋‹ค.


connect ๋””๋ ‰ํ† ๋ฆฌ ์•ˆ์— index.js๋ผ๋Š” ํŒŒ์ผ์ด ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. 

์ด์ œ ์ด ํŒŒ์ผ๋ช…์„ index.js ๊ฐ€ ์•„๋‹Œ index_2.js ๋กœ ๋ฐ”๊ฟ”๋ณด์ž.

๊ทธ๋ฆฌ๊ณ  ํ…Œ์ŠคํŠธ ํ”„๋กœ๊ทธ๋žจ์„ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์„œ require('connect'); ํ•œ ์ค„๋งŒ ์ž…๋ ฅํ•ด๋ณด๊ณ  ์‹คํ–‰ํ•ด๋ณด์ž. 

๊ทธ๋Ÿผ ์˜ค๋ฅ˜๊ฐ€ ๋‚  ๊ฒƒ์ด๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ์˜ module์—์„œ๋Š” index.js ๋ผ๋Š” ํŒŒ์ผ๋ช…์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๊ตณ์ด ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด package.json ํŒŒ์ผ์— ๋ช…์‹œํ•ด์ฃผ๋ฉด ๋œ๋‹ค.


package.json ํŒŒ์ผ์„ ์—ด์–ด์„œ "main" ์„ ์ฐพ์•„๋ณด์ž. ์•„๋งˆ ์—†์„ ๊ฒƒ์ด๋‹ค. ์•„๋ž˜์ฒ˜๋Ÿผ main์†์„ฑ์„ ๋„ฃ์–ด๋ณด์ž.

{  // package.json 1๋ฒˆ์งธ ๋ผ์ธ

"main":"index_2.js"

--์ƒ๋žต--

} // package.json ๋งˆ์ง€๋ง‰ ๋ผ์ธ


์ด์ œ ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋ณด๋ฉด ์—๋Ÿฌ์—†์ด ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ( core module์ด๋‹ˆ ํŒŒ์ผ๋ช…์€ ๋‹ค์‹œ index.js๋กœ ๋ฐ”๊ฟ”์ฃผ์ž. Now~~ )


์ฐธ๊ณ ๋กœ ์•„๋ž˜ ๊ทธ๋ฆผ์€ directory ํ˜•ํƒœ์˜ module์„ requireํ–ˆ์„ ๋•Œ ์ฒ˜๋ฆฌ๋˜๋Š” ๋กœ์ง์ด๋‹ค.



๋‘ ๋ฒˆ์งธ ์ฃผ์˜์‚ฌํ•ญ์€ "monkey patching"์ด๋‹ค. ์›์ˆญ์ด ํŒจ์น˜? ์ด๋ฆ„์ด ์ฐธ ํฌํ•œํ•˜๋‹ค.

monkey patching์€ module์„ ๊ฐ์ฒด๋กœ cachingํ•˜๋Š” Node์˜ ๋Šฅ๋ ฅ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•œ ๊ฒƒ์œผ๋กœ, ๋งŒ์•ฝ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ํŒŒ์ผ์ด ํ•˜๋‚˜์˜ module์„ requireํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์ด ๋•Œ ๋™์ผํ•œ module์„ ๋‘ ๋ฒˆ requireํ–ˆ๋‹ค๊ณ ํ•ด์„œ moduleํŒŒ์ผ์„ ๋‘ ๋ฒˆ ์ฝ์–ด๋“ค์ผ ํ•„์š”๊ฐ€ ์—†๋„๋ก Node์—์„œ ์บ์‹œ์— ๋„ฃ์–ด๋‘”๋‹ค. ํ•˜์ง€๋งŒ, ์ด ๋‘๋ฒˆ ์งธ require์—์„œ ์ด ์บ์‹œ์— ๋“ค์–ด์žˆ๋Š” module์ •๋ณด๋ฅผ ๋ณ€๊ฒฝ(alter)ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค. ์ด๋ ‡๊ฒŒ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ monkey patching์ด๋ผ๊ณ  ํ•˜๋Š”๋ฐ, ์ด๊ฒƒ์„ ์ž˜ ์ด์šฉํ•˜๋ฉด module์ด ๋‹ค๋ฅธ module์˜ ๋™์ž‘(behavior)๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์„ ๋ฟ ์•„๋‹ˆ๋ผ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋‹ค๋ฅธ ๋ฒ„์ „์˜ module์„ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋„๋ก ํ•ด์ค€๋‹ค. ( ์ด๊ฑด ๋™์  BCI๋ผ๊ณ  ์ดํ•ดํ–ˆ๋‹ค. )


3.2 ๋น„๋™๊ธฐ์‹ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ…Œํฌ๋‹‰


3.2.1 Callbackํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ one-off ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง


var fs = require('fs');
fs.readFile('./blah.txt', function(err, data) {
     if (err) { throw err };
     // do something
});


3.2.2 EventEmitter๋ฅผ ์ด์šฉํ•œ ๋ฐ˜๋ณต ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง 


var net = require('net');
var server = net.createServer(function(socket) {
     socket.on('data', function(data) {
          socket.write(data);
     });
});
server.listen(8080);


1ํšŒ์„ฑ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ์‹œ once ์‚ฌ์šฉ.


var net = require('net');
var server = net.createServer(function(socket) {
     socket.once ('data', function(data) {
          socket.write(data);
     });
});
server.listen(8080);


EventEmitter ํ™•์žฅํ•˜๊ธฐ


function Watcher(watchDir, processedDir) {
     this.watchDir = watchDir;
     this.processedDir = processedDir;
}

var events = require('events'), util = require('util');
util.inherits(Watcher, events.EventEmitter);     // == Watcher.prototype = new events.EventEmitter();


var fs = require('fs'), watchDir = './watch', processedDir = './done';
Watcher.prototype.watch = function() {
     var watcher = this;
     fs.readdir(this.watchDir, function(err, files) {
          if (err) throw err;
          for(var index in files) {
               watcher.emit('process', files[index]);
          }
     })
}
Watcher.prototype.start = function() {
     var watcher = this;
     fs.watchFile(watchDir, function() {
          watcher.watch();
     });
}

var watcher = new Watcher(watchDir, processedDir);


watcher.on('process', function process(file) {
     var watchFile = this.watchDir + '/' + file;
     var processedFile = this.processedDir + '/' + file.toLowerCase();
     fs.rename(watchFile, processedFile, function(err) {
          if (err) throw err;
     });
});


watcher.start();



3.2.3 ๋น„๋™๊ธฐ์‹ ์–ดํ”Œ ๊ฐœ๋ฐœ์‹œ ์ฃผ์˜ํ•  ์ 


๋™๊ธฐ์‹์—์„œ๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์‹คํ–‰ ์ˆœ์„œ๊ฐ€ ๋ช…ํ™•ํ•˜์ง€๋งŒ ๋น„๋™๊ธฐ์‹์—์„œ๋Š” ์‹คํ–‰ ์ˆœ์„œ๊ฐ€ ๋ช…ํ™•ํ•˜์ง€ ์•Š๋‹ค. 

Node์˜ event loop๋Š” ๋น„๋™๊ธฐ ๋กœ์ง์ด ์™„์ „ํžˆ ์™„๋ฃŒ๋˜์—ˆ๋Š”์ง€ ์ถ”์ ์„ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ฌด๋ฆฌ ๋น„๋™๊ธฐ ๋กœ์ง์ด๋ผ๋„ ์™„์ „ํžˆ ๋๋‚˜์ง€ ์•Š์•˜๋‹ค๋ฉด ํ”„๋กœ์„ธ์Šค๋Š” ์ข…๋ฃŒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


[ Javascript ์˜ Closure์— ๋Œ€ํ•œ ๊ฐœ๋… ๋งํฌ ]



3.3 ๋น„๋™๊ธฐ์‹ ๋กœ์ง์„ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ


Nimble ์„ ์ด์šฉํ•œ sequencing ์ฒ˜๋ฆฌ

Nimble ์ด์™ธ์—๋„ Step, Seq์™€ ๊ฐ™์€ module์ด ์ด๋ฏธ ์กด์žฌํ•จ. ๊ฐ€์ ธ๋‹ค ์“ฐ๋ฉด ๋จ.





[[๊ถ๊ธˆ์ฆ ๋“ค.....]]

1. ์˜์กด์„ฑ๋ชจ๋“ˆ package.json ํŒŒ์ผ๋ช…์„ ๋‹ค๋ฅธ๊ฑธ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‚˜??

npmjs.com์—์„œ ๋งํ•˜๋Š” npm์—์„œ ๋งํ•˜๋Š” package๋ผ ํ•จ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.


A package is any of:

  • a) a folder containing a program described by a package.json file
  • b) a gzipped tarball containing (a)
  • c) a url that resolves to (b)
  • d) a <name>@<version> that is published on the registry with (c)
  • e) a <name>@<tag> that points to (d)
  • f) a <name> that has a latest tag satisfying (e)
  • g) a git url that, when cloned, results in (a).

๋˜ํ•œ module์ด๋ผ ํ•จ์€


  • A folder with a package.json file containing a main field.
  • A folder with an index.js file in it.
  • A JavaScript file.

๋กœ ์ •์˜๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

๋”ฐ๋ผ์„œ, package.json ํŒŒ์ผ์„ ๋‹ค๋ฅธ ํŒŒ์ผ๋ช…์œผ๋กœ ์‚ฌ์šฉํ•œ ๋‹ค๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.


์ถœ์ฒ˜ : https://docs.npmjs.com/how-npm-works/packages


2. ์ด๋ฒคํŠธ ๋ฃจํ”„ = ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ????, ๋น„๋™๊ธฐ์™€ ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ์˜ ์ฐจ์ด์ ??

์ด๋ฒคํŠธ ๋ฃจํ”„๋Š” ๊ฒฐ๊ตญ ๋ฉ€ํ‹ฐ์“ฐ๋ ˆ๋“œ, ํด๋ง๊ณผ ๊ฐ™์€ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋ผ๋Š” ๊ฒฐ๋ก ์ž…๋‹ˆ๋‹ค. 

์•„๋ž˜๋Š” ์ฐธ์กฐํ•  ๋งŒํ•œ ๋งํฌ๋“ค์ž…๋‹ˆ๋‹ค.


http://jeremyko.blogspot.kr/2012/12/nodejs-thread-poollibuv.html    ( ํ•œ๊ธ€ ๋ธ”๋กœ๊ทธ )


http://nikhilm.github.io/uvbook/basics.html#event-loops


http://stackoverflow.com/questions/21485920/single-threaded-event-loop-vs-multi-threaded-non-blocking-worker-in-node-js



3. monkey patching - ์™œ ์ฒซ ๋ฒˆ์งธ requireํ•  ๋•Œ ์ˆ˜์ •๊ฐ€๋ŠฅX ?

์ด๊ฑด ์‚ฌ์‹ค ์งˆ๋ฌธ ์ž์ฒด๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. monkey patching์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜ ๋งํฌ์— ์„ค๋ช…์ด ๋‚˜์™€์žˆ๋‹ค.


http://fredkschott.com/post/2014/09/nodejs-dangerous-module-design-patterns/


๊ฒฐ๊ตญ monkey patching ์ด๋ผ๋Š” ๊ฒƒ์€ ๊ธฐ์กด์— ์žˆ๋˜ ๊ฒƒ์„ overwriteํ•œ๋‹ค๋Š” ๊ฒƒ์ธ๋ฐ require๋ฅผ ์ฒ˜์Œ ํ•  ๋•Œ์—๋Š” overwriteํ•  ๊ฒŒ ์—†์œผ๋‹ˆ๊นŒ ๋™์ผํ•œ ๋ชจ๋“ˆ์„ ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ๋˜ require ํ•  ๋•Œ์— ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๋ฅผ ์ค€๋‹ค๊ณ  ์ฑ…์—์„œ ์„ค๋ช…์„ ํ•œ ๊ฒƒ ๊ฐ™๋‹ค. ์ด "์›์ˆญ์ด ํŒจ์น˜"์— ๋Œ€ํ•ด์„œ๋Š” ์ฑ…์—์„œ ์ž์„ธํ•˜๊ฒŒ ์„ค๋ช…์„ ์•ˆํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์œ„ ๋งํฌ์—์„œ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์„ ๋ณด๋ฉด ๊ทธ ์œ„ํ—˜์„ฑ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿฐ๊ฒŒ ์•„๋‹Œ๊ฐ€ ์‹ถ๋‹ค. ๊ฐ€๋…์„ฑ๋„ ๋–จ์–ด์งˆ ๊ฒƒ ๊ฐ™๊ณ ..