JUINTINATION

Node.js와 Express.js 가볍게 입문해보기 - 3 본문

StudyNote

Node.js와 Express.js 가볍게 입문해보기 - 3

DEOKJAE KWON 2024. 1. 15. 20:40
반응형

지난 도커(Docker) 가볍게 입문해보기 글에서 도커의 가벼운 입문 말고 Express.js 기본적인 CURD API 만들어보기, Middleware에 대한 개념 이해하기 등의 과제를 받았다고 언급했었다. 이 글에서는 Express.js로 기본 예제인 로컬에서 Hello World 출력하기 프로젝트 관련 내용을 적을 것이다.

지난 Node.js와 Express.js 가볍게 입문해보기 - 2에서 이어지는 내용이며 해당 글은 이 링크로 들어가면 확인할 수 있다.

 

Node.js와 Express.js 가볍게 입문해보기 - 2

지난 도커(Docker) 가볍게 입문해보기 글에서 도커의 가벼운 입문 말고 Express.js 기본적인 CURD API 만들어보기, Middleware에 대한 개념 이해하기 등의 과제를 받았다고 언급했었다. 이 글에서는 Express.j

juintination.tistory.com

Hello World 예제

  • 폴더 셋업
  • NPM init과 package.json
  • 의존 모듈 선언
  • app.js 파일
  • Jade 파일
  • 애플리케이션 실행

폴더 셋업

  • node_modules: Express.js와 Connect 라이브러리 뿐만 아니라 의존 모듈(서드파티 모듈)도 이 폴더 안에 존재한다.
  • views: Jade(또는 다른 템플릿 엔진) 파일
  • routes: 요청 핸들러가 있는 Node.js 모듈
  • db: MongoDB의 초기 데이터와 스크립트
  • public: HTML, CSS, 자바스크립트(브라우저), Stylus(또는 그 외 모든 CSS 프레임워크 파일)를 포함한 모든 정적(프론트엔드) 파일

$ mkdir hello-world $ cd hello-world $ mkdir -p public public/css public/img public/js db views views/includes routes 커맨드를 실행하여 폴더를 직접 생성할 수도 있지만 나는 $ express hello-world 커맨드더를 실행하여 폴더와 예시 코드를 자동으로 생성하게 했다.
이후에 $ npm install express 커맨드를 실행하여 node_modules 폴더가 생성되도록 했다.

NPM init과 package.json

이후에 $ npm init 커맨드 실행하여 package.json을 다음과 같이 입력했다.

{
  "name": "hello-world",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "jade": "~1.11.0",
    "morgan": "~1.9.1"
  },
  "main": "app.js",
  "author": "juintination",
  "license": "ISC",
  "description": ""
}

app.js 파일을 실행하려면 다음 커맨드 중 하나를 사용하면 된다.

$ node app.js $ node app $ npm run start

app.js 파일

메인 Express.js 파일의 전형적인 구조는 다음 부분을 포함한다.

  1. 의존 모듈 필요
  2. 설정
  3. 데이터베이스에 연결(선택)
  4. 미들웨어 정의
  5. 라우트 정의
  6. 서버 시작
  7. 클러스터를 이용하여 작업 스레드 시작(선택)

요청은 일련의 미들웨어를 따라 위에서부터 순서대로 실행하기 때문에 여기서 순서가 굉장히 중요하다.


프로그래밍 연습

이 애플리케이션은 자연스럽게 블로그 예제 프로젝트로 전환되므로 쓸데없는 짓은 아니라고 한다.

사용하는 코드 편집기에서 app.js 파일을 열거나 github.com/azat-co/blog-express의 코드를 복사한다.

 

GitHub - azat-co/blog-express: Express.js Blog App

Express.js Blog App. Contribute to azat-co/blog-express development by creating an account on GitHub.

github.com

우선, 모든 의존 모듈을 require()로 포함해야 한다.

var express = require('express');
var http = require('http');
var path = require('path');

그 후 Express.js 객체를 초기화한다.

var app = express();

 


Express.js 세팅을 설정하는 방법 중 하나는 다음과 같이 설정 이름, 값과 함께 app.set()을 사용하는 것이다.

app.set('appName', 'hello-world');

app.js의 몇 가지 설정에 대한 설명

  • port: 요청을 기다릴 서버의 번호
  • views: 템플릿이 있는 폴더의 절대 경로(예제의 views)
  • view engiine: 템플릿 파일의 파일 확장자(예를 들어 jade, html)

환경 변수(env vars)에서 제공한 포트 번호를 사용하고 싶다면 process.env.PORT를 이용해서 접근하면 된다.

app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

다음은 애플리케이션의 미들웨어 부분이다. 미들웨어는 Express.js 프레임워크의 중추로 두 가지 형태로 제공된다.

  1. 외부(서드파티) 모듈에서 정의
    1. ex) Connect/Express.js 바디-파서의 bodyParser.json: app.use(bodyParser.json());
  2. 애플리케이션 또는 애플리케이션의 모듈에서 정의
    1. ex) app.use(function(req, res, next) {…});

