공부/컴퓨터
Do it! Node.js 프로그래밍 - 실제 서버로 구동 가능한 코드로 배운다.
찬
2018. 7. 17. 22:34
반응형
정재곤 저 |
책 읽기
- 책 자체는 크기도 크고 두껍기도 하다. 하지만 안의 글자 크기가 작아서 많은 양의 정보가 담겨 있다. 아마도 책을 좀 작게 만들었거나, 읽기 쉽도록 글자를 좀 크게 했으면, 소위 "바이블"이라고 불리는 책 두께가 되었을듯...
- 책 초반에는 아주 작은 정보까지 책에 나오고는 있으나, 그 작은 정보들을 아주 간단한 설명으로 퉁쳐 버리거나 설명하지 않은 부분에 대해서도 많은 단어들을 등장 시킨다.
- 예를 들면 18 페이지의 작은 "주의" 박스에서는 "세션"이나 "쿠기"등의 단어를 사용하는데. 여기에 대한 설명은 없다. 그 전에는 "용어"칸을 통해서 조금 어렵다고 생각되는 단어들을 모두 설명하고 있는데 말이다.
- 초보자들을 위한 책이라서, 세세한 설명이 달려 있는거 치고는, 설명이 부족하다. 그렇다고 설명이 안 달려 있는것도 아니니.
- 만약 초보자가 해당 책을 읽는다면, 잘 모르는 단어가 나왔을때는 그냥 과감히 무시하고 넘어 가는것이 좋겠다. 설명 자체는 세세하게 잘 되어 있으니, 모르는 단어들은 아마도 책 뒷 부분에 설명이 나올듯 하다.
이것저것
읽으면서 정리하기
31페이지
- 31페이지에 보면,
이런 문제를 해결하기 위해서 만든게 노드입니다
라는 말이 있는데, 이 설명은 좀 이상하다고 생각된다. 노드의 특성이 비동기 입출력이지, 비동기 입출력을 위해서 노드를 만들었다고 적혀 있으니 말이다. 뭐.. 내가 모르는 무언가가 있는건가?
78 페이지
- basename()에 대한 설명으로
파일 패스에서 파일의 확장자를 제외한 이름을 반환합니다.
라고 되어 있는데 잘못된 설명이다. 기본적으로 basename은 파일의 반환하는 함수이고, 두번째 인자에 따라서 확장자를 제거해 주던지 아니면, 그대로 두던지 한다. 심지어 80페이지의 실제 출력 결과물에서도 확장자가 제거 되지 않고nodepad.exe
가 출력 된다.
84 페이지
그리고 문자열은 큰 따옴표(" ") 또는 작은 따옴표(' ')를 사용하여 표기합니다.
라고 되어 있다. 이쪽 세상에서는 큰 따옴표보다는 작은 따옴표를 훨씬 더 많이 쓴다. 이 책에서 나오는 예제들도 대부분(?) 작은 따옴표를 사용하고 있다.
94 페이지 ~ 96 페이지
- 94 페이지부터 96페이지까지 있는, push, pop, shift, unshift 관련 예제들은 의도를 제대로 표현하지 못한다. 이 함수들은 배열에 어느곳을 기준으로 아이템을 추가/삭제하는지가 중요한데, 예제에서는 단순히 배열의 count 만 하고 있다. 정확하게 동작하는지 확인해 보려면, 최소한 push, pop, unshift 를 사용하기 직전과, 사용한 직후에
console.dir(Users);
라도 있어야 확인할 수 있다. - 96 페이지 이후에 나오는 delete, splice, slice 의 경우에는
console.dir(Users);
로 화면에 객체 정보를 출력해 해당 함수들이 잘 동작하는지 확인하도록 예제가 만들어져 있다.
105 페이지
- 사소하긴 하지만, 예제의 제일 아래쪽줄 바로 윗줄에
'객체의 walk(10)을 호출합니다.'
라고 되어 있는 부분에서객체의
앞에 공백이 하나 들어가야 한다. 107 페이지의 결과에서는 Person.name 과 '객체의' 라는 글자 사이에 공백이 있다.
107 페이지
- prototype에 대한 설명이 너무 퉁 쳐서 되어 있다.
메모리를 효율적으로 관리한다
라고 하기에는 내부 동작이 복잡하기 때문에 이해하고 넘어 가는 것이 좋다. 오승환님의 글 : [Javascrip] 프로토타입 이해하기 라는 글을 보면 이해하기 쉽게 잘 설명 되어 있다. 물론 초보자라면 읽어도 이해하기 어려울 수 있으니, 그 때는 그냥 패스.
109 페이지
이 작업을 쉽게 할 수 있도록 노드에서 미리 만들어둔 모듈이 url 모듈입니다.
라는 말이 있다. 실제로 url 모듈이 이러한 역할을 하지만, url 모듈에서는 "한글 도메인"을 "영문 도메인"으로 바꾸는 다른 기능들도 가지고 있다. 그러므로, 정확하게 바꾸자면노드에서 미리 만들어 둔 url 모듈을 사용하면 이 작업을 쉽게 할 수 있다.
고 되는게 정확하겠다. 맞다. 그냥 꼬투리 잡는거다. ㅋㅋ.
119 페이지, 120 페이지
readFile(filename, [encoding], [callback])
이라고 되어 있는데, 정확한 스펙은readFile(filename, [options], callback)
이다.options
에는encoding
을 적을 수 있기 때문에 그 부분은 적당히 맞다고해도, callback은 반드시 필요한데,[callback]
으로 표시해서 마치 생략할 수 있는 것 처럼 표기 했다. 그러므로 수정되어야 한다.writeFile
,open
,read
,write
,close
모두 callback을 생략해서는 안된다.
127 페이지
- 주의 상자에
기존 output2.txt 파일을 삭제한 후 output.txt 파일을 output2.txt 파일로 복사하는 과정이 비동기 방식으로 처리되므로 화면에 출력되는 순서는 다를 수 있습니다.
라고 되어 있는데.. 단순히 출력만 다른게 문제가 아니다. - 파일을 삭제하는
fs.unlink
역시 비동기로 동작된다. 즉, 언제 파일이 지워질지 모르는 상태에서 다음 코드인infile.pipe(outfile)
을 수행하게 된다. 이 때fs.unlink
보다infile.pipe(outfile)
이 먼저 실행 완료되면, 파일을 "복사"를 한 뒤, 파일을 "삭제"하게 되므로 복사가 제대로 되지 않을 수 있다. - 그러므로 단순이 출력만 다른 문제가 아니라, 코드 자체가 오류를 일으킬 수 있도록 되어 있다는것이 문제다.
- 제대로 수정할 것이라면,
fs.unlink
의 callback 함수 안에서 복사하는 동작을 넣어야 한다고 생각된다. - 아님 말고. ㅋ
137 페이지
server.listen(port, host, '50000', function() { ...
부분에서 좀 잘못 된 부분이 있다. 물론,'50000'
의 위치에 들어가야 하는 정보는backlog
라는 값이 되어야 하는데, API 정의상에서는 이 값이<number>
여야 한다.물론 코드를 동작시켰을때, 잘 동작할 수도 있다. javascript의 오묘한 형 변환이 있기 때문이다. ㅎ. 물론 난 실제로 코드를 동작시켜서 확인해 보지는 않았다. ㅎㅎ.
145 페이지
이 파일을 실행한 후 웹 브라우저에서 요청을 보내면 같은 결과를 볼 수 있습니다.
라고 되어 있다.같은 결과
를 볼 수 있는것이지 실제로 같은 응답을 보낸것은 아니다.pipe
를 이용해서 데이터를 바로 쏴 버리면, 현재 보내는 파일의 content-type을 보내지 않게 되므로, 웹 브라우져가 알아서 보여주는것이다.그렇기 때문에 책에서도
이 방법으로 코딩을 했을때 헤더를 설정할 수 없는 등의 제약이 생기므로 필요할 때만 사용하길 권합니다.
라고 적어 둔 것이다.헤더도 제대로 셋팅하고 파일도 전달 하고 싶다면,
infile.pipe(res);
바로 윗 줄에res.writeHead(200, {'Content-Type': 'image/png'});
를 추가해 주면 Content Type 헤더도 제대로 전달 할 수 있다.
149 페이지
- 정박사의 한마디 부분 중
GET 방식은 헤더 부분에 요청 정보들을 넣어 보내고
라는 부분이 있다. 정확하게 말하면 GET 방식은 URL 부분에 요청 정보를 전달하는것이다. - GET 이던 POST던 상관없이(심지어 PUT이나 DELETE에도) 헤더 부분에 요청 정보를 넣어 보낼 수 있다.
- 초보를 위한 책이기 때문에, 이 모든것을 구체적으로 설명할 수 없다는것을 독자는 이해해야 한다.
- 클라이언트에서 어떤 Method를 쓰던 request 헤더에 부가적인 정보를 보내고, 서버에서 그 정보를 받아서 처리하겠다고 약속하면 된다.
164 페이지
- 첫 번째 코드 예제 중에서
app.use('/public', static(path.join(__dirname, 'public')));
부분이 잘못 되었다. - 코드의 직전 설명에서는
[public] 폴더에 있는 모든 파일을 웹 서버의 루트 패스로 접근할 수 있도록 만들고 싶다면
이라고 표현되어 있다. 이 말대로 동작하려면 코드는app.use(static(path.join(__dirname, 'public')));
이 되어야 할 것이다. - 다음 페이지의 3번째 예제는 설명이 제대로 되어 있다.
- 167 페이지의 예제에서도
app.use('/public', static( ... ) )
으로 되어 있는데, 이 역시app.use( static( ... ) )
로 되어야 한다. - 그리고 static 이라는 이름의 변수를 쓰는건 좋지 않다. 오해를 일으킬 수도 있고, 추후 TypeScript 등을쓰게 되면 또 문제가 된다. 그러므로 static이라는 이름의 변수는 피하도록 하자.
- 참고로 Express 4.x 이후로는
express.static
미들웨어를 기본으로 제공한다고 한다. 그래서 코드를 쓸 때 그냥,app.use(express.static('public'));
형태로 쓰면 된다. 여러 디렉토리를 설정할 수도 있다고 한다.
168 페이지
- 아래쪽을 보면
서버 코드에서 use() 메소드로 설정한 함수는 login.html 문서에 접근했을때는 호출되지 않습니다.
라고 되어 있다. 근데... 잘은 모르지만... 아마도... 이 설명은 잘못 되었다. - 서버 코드에서
app.use( '/public', static(...))
부분이 실행되었기 때문에, public 디렉토리에서 login.html을 찾아서, 웹 브라우져로 내려 주었기 때문에, 웹브라우저에서 해당 HTML을 볼 수 있게 된 것이다. - 그러므로 정확하게 말하면
서버코드에서 app.use( static(...) ) 메소드로 설정한 함수가 동작했고, 그 다음 app.use() 함수는 호출 되지 않습니다.
라고 이해하는게 좋겠다. - 그렇다면 왜,
app.use(static(...))
다음에 우리가 정의한 미들웨어는 실행되지 않는가? 바로,static(...)
함수 안에서 error가 나지 않는 이상next()
함수를 호출하지 않도록 코드가 만들어져 있다. 관심이 있다면 직접 소스 코드를 확인해 보자.
262 페이지
- 세번째 줄
I accept th license terms
->I accept the license terms
로e
가 빠진 듯 하다.
276 페이지 277 페이지
- 276 페이지
select ?? from ?? where id = ? and password = ?
부분과 227페이지SQL문 안에 들어 있는 ?? 또는 ? 기호를 대체한 후 다음과 같은 SQL 문을 만들어 냅니다.
에서 어떤때는 ?? 를 쓰고, 어떤때는 ?를 쓰는데 이건 오타가 아니다. ??
는 '' 없이 그냥 값이 대체 될 때 사용되고,?
는 ''를 감싸서 대체 된다.- 277 페이지 중간에 있는
select id, name, age from users where id = 'test01' and password = '123456'
을 보면 잘 알 수 있다.
348 페이지
- 마지막 예제에서
<h2><% = title %></h2>
가 있는데%
와=
를 붙여 적어야 한다. 즉,<h2><%= title %></h2>
가 되어야 함. - 그 외, 다른 곳에서도
<% =
와 같이 띄워쓰는 코드들이 보이는데 이것은 모두 오타이다. 그러므로 다 붙어 있다고 생각하면 된다. - 그리고 여기에서
<%
를 쓰는 경우와<%=
를 쓰는 경우가 있는데, 이것에 대한 자세한 사용법은 ejs홈페이지 에서 Tags 부분을 확인해 보면 좋다.
8장 뷰템플릿 적용하기...
- 뷰 템플릿은 ejs와 pug에 대한 설명이 나온다.
- 기존에 HTML을 알고 있는 사람이라면 ejs가 훨씬 더 직관적이다. 반면 pug는 pug만의 문법을 따라야 한다는 불편함이 있다.
- 물론 pug가 HTML tag를 모두 적지 않아도 된다는 장점이 있지만, 요즘에는 대부분 IDE 툴에서 HTML 자동 완성을 제공해 주므로, 크게 차이가 나지 않을 것으로 보인다.
- 암튼 난 ejs 가 훨씬 더 편해 보인다. 예전에 php를 해서 그런지 ejs가 훨씬 더 익숙해 보인다.
373 페이지
- 두번째 예제 박스에서
passport.use(new LocalStrategy(
부분은passport.use('local', new LocalStratgy(
로 바꾸는것이 책을 읽는데 좀 더 수월하다. 다음장인 374 페이지의 윗 부분 그림에도스트래티지 설정
이라는 부분에 보면'local'
을 설정해 둔 것을 볼 수 있다. - 다만
'local'
을 생략했다고 해서 잘못 동작하는것은 아닌데,passport.use()
함수를 호출할 때, Strategy의 이름을 설정해 주지 않는다면, Strategy에서 name 값을 얻어와 셋팅하도록 되어 있기 때문이다. - https://github.com/jaredhanson/passport/blob/master/lib/authenticator.js
- LocalStrategy의 코드를 보면 자신의 name 값을 설정하는 코드를 찾을 수 있다.
- https://github.com/jaredhanson/passport-local/blob/master/lib/strategy.js
- 그러므로
passport.use(new LocalStrategy(
로 설정했다고 해도, 가져다 쓸 때는passport.authenticate('local', ...)
으로 호출 할 수 있게 된다.
427 페이지
attach(httpServer, options)
는 정확하게 하면,attach(httpServer[, options])
이다. 즉, Options는 생략 가능. 물론 책에서 일일이 설명하기 어려우니 생략했을 것이라고 생각한다. 글쓴이보고 뭐라고 하지 말길...- 그 아래에 있는
listen(httpServer, options)
역시 마찬가지다.
431 페이지
- 예제 중에서
socket.on(...
부분의 코드에서 들여쓰기가 잘못 되어 있으니 주의해서 볼 것.
435 페이지
- 예제나 책 설명 중에
recepient
는recipient
의 오타이다. 하지만 책 전반에 걸쳐 오타인recepient
를 사용했으니, 실제 코드에서는 별 문제가 없을 것으로 예상된다. - 나도 자주 틀리는 단어라.. ㅎㅎ. 이해가 된다. ㅋㅋㅋㅋㅋ.
481 페이지
이 callback 함수는 두 개의 파라미터를 전달받을 수 있는데, 첫 번째 파라미터는 오류 전달을 위해 사용하고 두번째 파라미터는 정상적인 데이터를 전달 할 때 사용합니다.
라고 설명되어 있다.- 487 페이지에 실제로 에러가 난 상황을 가정하고, 첫번째 파라미터에 "정보"를 넘기고 있는것을 볼 수 있다. 481 페이지의 내용을 대충 읽으면, 487 페이지의 내용을 이해하기 어려울 수 있을것 같아, 기록해 둔다.
484 페이지
- 제일 아래 표에서
result : 응답 데이터가 배열 객체로 들어 있습니다.
라고 되어 있다. - 여기서는 성공한 경우에 대한 정보만 표로 나타내고 있다. 실패한 경우에는
error
이라는 속성에 정보가 채워져 있다. 이 내용은 489 페이지에 설명되어 있다. - 다만 실패한 경우에 대한 설명은 표로 설명되어 있지 않아 놓치기 쉬울 것 같이 기록해 둔다.
621 페이지
- 예제의 하단을 보면
Entities : Entities
부분이 있다. - 또한, 622 페이지 ejs 예제를 보면
var entities = new Entities();
코드가 있다. - 뜬금 없이 갑자기
Entities
를 사용하고 있는데, 이건 책에 코드가 누락되어 있기 때문이다. - 619 페이지 코드에서 제일 윗 줄에
....
위치에 다음의 코드가 들어가야 한다.var Entities = require('html-entities').AllHtmlEntities;
. - 인터넷에세 예제를 다운로드 받아보면 추가 되어 있으나, 책에서는 생략되어 있어 의아하게 생각할 수 있는 부분이다.
- 책에서는
Entitites
에 대한 설명을 아예 없다. - html-entities 모듈은 HTML을 인코딩/디코딩 시켜주는 역할을 한다. 설치는
npm install html-entities --save
로 설치 할 수 있다.
반응형