728x90
반응형
Selenium을 파이썬에서만 쓸 수 있을 줄 알았는데 NodeJS에서도 된다는 말을 듣고 javascript로 만들어볼까 한다.
1. Chrome 을 다운로드한다.
https://www.google.com/chrome/index.html
2. 아래 사진처럼 크롬 버전을 익혀둔다.
3. 크롬 버전을 확인했으면 앞자리 수에 맞는 크롬 드라이버를 설치한다.
4. 윈도우로 설치해준다. ( 버전은 다를 수 있습니다. )
5. 압축을 해제한 후 해당 파일 경로를 알아둔다. ( 나중에 셀레니움에서 사용 )
5. NodeJS와 VSCode를 설치한다.
https://nodejs.org/ko/download/
개인적으로 생각하는 쓰기 좋은 vscode typescript 확장들
- ES7+ React/Redux/React-Native snippets
- ESLint
- Live Server
- Prettier
6. npm init 및 필요 구성 모듈을 설치해준다.
$ npm init
$ npm i express typescript ts-node nodemon @types/node @types/express
7. typscript를 위한 옵션을 설정하기 위해 다음 명령어를 입력해준다.
$ npx tsc --init
/tsconfig.json
{
"compilerOptions": {
"target": "es6", // 어떤 버전으로 컴파일할지 작성
"module": "commonjs", //어떤 모듈 방식으로 컴파일할지 설정
"outDir": "./dist", //컴파일 후 js 파일들이 생성되는 곳
"rootDir": ".", //루트 폴더
"strict": true, //strict 옵션 활성화
"moduleResolution": "node", //모듈 해석 방법 설정: 'node' (Node.js)
"esModuleInterop": true,
"jsx": "react"
}
}
8. app.ts 파일을 만든다.
/app.ts
import express, { Request, Response, NextFunction } from 'express';
const app = express();
app.get('/welcome', (req: Request, res: Response, next: NextFunction) => {
res.send('welcome!');
});
app.listen('1234', () => {
console.log(`
################################################
🛡️ Server listening on port: 1234🛡️
################################################
`);
});
9. pakage.json 파일을 수정해준다.
...
"scripts": {
"start": "node dist/app.js",
"build": "tsc -p .",
"dev": "nodemon --watch \"src/**/*.ts\" --exec \"ts-node\" app.ts"
}
...
- build : typscript 파일을 js 파일로 컴파일해준다.
- start : 컴파일한 js 파일로 서버를 실행한다.
10. 빌드하고 시작해본다.
$ npm run build
$ npm run start
정상적으로 뜨는 것을 확인할 수 있다.
또한 내가 express를 쓸 때 기본적으로 사용하는게 body-parser와cookie-parser, dotenv인데, 자세한 내용은 검색하면 나온다.
나중에 json 형식으로 통신할 때나 쿠키를 사용할 때, 중요한 정보를 환경 변수로 사용할 때 대비하자.
11. body-parser , cookie-parser, dotenv를 설치한다.
$ npm install --save body-parser @types/body-parser cookie-parser @types/cookie-parser dotenv
12. app.ts 파일을 수정해준다.
import express, { Request, Response, NextFunction } from 'express';
// parser
import bodyParser from 'body-parser';
import cookieParser from 'cookie-parser';
// dotenv
import dotenv from 'dotenv'
dotenv.config();
const app = express();
app.use(bodyParser.json())
app.use(cookieParser())
app.get('/welcome', (req: Request, res: Response, next: NextFunction) => {
res.send('welcome!');
});
app.listen('1234', () => {
console.log(`
################################################
🛡️ Server listening on port: 1234🛡️
################################################
`);
});
13. 좀 더 짜임새있는 구조를 위해 미리 폴더들을 만들어두자.
14. routers 밑에 파일을 만들고, app.ts 파일을 수정해준다.
/routers/one.ts
import express, { Request, Response, NextFunction } from 'express';
var router = express.Router();
router.get('/', async function (req: Request, res: Response, next: NextFunction) {
res.send('welcome!');
});
export default router;
/app.ts
import express, { Request, Response, NextFunction } from 'express';
// parser
import bodyParser from 'body-parser';
import cookieParser from 'cookie-parser';
// router
import oneRouter from './routers/one'
const app = express();
app.use(bodyParser.json())
app.use(cookieParser())
app.use('/one',oneRouter)
app.listen('1234', () => {
console.log(`
################################################
🛡️ Server listening on port: 1234🛡️
################################################
`);
});
15. logging 미들웨어를 만들기 위해 다음 명령어로 설치해준다.
$ npm install winston @types/winston winston winston-daily-rotate-file
/config/winston.ts
import winston, { info } from 'winston';
import winstonDaily from 'winston-daily-rotate-file';
const logDir = 'logs'; // logs 디렉토리 하위에 로그 파일 저장
const { combine, timestamp, printf } = winston.format;
// Define log format
const logFormat = printf(info => {
return `${info.timestamp} ${info.level}: ${info.message}`;
});
/*
* Log Level
* error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6
*/
const loggerError = winston.createLogger({
format: combine(
timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
logFormat,
),
transports: [
// error 레벨 로그를 저장할 파일 설정
new winstonDaily({
level: 'info',
datePattern: 'YYYY-MM-DD',
dirname: logDir + '/error', // error.log 파일은 /logs/error 하위에 저장
filename: `%DATE%.error.log`,
maxFiles: 30,
watchLog: true,
zippedArchive: true,
}),
],
});
const loggerInfo = winston.createLogger({
format: combine(
timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
logFormat,
),
transports: [
// info 레벨 로그를 저장할 파일 설정
new winstonDaily({
level: 'info',
datePattern: 'YYYY-MM-DD',
dirname: logDir + '/info',
filename: `%DATE%.info.log`,
maxFiles: 30, // 30일치 로그 파일 저장
watchLog: true,
zippedArchive: true,
}),
],
});
const loggerHttp = winston.createLogger({
format: combine(
timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
logFormat,
),
transports: [
// http 레벨 로그를 저장할 파일 설정
new winstonDaily({
level: 'info',
datePattern: 'YYYY-MM-DD',
dirname: logDir + '/http',
filename: `%DATE%.http.log`,
maxFiles: 30, // 30일치 로그 파일 저장
watchLog: true,
zippedArchive: true,
}),
],
});
const loggerDebug = winston.createLogger({
format: combine(
timestamp({
format: 'YYYY-MM-DD HH:mm:ss',
}),
logFormat,
),
transports: [
// debug 레벨 로그를 저장할 파일 설정
new winstonDaily({
level: 'info',
datePattern: 'YYYY-MM-DD',
dirname: logDir + '/debug',
filename: `%DATE%.debug.log`,
maxFiles: 30,
watchLog: true,
zippedArchive: true,
}),
],
});
// Production 환경이 아닌 경우(dev 등)
if (process.env.NODE_ENV !== 'production') {
loggerInfo.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(), // 색깔 넣어서 출력
winston.format.simple(), // `${info.level}: ${info.message} JSON.stringify({ ...rest })` 포맷으로 출력
)
}));
}
// Production 환경이 아닌 경우(dev 등)
if (process.env.NODE_ENV !== 'production') {
loggerError.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(), // 색깔 넣어서 출력
winston.format.simple(), // `${info.level}: ${info.message} JSON.stringify({ ...rest })` 포맷으로 출력
)
}));
}
if (process.env.NODE_ENV !== 'production') {
loggerHttp.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(), // 색깔 넣어서 출력
winston.format.simple(), // `${info.level}: ${info.message} JSON.stringify({ ...rest })` 포맷으로 출력
)
}));
}
if (process.env.NODE_ENV !== 'production') {
loggerDebug.add(new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(), // 색깔 넣어서 출력
winston.format.simple(), // `${info.level}: ${info.message} JSON.stringify({ ...rest })` 포맷으로 출력
)
}));
}
export {
loggerInfo,
loggerError,
loggerHttp,
loggerDebug,
};
/middlewares/index.ts
export * from "./http"
/middlewares/http.ts
import express, { Request, Response, NextFunction } from 'express';
import {
loggerInfo,
loggerError,
loggerHttp,
loggerDebug,
} from '../config/winston'
interface LOGSTR {
url : string;
method : string;
query? : Object;
body? : Object;
}
export const httpLoggingMiddleware = async (req: Request, res: Response, next: NextFunction) => {
let logStr: LOGSTR = {
url : "",
method: "",
query: "",
body: "",
}
try {
// 접속 경로
logStr.url = req.originalUrl;
// 메소드
logStr.method = req.method;
switch (req.method) {
case 'GET':
logStr.query = req.query;
break;
case 'POST':
logStr.body = req.body;
break;
case 'PATCH':
logStr.body = req.body;
break;
case 'DELETE':
logStr.query = req.query;
break;
}
loggerHttp.info(JSON.stringify(logStr))
next();
}
catch (Err) {
loggerError.info(Err)
res.send({ success: false });
}
}
/routers/one.ts
import express, { Request, Response, NextFunction } from 'express';
var router = express.Router();
// middlewares
import { httpLoggingMiddleware } from '../middlewares'
// logger
import {
loggerHttp,
loggerDebug,
loggerError,
loggerInfo
} from '../config/winston';
router.get('/',httpLoggingMiddleware, async function (req: Request, res: Response, next: NextFunction) {
res.send('welcome!');
});
export default router;
16. /one 라우터에 접근해보고 로그 데이터가 잘 생성되는지 확인한다.
get 메소드는 브라우저 url 창에 입력해도 된다.
728x90
반응형