미들웨어는 코드를 구성 및 재사용하기 위한 방법이며 기본적으로 세 개의 파라미터(request, response, next)로 이루어진 함수일 뿐이다. 6장에서 미들웨어의 기능을 더 많이 사용한다고 한다.

app.js 파일의 다음 컴포넌트는 라우트다. 라우트는 정의된 순서대로 처리된다. 보통 라우트는 미들웨어 뒤에 위치하지만, 일부 미들웨어는 라우트 뒤에 위치하기도 한다. 라우트 뒤에 위치한 미들웨어의 대표적인 예는 에러 핸들러이다.

HTTP 요청이 처리되는 방식을 보여주는 그림은 다음에 자세히 공부할 때 그려서 해석과 함께 올리도록 하겠다.


다음 절에서는 라우트에 대해 다룬다. 헬퍼 app.VERB(url, fn1, fn2, …, fnN)에 의해 Express.js에서 라우트가 정의되는데 이 때 fnN은 요청 핸들러고 url은 RegExp의 URL 패턴이며 VERB는 다음가 같다.

  • all: 모든 요청(모든 메소드)을 처리
  • get: GET 요청 처리
  • post: POST 요청 처리
  • put: PUT 요청 처리
  • del: DELETE 요청 처리

delete 연산자는 객체의 프로퍼티를 삭제한다.


Hello World 예제에서 라우트 하나는 모든 URL의 모든 메소드 요청(와일드카드 문자 *)을 처리하는 데 사용된다.

요청 핸들러 안에서 메시지 msg(두 번째 인자의 프로퍼티)를 이용하여 템플릿이 렌더링(res.render())된다.

app.all('*', function(req, res)) {
    res.render('index', {msg: 'Welcome to the Practical Node.js!'});
});

res.render(viewName, data, callback(error, html))의 각각의 파라미터는 다음을 의미한다.

  • viewName: 파일 확장자가 있는 템플릿 명 또는 뷰 엔진이 설정된 경우 파일 템플릿 이름(확장자 제외)
  • data: locals로 전달되는 객체(선택)
    • ex) Jade에서 msg를 사용하려면 {msg: “…”}가 존재해야 한다.
  • callback: 렌더링이 끝났을 때 error 및 HTML과 함께 호출되는 함수(선택)

res.render()는 Node.js가 아니라 Express.js의 메소드로 호출되었을 때는 응답 프로세스를 종료시키는 res.end()를 호출한다. 즉, res.render() 실행 다음에는 미들웨어들이 처리되지 않는다.


마지막은 서버를 시작하기 위한 명령인데 핵심 http 모듈과 createServer 메서드로 이루어져 있다.

createServer 메서드에서 시스템은 모든 설정 값 및 라우트와 함께 Express.js 애플리케이션 객체를 전달한다.

http.createServer(app).listen(app.get('port'), function() {
    console.log('Express server listening on port ' + app.get('port'));
});

 


다음은 app.js 파일의 전체 소스코드이다.

var express = require('express');

var http = require('http');
var path = require('path');

var app = express();

app.set('appName', 'hello-world_appName_test');

app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.all('*', function(req, res) {
	res.render(
		'index',
		{msg: 'Welcome to the Practical Node.js!'}
  );
});

http
	.createServer(app)
	.listen(
		app.get('port'),
		function() {
			console.log('Express server listening on port ' + app.get('port')
		);
	}
);

Jade 파일

Jade는 개발자가 코드를 덜 작성할 수 있게 도와주며 거의 모든 자바스크립트 함수를 실행 가능한 템플릿 엔진이다. Jade는 루비의 Haml처럼 공백 또는 들여쓰기를 사용하며 들여쓰기할 때 두 칸의 공백을 사용하는 것이 규약이다.

Jade가 동작하는 방식 중에서 첫 번째 단어는 HTML 태그 또는 요소로 사용되고 그 뒤에 따라오는 텍스트는 이 요소 안에 위치한다.

h1 hello
p Welcome to the Practical Node.js!

다음 HTML 코드를 생성한다.

<h1>hello</h1>
<p>Welcome to the Practical Node.js!</p>

변수(local)의 값을 출력하고 싶다면 다음과 같이 =를 사용한다.

p= msg

이 예제의 경우 views 폴더 안에 헤더와 단락 내에서 msg 변수 값을 가진 단락을 출력하는 index.jade를 생성한다.

h1 hello
p =msg

애플리케이션 실행

$ node app.js 커맨드를 실행하고 브라우저에서 http://localhost:3000 으로 들어가보면 다음과 같은 화면을 볼 수 있다.


결론

자바 스프링 프레임워크를 처음 공부할 때처럼 로컬에서 Hello World를 출력하는 코드를 작성하고 실행해봤다. 실제로 해보면서 느낀 점이라면 아직 자바 스프링 프레임워크보다 익숙하지 않은 탓도 있겠지만 실행이 조금 더 복잡한 느낌이 든다. https://start.spring.io/에서 프로젝트 설정을 마치고 대충 Controller 클래스 만들고 어노테이션 설정해서 index.html로 연결 어쩌구.. 하면 끝이었던 것 같은데 아무튼 정진 또 정진이다!

728x90
Comments