Express로 서버 실행하기

소스코드

이 게시물에는 코드작성이 포함되어 있습니다. 소스코드를 받으신 후 진행해 주세요. MEAN Stack/개발 환경 구축에서 설명된 프로그램들(git, npm, atom editor)이 있어야 아래의 명령어들을 실행할 수 있습니다.

git clone https://github.com/a-mean-blogger/hello-world.git
cd hello-world
git reset --hard 1f7e4d6
npm install
atom .

- Github에서 소스코드 보기: https://github.com/a-mean-blogger/hello-world/tree/1f7e4d6cc800510b129b44b002a20ca48b131234


Express는 node.js로 서버를 만드는 framework입니다. node.js와 Express를 사용해서 초간단 웹서버를 만들어 봅시다.
git, node js/NPM, atom 에디터는 모두 설치되어 있겠지요?

git bash를 실행한 후 아래 스크린샷의 명령어를 입력하여 프로젝트 폴더를 생성하고 git 저장소를 생성합니다.

mkdir 명령어로 프로젝트 폴더를 생성하였고, git init 명령어로 git 저장소를 생성하였습니다.

다음으로 npm init 명령어로 현재 폴더에 node 프로젝트를 생성합니다. 이 명령어를 실행하면 프로젝트에 대한 질의 응답이 아래와 같이 나오는데, 일단 아무것도 입력하지 않고 계속 엔터를 쳐서 넘깁시다. 이 질문들을 바탕으로 package.json 파일을 생성하게 되는데, 그냥 엔터를 쳐서 넘기게 되면 해당 질문에 해당하는 항목이 생성되지 않거나, 질문의 기본값(괄호안의 값)이 있는 경우 해당값이 입력됩니다.

생성된 package.json파일은 아래와 같은 텍스트를 담고 있습니다.

