일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- dp
- 프로그래머스
- Algorithm
- 타입 챌린지
- dfs
- 문자열
- 그래프
- Nestjs
- typescript
- javascript
- 크롤링
- BFS
- 소켓
- ip
- 레벨 1
- 쉬운 문제
- Node.js
- 수학
- 가천대
- 백준
- socket
- type challenge
- Crawling
- TCP
- 자바스크립트
- 프로그래머스 레벨 2
- HTTP 완벽 가이드
- 타입스크립트
- HTTP
- 알고리즘
- Today
- Total
kakasoo
Express로 기초적인 서버 만들기 본문
Express로 서버 만들기
Express-generator로 서버 생성
$ npm install express-generator -g
$ express --no-view myAppName
위 라이브러리를 설치하고 사용하는 것만으로도 이미 웹 서버를 만들 수 있다. express 뒤에 들어간 --no-view는 option이다. pug나 jade 같이 서버 사이드 렌더링을 도와줄 view를 설정할 수도 있지만, 이제는 클라이언트와 서버를 분리하는 게 당연한(?) 일인 만큼, view는 없애도록 했다. 나는 이 상태로 개발을 시작했다. 굳이 pug과 jade를 쓸 필요 없이, 클라이언트는 분리해서 React로 만들고자 했다.
이번에는 간단한 수준에서 Express를 설명하고자 한다. 필요하다면 다른 글에서 썼던 내용을 가져다가, 다시 이야기할 수도 있겠다.
( 사실 이렇게 이야기하는 까닭은, 나중에 내가 작성한 글을 토대로 다른 사람을 가르쳐야 할 수도 있기 때문이다. )
$ cd myAppName
$ npm start
여기까지 따라하면 웹 서버가 동작할 것이고, 브라우저에서 127.0.0.1:3000을 입력하면 Welcome to Express 라는 문구를 볼 수 있을 것이다. 127.0.0.1은 localhost 라고 하여, 특별한 IP 값을 말하는데, 이는 자기 자신을 뜻한다. 어떤 컴퓨터든 자기 자신을 가리킬 때는 127.0.0.1, 즉 로컬 호스트라고 한다. 당연한 이야기지만, 다른 사람들이 이 값을 브라우저에 입력하고 우리가 만든 서버에 들어올 수는 없다. 상대가 스스로를 '나' 라고 부른다고 해서 그 '나'가 내가 말할 때의 '나'와 동일인물이 아니지 않은가.
상대방에게도 이 서버를 들어오게 할 생각이라면, 아래의 명령어를 따라 쳐보자.
$ ipconfig
이러면 다양한 주소들이 나오는데, 이것들 중 IPv4라는 주소 끝에 :3000이라는 port 번호를 붙이면, 모두 127.0.0.1:3000과 같은 페이지를 보여줄 것이다. 다양한 주소들이 있겠지만, 노트북이 여러 주소를 가진다기보단, 자신을 지칭하는 표현이 많다고 생각하는 게 옳다. 일단 여기서 무선 LAN 어댑터 Wi-Fi의 IPv4 값을 입력하고 포트 3000을 붙여보자. 위에서 한 것과 동일한 페이지를 볼 수 있을 것이다.
디렉토리 구조
기본적으로 생성된 것은 위와 같이, bin, public, routes, 그리고 app.js와 package.json으로 이루어져 있다. 가장 먼저 보여진 김에, app.js를 설명하자면, app.js는 우리가 만들 application 그 자체라고 보면 된다. 서버를 만든다는 것은 이 application을 만드는 것에 가깝다. 지금도 자동 생성된 코드가 있지만, 이는 서버가 동작할 뿐이지 우리가 원하는 결과를 내는 것은 아니다. 우리가 어떤 서버를 만들지를 생각하고, 그에 맞게 기능을 추가해주어야 한다.
ctrl + c를 눌러 동작 중인 서버를 꺼주고, 코드를 수정해주자. 자동으로 생성된 코드는 ES5의 문법을 따르고 있다.
app.js
const express = require("express");
const path = require("path");
const cookieParser = require("cookie-parser");
const logger = require("morgan");
const indexRouter = require("./routes/index");
const usersRouter = require("./routes/users");
const app = express();
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")));
app.use("/", indexRouter);
app.use("/users", usersRouter);
module.exports = app;
package.json
{
"name": "example",
"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",
"morgan": "~1.9.1"
}
}
지금 우리에게 중요한 것은 script인데, 여기서 start가 우리가 아까 npm start를 입력했을 때의 내용이다. 서버를 실행시키는 것은 항상 명령어가 필요하다. 또, 명령어는 test나 build가 있을 수 있고, 이를 실행하기 전에 미리 (pre) 실행해야 하는 명령어들이 있을 수도 있다. 이 명령어의 길이가 길어지면 서버를 실행시키기가 불편해지므로, npm run start라는 명령어에 해당하는 명령어를 미리 입력한 것이다.
기본적으로 생성된 것은 node ./bin/www라고 되어있다. node를 사용해본 사람이라면, 이게 ./bin/www.js를 실행시키라는 뜻인 것을 알 수 있을 것이다. 우리가 npm start를 입력할 때마다 저 명령어로 변환되어 대신 실행된다.
추가로, 다른 명령어를 실행할 때는 npm run 명령어의 형태를 따른다. start 명령어만 중간의 run을 생략할 수 있다.
start 명령어가 node ./bin/www이므로, 일단 bin 폴더의 www 파일을 보자.
bin
./bin/www 수정 전
#!/usr/bin/env node
var app = require('../app');
var debug = require('debug')('example:server');
var http = require('http');
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
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;
}
}
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
상당히 길고 복잡해 보이지만, 편의 상 환경 변수들을 그대로 작성하여, 코드를 지워보겠다.
./bin/www 수정 후
const app = require("../app");
const http = require("http");
const port = process.env.PORT || "3000";
app.set("port", port);
const server = http.createServer(app);
server.listen(port);
이제 코드가 상당히 줄어들었다. 이것만 가지고도 서버가 동작하는 데에는 문제가 없다. 위 코드에서 변한 점은 var로 작성된 것을 const로 고치고, 함수로 되어 있던 부분을 지우고 디버깅을 제거해 간결하게 만든 것이 전부다. 이 상태에서 볼 때, 위 코드는 그저 우리가 만든 ( 또는 자동으로 생성된 ) app을 불러오고, http라는 프로토콜 위에 app을 올린 것이라고 볼 수 있다. 뒤에 포트가 3000이었던 이유 역시, 중간에 process.env.PORT가 없다면 3000 이라는 값을 쓰게 한 부분에서 확인할 수 있다.
server를 생성한 후 해당하는 포트에 맞게 listen을 해주면 서버 작성은 끝난다.
'프로그래밍' 카테고리의 다른 글
push한 git commit의 작성자 변경하기 (0) | 2023.02.01 |
---|---|
Express-generator로 기초적인 서버 만들기 (2) (0) | 2021.03.09 |
라즈베리파이로 집에 서버 설치하기 (0) | 2021.03.08 |
CRA npm run build 시 에러 발생 ( 일시적 해결 방법 ) (0) | 2021.03.07 |
쉘 스크립트와 crontab을 활용한 배포 자동화 (0) | 2021.03.07 |