express-generator
매번 서버를 만들 때마다 라우터, 모델, 뷰, 미들웨어, 에러 미들웨어 등을 만드는 일은 매우 번거롭습니다.
이처럼 반복적으로 수행되는 일은 express-generator 를 이용해 한 번에 만들 수 있습니다.
express-generator 를 통해 생성된 프로젝트는 개인의 스타일에 맞춰 수정하는 것도 가능합니다.
express-generator 프로젝트 생성
- npm 을 이용해 설치가 가능합니다.
$ npm install -g express-generator
- express-generator 가 생성되면 express 명령어를 통해 프로젝트를 생성할 수 있습니다.
express [프로젝트명]
위처럼 express 프로젝트가 생성되면 의존성 모듈을 설치하는 방법과 앱을 실행하는 방법이 콘솔에 출력됩니다.
생성된 프로젝트는 package.json 파일에 기록된 dependencies 를 설치하기 위해 반드시 npm install 을 해줘야 합니다.
express-generator 로 생성된 프로젝트의 구조
위에서 설치한 testApp 프로젝트의 구조를 살펴보겠습니다.
package.json
express-generator 로 생성된 프로젝트의 package.json 은 다음과 같습니다.
{
"name": "testapp",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"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"
}
}
cookie-parser, debug, express, jade, morgan, http-errors 등의 모듈이 기본적으로 설치되어 있습니다.
debug 설정을 통해 라우트의 일치 여부, 사용중인 미들웨어, 현재 동작 중인 애플리케이션 모드, 요청-응답 시간을 확인할 수 있습니다.
jade 는 express 에서 사용하는 html 렌더링 템플링 엔진입니다. express 에서는 jade 와 함께 ejs 라는 2개의 템플릿 엔진을 사용합니다.
body-parser 모듈은 express 4.16 이상부터 express 에 내장되어 있습니다
app.js
서버에 필요한 미들웨어들을 등록하는 파일입니다.
// 미들웨어 가져오기
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
// routes 폴더에 있는 index.js 와 users.js 를 가져옴
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
// express 미들웨어를 등록할 app 변수를 선언
var app = express();
// app.set 을 설정 , view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 미들웨어를 등록
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// ./routes 디렉터리에 만들어진 라우터를 / 와 /users 엔드 포인트로 분리합니다.
// 엔드포인트를 / 로 요청하면 ./routes/index.js 를 호출하고 /users 로 요청하면 ./routes/users.js 를 호출합니다.
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
// 에러 처리
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
// 외부에서 사용 가능하도록 모듈화
module.exports = app;
코드가 길지만 앞에서 모두 다룬 내용으로 주석을 통해 코드의 역할을 확인하실 수 있습니다.
app.js 는 미들웨어만 포함하고 서버를 직접 생성하진 않습니다.
서버를 생성하는 일은 bin/www 가 하게 됩니다.
bin 디렉터리
bin 디렉터리는 app.js 파일을 가져와 서버를 실행하는 www 파일을 가지고 있습니다.
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('testapp:server');
var http = require('http');
/**
* Get port from environment and store in Express.
* 서버의 포트를 설정합니다. app.set 을 이용해서 포트를 설정할 수 있습니다.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
* 완성된 app 을 http 를 이용해 서버를 생성합니다.
* 생성된 인스턴스는 server로 저장하고 server 를 이용해 리스닝과 에러 처리를 하게 됩니다.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
* 서버를 실행합니다.
* 서버 실행 중 문제가 발생하거나 정상적으로 실행되었을 때 호출되는 함수를 등록합니다.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
* 포트 번호를 검사합니다.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
* 서버 실행 중 발생된 에러를 핸들링하는 함수입니다.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
* 서버 실행 완료 후 핸들링하는 함수입니다.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
주석을 통해 각 코드의 역할을 확인하실 수 있습니다.
www 파일의 목적은 app.js 파일을 가져와 http 모듈을 이용해서 서버를 등록하고 서버 등록 중 문제에 대해 처리하는 역할을 합니다.
서버가 잘 등록되었는지, 서버 등록 중 문제가 발생하지 않았는지 설정하고, 서버를 몇 번 포트로 열지 설정하는 파일입니다.
routes 디렉토리
index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
users.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
초기에 생성된 index.js 와 users.js 입니다.
여기서 설정된 파일을 app.js 가 호출하여 미들웨어를 등록합니다.
routes 디렉토리는 우리가 원하는 형태의 라우터를 만들면 됩니다.
public 디렉토리
public 은 필요한 정적파일을 관리하는 디렉토리입니다.
images, javascripts, styles 디렉토리로 나뉘어져 있으며 이미지, JS, CSS 파일을 독립적으로 관리합니다.
views 디렉토리
HTML 으로 렌더링 되는 템플릿 엔진 파일을 관리합니다.
초기에 express 프로젝트 생성 시에 ejs, jade 옵션에 따라 다른 파일이 생성됩니다.
그 외
- DB 연결을 위한 디비 모델, 유틸성 함수를 모아놓는 디렉터리를 생성해 관리할 수 있습니다.
express 실행하기
생성된 프로젝트를 npm 또는 bin 디렉터리의 www 파일을 실행해 서버를 실행할 수 있습니다.
$ npm run start
$ node ./bin/www
결과
참고도서 : 자바스크립트로 서버와 클라이언트 구축하기
'Study > Express(node.js)' 카테고리의 다른 글
node.js ) 비동기 패턴 해결 (1) - 콜백함수 (0) | 2022.02.05 |
---|---|
node.js ) 비동기 (asynchronous) 패턴 (0) | 2022.02.05 |
express ) 미들웨어 (0) | 2022.02.04 |
express ) Router (0) | 2022.01.17 |
node.js ) package.json 파헤치기 (0) | 2022.01.16 |
댓글