{
  "name": "hello-world",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

npm init 명령어의 역할은 사실 이 파일을 생성하는 것이 전부입니다. 여기 눈여겨 봐야 할 부분은

  "main": "index.js", 

바로 이부분인데요, node.js 프로젝트의 메인 코드 파일명이 기록되어 있는 부분입니다. index.js가 기본값으로 입력이 되어 있으니 touch 명령어로 index.js파일을 생성해 봅시다.

다음으로 현재 프로젝트 폴더에 Express를 설치합니다. Express는 node.js용 웹사이트 개발 framework이며 NPM을 통해 설치할 수 있습니다.

NPM 명령어를 통해 설치된 package들은 현재_폴더/node_modules 폴더에 저장됩니다.

지금까지의 과정이 잘 이해가 되지 않으시면 Node JS 첫걸음/개발 환경 구축을 다시 읽어 주세요. 자세히 읽어보면 다 설명된 내용입니다.

atom . 명령어로 현재폴더를 atom 에디터로 엽니다.


왼쪽 패널의 파일 시스템 창을 보면 npm install --save 명령어가 실생된 후에 node_modules 폴더와 package-lock.json 파일이 추가로 생성된 것을 볼 수 있고, package.json에 dependencies항목이 생겼으며 express가 들어간 것을 볼 수 있습니다.

**참고로 파일및 폴더의 생성, 삭제, 이동, 복사, 이름 변경 등은 atom에서도 가능합니다. 파일 시스템 창에서 마우스 오른쪽 버튼을 눌러서 사용해 보세요.

서버를 생성하기 위해 index.js에 다음 코드를 입력해 줍니다.

//index.js

var express = require('express'); // 설치한 express module을 불러와서 변수(express)에 담습니다.
var app = express(); //express를 실행하여 app object를 초기화 합니다.

app.get('/', function(req, res) { // '/' 위치에 'get'요청을 받는 경우,
  res.send('Hello World!'); // "Hello World!"를 보냅니다.
});

var port = 3000; // 사용할 포트 번호를 port 변수에 넣습니다. 
app.listen(port, function(){ // port변수를 이용하여 3000번 포트에 node.js 서버를 연결합니다.
  console.log('server on! http://localhost:'+port); //서버가 실행되면 콘솔창에 표시될 메세지입니다.
});

require(모듈_이름) 함수는 node.js에서 기본적으로 주어지는 함수로, modules폴더 안에 설치된 모듈을 불러오는 함수입니다. express 모듈을 express 변수에 담고, express()로 app object를 초기화 하는 것은 Express framework에서 항상 가장 처음하는 것이므로 따라해 줍니다.

app.get, app.listen은 해당부분의 코드가 index.js 실행시 바로 실행되는 것이 아니라, app.get 부분은 서버에 get요청이 있는경우, app.listen은 서버가 실행되는 경우에 각각 실행이 됩니다. 이렇게 어떠한 조건이 갖춰지면 실행되는 코드를 가지는 함수를 event listener(이벤트 리스너)라고 합니다.

app.get 부분을 다시 살펴봅시다. 이번 포스팅에서 가장 중요한 부분입니다.

app.get('/', function(req, res) { // '/' 위치에 'get'요청을 받는 경우,
  res.send('Hello World!'); // "Hello World!"를 보냅니다.
});
app.HTTP_Method_중_하나('Route_주소', 콜백_함수, 콜백_함수, 콜백_함수...)

의 구조를 하고 있습니다. 위에서는 콜백 함수를 하나만 사용했지만 함수사이에 ","를 넣어서 여러개의 콜백함수를 넣을 수도 있습니다.

콜백 함수에는 req, res, next의 parameter들(이 순서만 중요할 뿐 이름은 바꿔도 상관없습니다)이 자동으로 전달됩니다. 다음으로 이 parameter들에 대해 살펴봅시다.

req

request에 관련된 값들과 함수들이 저장되어 있는 object. HTTP request header, 요청 url, cookies, query, body 등의 정보가 저장되어 있습니다.

이 object의 전체 구조를 확인하고 싶을땐 콜백 함수에 console.log(req) 코드를 넣으면 안을 확인할 수 있습니다.(req 뿐만 아니라 나머지 res, next 등도 console.log를 통해 값을 확인해 봅시다!)

res

response에 관련된 값들과 함수들이 저장되어 있는 object. HTTP response header, cookies, HTTP code 등의 정보를 확인하고 값을 변경할 수도 있습니다.

또한 어떠한 방식으로 response할지도 정할 수 있습니다. 위 예제에서는 res.send를 사용해서 텍스트를 response하였습니다.

next

만약 여러개의 콜백 함수를 사용한다면 이 함수를 호출하여 다음번 콜백 함수로 넘어갈 수 있습니다. 위 예제에서는 함수가 하나뿐이므로 parameter에 적지도 않았습니다.

위 코드에서 주석을 빼고 입력하면 atom에서 이렇게 보이겠죠.


hello world강좌라 정말 한 스텝 한 스텝 마다 스크린샷을 찍었습니다.

이제 서버를 실행시킬 차례입니다.

$ node index.js

위 명령어를 입력하면 우리가 코딩한 대로 'Server On!'이라는 메세지가 뜨면서 서버가 실행됩니다.


웹 브라우저를 열고 http://localhost:3000 에 접속해 봅시다. localhost는 http프로토콜에서 자기 자신의 서버에 접속할 때 사용되는 주소이고, 3000은 서버에 접속하는 포트 번호로, app.listen에서 3000으로 설정했기 때문에 3000을 사용합니다. 한 서버에 여러가지 서버 프로그램이 작동하는 경우 포트 번호를 달리해서 구별하게 됩니다. 혹시나 자신의 컴퓨터가 이미 3000번 포트를 사용하고 있다면, 다른 값으로 바꾸어서 실행해 보세요.

웹 브라우저에 주소를 입력하는 것은 서버에 HTTP method 중 GET으로 요청됩니다. 그러므로 위 코드의 app.get콜백_함수가 실행되어 res.send를 통해 우리가 입력한 Hello World!라는 텍스트가 출력이 되는 것입니다.

지금까지 작업한 것을 git에 저장하기 전에, node_modules 폴더가 git에 저장되지 않도록 .gitignore파일을 생성해 줍시다.

node_modules에 저장된 node package들은 용량이 커질 수 있고, 언제든지 누구든지 npm install 명령어로 복구가 가능하기 때문에 보통 git에는 저장하지 않습니다. .gitignore 파일의 각줄에 git에서 제외할 파일명, 폴더명 등을 넣어두면 자동으로 git에는 저장하지 않게됩니다. Atom 에디터에서도 해당 파일/폴더는 표시되지 않습니다. 위 스크린샷에서는 node_modules 폴더명을 입력하고 저장하자 마자 node_module 폴더명이 회색으로 변하였습니다. 시간이 지나면 아에 표시도 안됩니다.

마지막으로 프로젝트의 설명을 기록하는 README.md파일을 생성해 줍시다.

여기에 기록된 내용은 github에 git을 개제할 경우에 아래와 같이 보이게 됩니다.

마지막으로 git add ., git commit -m 명령어로 지금까지 한 작업을 안전하게 저장합니다.

마지막으로 git add ., git commit -m 명령어로 지금까지 한 작업을 안전하게 저장합니다. 보너스로 개발 환경 구축/Git GitHub 간단 사용법를 따라서 github에 업로드까지 하시면 백점 만점 받으실 수 있습니다!

마치며..

첫 실습인데 어떠셨는지.. 별 내용은 없는데 너무 복잡하게 설명한 것 같기도 하네요. 피드백은 항상 고맙게 받겠습니다. 혹시 잘 안되는 부분이 있으면 댓글 남겨주세요. 읽어주셔서 감사합니다!

댓글

j
jungbin lee 2016.12.27
이 블로그를 이제야 알다니! 멋집니다.
I
Ian H 2016.12.28
@jungbin lee,
감사합니다^^;
김태현 2017.01.28
events.js:160       throw er; // Unhandled 'error' event       ^
Error: listen EADDRINUSE :::3000     at Object.exports._errnoException (util.js:1022:11)     at exports._exceptionWithHostPort (util.js:1045:20)     at Server._listen2 (net.js:1262:14)     at listen (net.js:1298:10)     at Server.listen (net.js:1376:9)     at Function.listen (C:\Users\admin\Desktop\MyProject\Web\myapp\node_modules\express\lib\application.js:617:24)     at Object.<anonymous> (C:\Users\admin\Desktop\MyProject\Web\myapp\app.js:15:5)     at Module._compile (module.js:571:32)     at Object.Module._extensions..js (module.js:580:10)     at Module.load (module.js:488:32) [nodemon] app crashed - waiting for file changes before starting...
nodemon 을 치면 이런게 나오는데 왜이러는 걸까요
I
Ian H 2017.01.28
@김태현,
3000을 다른 숫자로 바꿔서 실행해 보세요~
J
Jason 2017.02.13
Is this ok? (yes) 여기에서 엔터 말고 yes 를 입력해야 정상적으로 종료가 되더라고요. 블로그 잘 보고 있습니다^^
I
Ian H 2017.02.17
@Jason,
앗. 그런 방법이 있었네요. 맥에서는 그냥 엔터쳐도 종료가 되거든요.
김동권 2017.05.17
감사합니다 잘배우고 있습니다~
김성환 2017.10.04
현재 폴더를 아톰으로 열기 >> atom . 을 실행하면 command not found가 나오는 데 어떻게 해야 할까요?
$ atom . bash: atom: command not found
I
Ian H 2017.10.04
@김성환,
환경변수가 업데이트 되지 않아서 그렇습니다. 컴퓨터를 재부팅해보세요
김성환 2017.10.04
@Ian H,
PATH 없는것 같아 해결했는데 댓글 달아주셔서 글 안지우겠습니다. 빠른 댓글 감사 드립니다. 
I
Ian H 2017.10.04
@김성환,
해결하셨다니 다행이네요^^
김종하 2017.12.08
"현재폴더를 atom 에디터로 엽니다. "
여기서 "atom 에디터" 링크 404 에러 뜹니다
I
Ian H 2017.12.08
@김종하,
수정하였습니다. 알려주셔서 감사합니다^^
J
Jaehong Ahn 2018.02.06
와....감사합니다.. 진짜 엄청나게 친절하고 세세하게, 또 알기 쉽게 쓰여진 강좌/가이드인거 같습니다. 구글링의 구글링을 거쳐 어쩌다 정말 우연히 여기까지 왔는데 정말 도움이 됩니다. 잘 보고 가요!
I
Ian H 2018.02.13
@Jaehong Ahn,
격려의 말씀 감사합니다^^
반팔 2018.09.19
한 단계 한 단계 따라해보고 있어요. 감사합니다!
I
Ian H 2018.09.19
@반팔,
^^ 화이팅!
컴신 2018.11.08
너무 깔끔하니, 설명이 잘되어있어서 한번 읽었을뿐인데 전부 다 쏙쏙 들어오네요. lan H님 atom에서 에디터 theme  설정 어떤걸로 하셨는지 알려 주실 수 있을까요 ?!  lan H님 에디터가 눈에 확 잘들어오네요!!
I
Ian H 2018.11.08
@컴신,
감사합니다^^ 기본 theme인데.. 아마 저때랑 지금이랑 기본 theme 색깔이 조금 달라진 것 같아요.
j
js lee 2019.03.12
이 게시 글은 2016년도에 작성 되어진건데.... 2019년 이제야 이 블로그를 알다니.... 알기 쉽게 내용을 잘 정리 해주셔서 열심히 공부하겠습니다. 감사합니다.
I
Ian H 2019.03.12
@js lee,
반갑습니다^^ 궁금하신 점 있으시면 질문도 해주세요!
캡틴제라드 2019.06.07
app.get('/',function(req,res){   res.send('Hello World'); });
이 부분에서요, function(req,res) 이 부분이 정확히 어떤 역할을 하는건지 알 수 있을까요?ㅎㅎㅎ function이 무슨 일을 하는지도 궁금합니다!! ㅎㅎ
I
Ian H 2019.06.07
@캡틴제라드,
본문에도 써있듯이 app.get은 event listener 역할을 하는 함수 입니다. 
node index.js로 코드를 실행하면 index.js의 코드들이 위에서 아래로 순서대로 실행되는데, app.get 함수는 두가지 파라메터를 가지고 있죠. 첫번째는 route이고, 두번째는 콜백 함수요.
이처럼 함수(app.get)의 파라메터로 함수(function(req,res){...})를 전달하는 것을 콜백 함수 전달이라고 하고, 전달된 콜백 함수는 원래 함수의 알고리즘에 따라 알맞은 시점에 해당 콜백함수가 호출이 됩니다. 그리고 콜백함수의 파라메터 역시 원래 함수의 알고리즘에 따라 어떠한 값이 들어갈지가 정해집니다.
다시 index.js로 돌아가서, index.js의 코드들이 처음 읽어 내려갈 때는 이 콜백 함수 속의 코드가 실행되지 않습니다.
app.get함수에 의해 이 콜백 함수가 언제 실행될지가 정해집니다. 여기서는 HTTP GET method로 첫번째 파라메터인 '/'에 요청이 오면 콜백 함수의 코드가 실행됩니다. 이름이 콜백 함수인 이유도 함수가 다시 호출(call back)하기 때문에 이런 이름이 붙여졌습니다.
서론이 길었는데, function(req,res){...}은 위 코드에서 원래 함수(app.get)의 파라메터 자리에 위치하고 있죠. 파라메터자리에서 함수를 선언하고 파라메터로서 함수에 전달되는 역할을 합니다.
보통 함수의 선언은 function 함수_이름(파라메터들){함수_코드} 로 하잖아요? 근데 저렇게 함수이름없이 선언되는 함수를 anonymous(어나니머스, 이름이없는) 함수라고 합니다.
function(req,res)는 app.get의 콜백 함수이며, app.get의 알고리즘에 의해 req(오브젝트), res(오브젝트), next(함수) 세 개의 파라메터를 전달받습니다. 위 코드에서 마지막 next는 콜백 함수 코드에서 사용되지 않으므로 삭제를 하여 function(req,res,next)가 아닌 function(req,res)로 사용되었습니다.
혹시 더 이해가 안되시는 부분이 있으면 알려주세요^^
d
dia7691 2020.02.16
이 블로그에서 자바스크립트 기초를 모두 배워 그 다음으로 nodejs를 배우려 합니다 ㅎ 좋은강좌 감사드립니다^^
I
Ian H 2020.02.17
@dia7691,
와 제가 다 뿌듯하네요^^ 공부하시다가 질문있으시면 댓글남겨주세요! 화이팅!
댓글쓰기

이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기

UP