신수용

08 Node.js

1 +"use strict"
2 +
3 +var http = require('http');
4 +var server = http.createServer(function(req, res) {
5 + res.writeHeader(200, {"Content-Type": "text/plain"});
6 + res.write("Hello World");
7 + res.end();
8 +});
9 +
10 +server.listen(3000, function() {
11 + console.log("Sever listeining on http://localhost:3000");
12 +});
1 +"use strict"
2 +
3 +var http = require('http'),
4 + path = require('path'),
5 + url = require('url'),
6 + fs = require('fs');
7 +
8 +var DOCUMENT_ROOT = "../../05_CSS/";
9 +var server = http.createServer(function(req, res) {
10 + var reqPath = url.parse(req.url).pathname;
11 + if (reqPath == "/") {
12 + reqPath = "ex01.html";
13 + }
14 + var fullPath = path.join(process.cwd(), DOCUMENT_ROOT, reqPath);
15 + fs.readFile(fullPath, "binary", function(err, file) {
16 + if(err) {
17 + if (err.code == "ENOENT") {
18 + console.log("SEND 404 for " + req.url);
19 + res.writeHeader(404, {"Content-Type": "text/html"});
20 + res.write("<h1>Not found</h1>");
21 + res.end();
22 + } else {
23 + console.error("Error", err);
24 + res.writeHeader(500, {"Content-Type": "text/plain"});
25 + res.write(err + "\n");
26 + res.end();
27 + }
28 + } else{
29 + console.log("SEND 200 for " + req.url);
30 + res.writeHeader(200);
31 + res.write(file, "binary");
32 + res.end();
33 + }
34 + });
35 +});
36 +
37 +server.listen(3000, function() {
38 + console.log("Sever listeining on http://localhost:3000");
39 +});
...\ No newline at end of file ...\ No newline at end of file
1 +# Logs
2 +logs
3 +*.log
4 +
5 +# Runtime data
6 +pids
7 +*.pid
8 +*.seed
9 +
10 +# Directory for instrumented libs generated by jscoverage/JSCover
11 +lib-cov
12 +
13 +# Coverage directory used by tools like istanbul
14 +coverage
15 +
16 +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 +.grunt
18 +
19 +# node-waf configuration
20 +.lock-wscript
21 +
22 +# Compiled binary addons (http://nodejs.org/api/addons.html)
23 +build/Release
24 +
25 +# Dependency directory
26 +# https://docs.npmjs.com/cli/shrinkwrap#caveats
27 +node_modules
28 +
29 +# Debug log from npm
30 +npm-debug.log
1 +var express = require('express');
2 +var path = require('path');
3 +var favicon = require('serve-favicon');
4 +var logger = require('morgan');
5 +var cookieParser = require('cookie-parser');
6 +var bodyParser = require('body-parser');
7 +
8 +var index = require('./routes/index');
9 +var users = require('./routes/users');
10 +
11 +var app = express();
12 +
13 +// view engine setup
14 +app.set('views', path.join(__dirname, 'views'));
15 +app.set('view engine', 'ejs');
16 +
17 +// uncomment after placing your favicon in /public
18 +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
19 +app.use(logger('dev'));
20 +app.use(bodyParser.json());
21 +app.use(bodyParser.urlencoded({ extended: false }));
22 +app.use(cookieParser());
23 +app.use(require('node-sass-middleware')({
24 + src: path.join(__dirname, 'public'),
25 + dest: path.join(__dirname, 'public'),
26 + indentedSyntax: true,
27 + sourceMap: true
28 +}));
29 +app.use(express.static(path.join(__dirname, 'public')));
30 +
31 +app.use('/', index);
32 +app.use('/users', users);
33 +
34 +// catch 404 and forward to error handler
35 +app.use(function(req, res, next) {
36 + var err = new Error('Not Found');
37 + err.status = 404;
38 + next(err);
39 +});
40 +
41 +// error handler
42 +app.use(function(err, req, res, next) {
43 + // set locals, only providing error in development
44 + res.locals.message = err.message;
45 + res.locals.error = req.app.get('env') === 'development' ? err : {};
46 +
47 + // render the error page
48 + res.status(err.status || 500);
49 + res.render('error');
50 +});
51 +
52 +module.exports = app;
1 +#!/usr/bin/env node
2 +
3 +/**
4 + * Module dependencies.
5 + */
6 +
7 +var app = require('../app');
8 +var debug = require('debug')('app03:server');
9 +var http = require('http');
10 +
11 +/**
12 + * Get port from environment and store in Express.
13 + */
14 +
15 +var port = normalizePort(process.env.PORT || '3000');
16 +app.set('port', port);
17 +
18 +/**
19 + * Create HTTP server.
20 + */
21 +
22 +var server = http.createServer(app);
23 +
24 +/**
25 + * Listen on provided port, on all network interfaces.
26 + */
27 +
28 +server.listen(port);
29 +server.on('error', onError);
30 +server.on('listening', onListening);
31 +
32 +/**
33 + * Normalize a port into a number, string, or false.
34 + */
35 +
36 +function normalizePort(val) {
37 + var port = parseInt(val, 10);
38 +
39 + if (isNaN(port)) {
40 + // named pipe
41 + return val;
42 + }
43 +
44 + if (port >= 0) {
45 + // port number
46 + return port;
47 + }
48 +
49 + return false;
50 +}
51 +
52 +/**
53 + * Event listener for HTTP server "error" event.
54 + */
55 +
56 +function onError(error) {
57 + if (error.syscall !== 'listen') {
58 + throw error;
59 + }
60 +
61 + var bind = typeof port === 'string'
62 + ? 'Pipe ' + port
63 + : 'Port ' + port;
64 +
65 + // handle specific listen errors with friendly messages
66 + switch (error.code) {
67 + case 'EACCES':
68 + console.error(bind + ' requires elevated privileges');
69 + process.exit(1);
70 + break;
71 + case 'EADDRINUSE':
72 + console.error(bind + ' is already in use');
73 + process.exit(1);
74 + break;
75 + default:
76 + throw error;
77 + }
78 +}
79 +
80 +/**
81 + * Event listener for HTTP server "listening" event.
82 + */
83 +
84 +function onListening() {
85 + var addr = server.address();
86 + var bind = typeof addr === 'string'
87 + ? 'pipe ' + addr
88 + : 'port ' + addr.port;
89 + debug('Listening on ' + bind);
90 +}
1 +{
2 + "name": "app03",
3 + "version": "0.0.0",
4 + "private": true,
5 + "scripts": {
6 + "start": "node ./bin/www"
7 + },
8 + "dependencies": {
9 + "body-parser": "~1.16.0",
10 + "cookie-parser": "~1.4.3",
11 + "debug": "~2.6.0",
12 + "ejs": "~2.5.5",
13 + "express": "~4.14.1",
14 + "morgan": "~1.7.0",
15 + "node-sass-middleware": "0.9.8",
16 + "serve-favicon": "~2.3.2"
17 + }
18 +}
1 +body {
2 + padding: 50px;
3 + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; }
4 +
5 +a {
6 + color: #00B7FF; }
7 +
8 +/*# sourceMappingURL=style.css.map */
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "version": 3,
3 + "file": "style.css",
4 + "sources": [
5 + "style.sass"
6 + ],
7 + "mappings": "AAAA,AAAA,IAAI,CAAC;EACH,OAAO,EAAE,IAAK;EACd,IAAI,EAAE,kDAAmD,GAAG;;AAE9D,AAAA,CAAC,CAAC;EACA,KAAK,EAAE,OAAQ,GAAG",
8 + "names": []
9 +}
...\ No newline at end of file ...\ No newline at end of file
1 +body
2 + padding: 50px
3 + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif
4 +
5 +a
6 + color: #00B7FF
1 +var express = require('express');
2 +var router = express.Router();
3 +
4 +/* GET home page. */
5 +router.get('/', function(req, res, next) {
6 + res.render('index', { title: 'Express' });
7 +});
8 +
9 +module.exports = router;
1 +var express = require('express');
2 +var router = express.Router();
3 +
4 +/* GET users listing. */
5 +router.get('/', function(req, res, next) {
6 + res.send('respond with a resource');
7 +});
8 +
9 +module.exports = router;
1 +<h1><%= message %></h1>
2 +<h2><%= error.status %></h2>
3 +<pre><%= error.stack %></pre>
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <title><%= title %></title>
5 + <link rel='stylesheet' href='/stylesheets/style.css' />
6 + </head>
7 + <body>
8 + <h1><%= title %></h1>
9 + <p>Welcome to <%= title %></p>
10 + </body>
11 +</html>
1 +# Node.js를 이용한 간단한 웹서버 구축
2 +
3 +## 실행 방법
4 +
5 +1. Hello World 웹 서버
6 + ```
7 + node app01.js
8 + ```
9 +
10 +2. 03 실습의 내용을 제공하는 웹서버
11 + ```
12 + node app02.js
13 + ```
14 +
15 +## TIP
16 +1. 코드를 수정할 때 마다 서버를 새로 띄워야 해서 불편하다면 nodemon을 설치하고 nodemon으로 서버를 실행할 수 있습니다. 소스 코드가 수정되면 자동으로 서버가 다시 시작됩니다.
17 + ```
18 + npm install --global nodemon
19 +
20 + nodemon app02.js
21 + ```
1 +# Logs
2 +logs
3 +*.log
4 +
5 +# Runtime data
6 +pids
7 +*.pid
8 +*.seed
9 +
10 +# Directory for instrumented libs generated by jscoverage/JSCover
11 +lib-cov
12 +
13 +# Coverage directory used by tools like istanbul
14 +coverage
15 +
16 +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 +.grunt
18 +
19 +# node-waf configuration
20 +.lock-wscript
21 +
22 +# Compiled binary addons (http://nodejs.org/api/addons.html)
23 +build/Release
24 +
25 +# Dependency directory
26 +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
27 +node_modules
28 +
29 +# Debug log from npm
30 +npm-debug.log
1 +var express = require('express');
2 +var path = require('path');
3 +var favicon = require('serve-favicon');
4 +var logger = require('morgan');
5 +var cookieParser = require('cookie-parser');
6 +var bodyParser = require('body-parser');
7 +
8 +var routes = require('./routes/index');
9 +var users = require('./routes/users');
10 +
11 +var app = express();
12 +
13 +// view engine setup
14 +app.set('views', path.join(__dirname, 'views'));
15 +app.set('view engine', 'ejs');
16 +
17 +// uncomment after placing your favicon in /public
18 +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
19 +app.use(logger('dev'));
20 +app.use(bodyParser.json());
21 +app.use(bodyParser.urlencoded({ extended: false }));
22 +app.use(cookieParser());
23 +app.use(require('node-sass-middleware')({
24 + src: path.join(__dirname, 'public'),
25 + dest: path.join(__dirname, 'public'),
26 + indentedSyntax: true,
27 + sourceMap: true
28 +}));
29 +app.use(express.static(path.join(__dirname, 'public')));
30 +
31 +app.use('/', routes);
32 +app.use('/users', users);
33 +
34 +// catch 404 and forward to error handler
35 +app.use(function(req, res, next) {
36 + var err = new Error('Not Found');
37 + err.status = 404;
38 + next(err);
39 +});
40 +
41 +// error handlers
42 +
43 +// development error handler
44 +// will print stacktrace
45 +if (app.get('env') === 'development') {
46 + app.use(function(err, req, res, next) {
47 + res.status(err.status || 500);
48 + res.render('error', {
49 + message: err.message,
50 + error: err
51 + });
52 + });
53 +}
54 +
55 +// production error handler
56 +// no stacktraces leaked to user
57 +app.use(function(err, req, res, next) {
58 + res.status(err.status || 500);
59 + res.render('error', {
60 + message: err.message,
61 + error: {}
62 + });
63 +});
64 +
65 +
66 +module.exports = app;
1 +#!/usr/bin/env node
2 +
3 +/**
4 + * Module dependencies.
5 + */
6 +
7 +var app = require('../app');
8 +var debug = require('debug')('app03:server');
9 +var http = require('http');
10 +
11 +/**
12 + * Get port from environment and store in Express.
13 + */
14 +
15 +var port = normalizePort(process.env.PORT || '3000');
16 +app.set('port', port);
17 +
18 +/**
19 + * Create HTTP server.
20 + */
21 +
22 +var server = http.createServer(app);
23 +
24 +/**
25 + * Listen on provided port, on all network interfaces.
26 + */
27 +
28 +server.listen(port);
29 +server.on('error', onError);
30 +server.on('listening', onListening);
31 +
32 +/**
33 + * Normalize a port into a number, string, or false.
34 + */
35 +
36 +function normalizePort(val) {
37 + var port = parseInt(val, 10);
38 +
39 + if (isNaN(port)) {
40 + // named pipe
41 + return val;
42 + }
43 +
44 + if (port >= 0) {
45 + // port number
46 + return port;
47 + }
48 +
49 + return false;
50 +}
51 +
52 +/**
53 + * Event listener for HTTP server "error" event.
54 + */
55 +
56 +function onError(error) {
57 + if (error.syscall !== 'listen') {
58 + throw error;
59 + }
60 +
61 + var bind = typeof port === 'string'
62 + ? 'Pipe ' + port
63 + : 'Port ' + port;
64 +
65 + // handle specific listen errors with friendly messages
66 + switch (error.code) {
67 + case 'EACCES':
68 + console.error(bind + ' requires elevated privileges');
69 + process.exit(1);
70 + break;
71 + case 'EADDRINUSE':
72 + console.error(bind + ' is already in use');
73 + process.exit(1);
74 + break;
75 + default:
76 + throw error;
77 + }
78 +}
79 +
80 +/**
81 + * Event listener for HTTP server "listening" event.
82 + */
83 +
84 +function onListening() {
85 + var addr = server.address();
86 + var bind = typeof addr === 'string'
87 + ? 'pipe ' + addr
88 + : 'port ' + addr.port;
89 + debug('Listening on ' + bind);
90 +}
1 +{
2 + "name": "app03",
3 + "version": "0.0.0",
4 + "private": true,
5 + "scripts": {
6 + "start": "node ./bin/www"
7 + },
8 + "dependencies": {
9 + "body-parser": "~1.13.2",
10 + "cookie-parser": "~1.3.5",
11 + "debug": "~2.2.0",
12 + "ejs": "~2.3.3",
13 + "express": "~4.13.1",
14 + "morgan": "~1.6.1",
15 + "node-sass-middleware": "0.8.0",
16 + "serve-favicon": "~2.3.0"
17 + }
18 +}
...\ No newline at end of file ...\ No newline at end of file
1 +body {
2 + padding: 50px;
3 + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; }
4 +
5 +a {
6 + color: #00B7FF; }
7 +
8 +/*# sourceMappingURL=style.css.map */
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "version": 3,
3 + "file": "style.css",
4 + "sources": [
5 + "style.sass"
6 + ],
7 + "sourcesContent": [],
8 + "mappings": "AAAA,IAAI,CAAC;EACH,OAAO,EAAE,IAAK;EACd,IAAI,EAAE,kDAAmD,GAFrD;;AAIN,CAAC,CAAC;EACA,KAAK,EAAE,OAAQ,GADd",
9 + "names": []
10 +}
...\ No newline at end of file ...\ No newline at end of file
1 +body
2 + padding: 50px
3 + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif
4 +
5 +a
6 + color: #00B7FF
1 +var express = require('express');
2 +var router = express.Router();
3 +
4 +/* GET home page. */
5 +router.get('/', function(req, res, next) {
6 + res.render('index', { title: 'Express' });
7 +});
8 +
9 +module.exports = router;
1 +var express = require('express');
2 +var router = express.Router();
3 +
4 +/* GET users listing. */
5 +router.get('/', function(req, res, next) {
6 + res.send('respond with a resource');
7 +});
8 +
9 +module.exports = router;
1 +<h1><%= message %></h1>
2 +<h2><%= error.status %></h2>
3 +<pre><%= error.stack %></pre>
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <title><%= title %></title>
5 + <link rel='stylesheet' href='/stylesheets/style.css' />
6 + </head>
7 + <body>
8 + <h1><%= title %></h1>
9 + <p>Welcome to <%= title %></p>
10 + </body>
11 +</html>
1 +# 실습하는 법
2 +
3 +1. npm을 이용하여 express-generator (express app 뼈대를 자동 생성해주는 프로그램)을 설치합니다.
4 + ```
5 + npm install -g express-generator
6 + ```
7 +
8 +1. express generator를 이용하여 app을 하나 만듭니다.
9 + ```sh
10 + express -e -c sass --git app03
11 + # -e: Jade대신 EJS template 엔진을 이용합니다. Jade도 좋지만, 일단은 HTML과 가장 유사한 EJS를 사용해봅시다.
12 + # -c sass: sass나 scss를 사용하려고 합니다.
13 + # --git: git을 사용할 때 편리하도록 .gitignore를 자동으로 생성합니다.
14 + ```
15 +
16 +1. 디렉토리에 들어가서 파일들을 살펴봅시다.
17 + ```
18 + cd app03
19 + atom .
20 +```
21 +
22 +1. package들을 설치합니다.
23 + ```
24 + npm install
25 + ```
26 +
27 +1. 서버를 실행해봅시다.
28 + ```
29 + nodemon ./bin/www
30 + ```
31 +
32 +1. 웹브라우져에서 http://localhost:3000 에 접속해봅시다.
33 +
34 +1. 디렉토리 설명
35 + - app.js: Express 미들웨어들이 설정되어 있습니다.
36 + - routes/: 라우팅 정보, 즉 URL로 들어온 처리를 어떻게 하는지 관리합니다.
37 + - views/: 화면에 출력할 View Template이 들어있습니다.
38 + - public/: static파일로 처리될 image, javascript, stylesheet 등이 있습니다. SCSS를 사용해볼 때도 여기서 해봅니다.
39 + - node_modules: 로컬에 인스톨된 패키지가 있는 곳입니다. 건드리지 맙시다.
40 +
41 +## 참고
42 +
43 +### npm : Package Manager for Node.js
44 +- 참고: https://docs.npmjs.com/getting-started/what-is-npm
45 +
46 +
47 +1. npm init
48 + - 패키지 관리 시작. 해당 디렉토리에 package.json을 만듭니다.
49 + - Git Bash에서 에러가 나는 경우 윈도우 cmd 창에서 실행하세요.
50 + - 차례로 물어보는 것에 대답하면 package.json 파일이 생깁니다.
51 +
52 +2. npm install
53 + - npm를 이용해 원하는 패키지를 인스톨 합시다.
54 + - 옵션
55 + - -g (--global)은 global로 인스톨 합니다. 그러면 이 프로그램을 cmd 창에서 유틸리티 처럼 사용할 수 있습니다.
56 + - --save는 이 프로젝트의 로컬에 인스톨 하면서 package.json에 기록되어 추후 npm install 로 한꺼번에 인스톨 할 수 있습니다.
57 + - --save-dev는 save와 유사하지만, 프로젝트의 실행에는 필요없고, 개발 단계에서만 필요하다는 뜻입니다.
58 + -
59 + ```
60 + npm install -g gulp
61 + npm install --save-dev gulp
62 + npm install --save express
63 + npm install -g express-generator
64 + ```