Express 기본 구조 만들기
❥ npm init -y 로 시작 -> package.json 파일이 생성된다.
협업 시 package.json 파일만 건네주면 동일한 환경으로 개발이 가능해진다. (해당 파일을 넣어주고 npm install 로 설치 가능)
❥ .gitignore 파일에 node_modules/ 를 추가하여 노드 모듈은 깃 관리 대상에서 빼주는 게 좋다.
❥ 개발 후에도 필요한 모듈 설치하기
1. express
2. cors
3. ejs
세 가지는 npm i -S 로 설치해주기 -> 한번에 다 설치하려면 구분자는 공백으로 지정 npm i -S express cors ejs
❥ 개발에서만 필요한 모듈 설치하기
npm i -D 로 설치해주기
1. prettier
2. eslint / eslint-config-airbnb-base / eslint-plugin-import
npm i -D prettier eslint eslint-config-airbnb-base eslint-plugin-import
❥ .prettierrc 와 .eslintrc.js 파일 생성, .vscode 폴더와 그 안에 settings.json 파일 생성
// eslintrc.js
module.exports = {
extends: ['airbnb-base'],
rules: {
'no-console': 'off',
'no-plusplus': 'off',
},
};
// .prettierrc
{
"semi" : true,
"singleQuote" : true
}
// settings.json
{
"[javascript]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "j69.ejs-beautify",
},
"emmet.includeLanguages" : {
"ejs" : "html"
}
}
서버 기본 코드 작성
// 필요한 패키지 불러오기
const express = require('express');
const cors = require('cors');
// express 를 실행
const app = express();
const PORT = 4000;
// 서버에 필요한 기능들 설정
app.use(cors());
// 서버 실행
app.listen(PORT, () => {
console.log(`${PORT} 에서 서버 구동 중. . .`);
});
라우팅 기능 사용하기
모든 요청을 하나의 주소에서 받으면 병목현상이 발생하게 된다 -> Routing 으로 주소를 나눠준다!
특정 요청은 특정 주소로만 요청이 들어오도록 처리하고 해당 요청은 하나의 파일에 몰아서 처리하도록 설정해준다.
메인 화면 라우팅하기
const express = require('express');
const cors = require('cors');
const mainRouter = require('./routes/index');
const app = express();
const PORT = 4000;
app.use(cors());
app.set('view engine', 'ejs');
app.use('/', mainRouter);
app.listen(PORT, () => {
console.log(`${PORT} 에서 서버 구동 중. . .`);
});
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index');
});
module.exports = router;
유저 화면, 게시글 라우팅
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const app = express();
const PORT = 4000;
const mainRouter = require('./routes/index');
const userRouter = require('./routes/users');
const boardRouter = require('./routes/board');
app.use(cors());
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/', mainRouter);
app.use('/users', userRouter);
app.use('/board', boardRouter);
app.use((err, req, res, next) => {
console.log(err.stack);
res.status(err.statusCode);
res.render(err.message);
});
app.listen(PORT, () => {
console.log(`${PORT} 에서 서버 구동 중. . .`);
});
const express = require('express');
const router = express.Router();
// Temp Data
const USER = [
{
id: 'test',
password: '1234',
name: '테스트',
},
{
id: 'admin',
password: '123',
name: '관리자',
},
];
router.get('/', (req, res) => {
if (req.body.id && req.body.password) {
let findUser = USER.find((value) => {
return req.body.id === value.id && req.body.password === value.password;
});
if (findUser) {
res.render('users', { USER, findUser });
} else {
const err = new Error('로그인 실패');
err.statusCode = 400;
throw err;
}
} else if (req.query.id && req.query.password) {
let findUser = USER.find((value) => {
return req.query.id === value.id && req.query.password === value.password;
});
if (findUser) {
res.render('users', { USER, findUser });
} else {
const err = new Error('로그인 실패');
err.statusCode = 400;
throw err;
}
} else {
const err = new Error('입력값이 잘못 들어왔습니다.');
err.statusCode = 400;
throw err;
}
});
module.exports = router;
const express = require('express');
const router = express.Router();
const ARTICLE = [
{
title: '첫글 제목',
content: '첫글 내용입니다.',
},
{
title: '두번째글 제목',
content: '두번째글 내용입니다.',
},
];
router.get('/', (req, res) => {
res.render('board', { ARTICLE, articleCounts: ARTICLE.length });
});
// 글쓰기 이동
router.get('/write', (req, res) => {
res.render('board_write');
});
// 글 추가
router.post('/write', (req, res) => {
if (req.body.title && req.body.content) {
const newArticle = {
title: req.body.title,
content: req.body.content,
};
ARTICLE.push(newArticle);
res.redirect('/board');
} else {
const err = new Error('글 쓰기 오류');
err.statusCode = 404;
throw err;
}
});
// 글 수정 이동
router.get('/modify/:title', (req, res) => {
const arrIndex = ARTICLE.findIndex(
(value) => value.title === req.params.title
);
const findArticle = ARTICLE[arrIndex];
res.render('board_modify', { findArticle });
});
// 글 수정
router.post('/modify/:title', (req, res) => {
if (req.body.title && req.body.content) {
const arrIndex = ARTICLE.findIndex(
(value) => req.params.title === value.title
);
ARTICLE[arrIndex] = {
title: req.body.title,
content: req.body.content,
};
res.redirect('/board');
} else {
const err = new Error('글 수정 오류');
err.statusCode = 404;
throw err;
}
});
// 글 삭제
router.delete('/delete/:title', (req, res) => {
const arrIndex = ARTICLE.findIndex(
(value) => req.params.title === value.title
);
ARTICLE.splice(arrIndex, 1);
res.send('삭제 완료');
});
module.exports = router;
글의 제목으로 인덱스에 접근하는 방식이었다.
알듯말듯... 그래도 express 의 기본 구조는 좀 이해가 되는 것 같기도 하다.