관리자 글쓰기

문제

 

Node.js에 Webpack을 설치해서 프론트엔드 작업을 하던 중 async await 기능을 사용했더니 작동이 안 됐다.

콘솔 창을 확인해보니 regeneratorRuntime is not defined 라는 오류가 떴다.

 

해결

 

방법은 간단하다.

 

npm i regenerator-runtime

 

1. Node.js 터미널에 위의 명령어를 입력해서 regenerator-runtime 패키지를 다운로드한다.

 

import regeneratorRuntime from "regenerator-runtime";

 

2. 사용할 프론트엔드 Javascript 파일에서 regenerator-runtimeimport 한다.

 

 

 

 

 

 

[Node.js] 쿠키(Cookie), 세션(Session) Part 2
2021. 11. 2. 21:07 - 프론트맨

저번 포스팅에서는 쿠키와 세션의 개념 그리고 MongoDB에 연결하는 방법에 대해 정리했다.

이번 포스팅에는 세션을 사용하는 방법에 대해 구체적으로 알아보겠다.

2021.10.28 - [Programming/Node.js] - [Node.js] 쿠키(Cookie), 세션(Session) Part 1

 

 

쿠키와 세션에 대해 다시 정리해보자면 http는 Stateless(무상태 프로토콜)이다.

'브라우저의 요청과 서버의 응답'이라는 이벤트가 없을 시에 브라우저와 서버는 정보를 주고받지 않는다. 그러므로 사용자가 웹 페이지에서 나갔다 들어오면 서버는 사용자를 기억하지 못한다.

사용자에 대한 정보가 없기 때문이다.

만약 구글이나 네이버에 로그인하고 잠깐 창을 껐다 켰는데 다시 로그인해야 한다면 정말 불편할 것이다.

브라우저는 이러한 문제를 쿠키와 세션으로 해결했다.

 

 

쿠키에는 여러 가지 정보를 담을 수 있다. 서버는 사용자에게 쿠키에 정보를 담아서 줄 수 있다.

사용자가 브라우저를 통해 서버에 요청을 보내면 받은 쿠키도 함께 전송된다.

서버는 받은 쿠키로 사용자의 정보를 읽은 뒤 다시 쿠키를 전송한다.

 

 

쿠키가 사용자의 PC 메모리에 저장된다면 세션은 서버에 저장된다.

서버가 사용자의 세션을 생성하면 세션 ID도 같이 생성된다.

세션은 쿠키에 담겨 서버에 보내지는데 서버는 사용자의 세션 ID와

데이터베이스에 저장된 ID를 비교해서 유저를 인증한다.

 

 

여기까지 PART1에서 다뤘던 세션과 쿠키에 대해 간단히 정리해보았다.

그렇다면 서버는 언제, 누구에게 사용자의 쿠키, 세션을 생성해야 할까?

만약 로그인한 유저를 인증하기 위해 세션을 생성한다고 할 때 웹 페이지에

방문한 모든 사용자의 쿠키를 만든다면 그만큼 데이터베이스에도 저장해야 하고

결국 용량이 부담될 것이다.

이 때는 로그인 승인과 동시에 세션을 제공하면 로그인한 사용자에게만 전달될 것이다.

저번 포스팅에서처럼 express-session을 세팅했다면 그다음부터는 어렵지 않다.

 

import express from "express";
import session from "express-session";
import MongoStore from "connect-mongo";

const app = express();

app.use(
  session({
    secret: "asdfasfsdf",
    resave: false,
    saveUninitialized: false,
    cookie: {
      maxAge: 14 * 24 * 60 * 60 * 1000,
    },
    store: MongoStore.create({ mongoUrl: "mongodb://127.0.0.1:48945/project" }),
  })
);

app.listen(4000, () => {});

 

위의 코드처럼 saveUninitialized false로 지정하면 세션이 자동으로 생성되지 않는다.

세션을 생성하려면 데이터베이스에 유저의 정보가 저장될 때 세션의 값을 지정해야 된다.

 

import mongoose from "mongoose";

const accountSchema = new mongoose.Schema({
  id: { type: String, required: true },
  password: { type: String, required: true },
});

const Account = mongoose.model("Account", accountSchema);

export default Account;

 

유저의 아이디와 패스워드를 생성하는 데이터베이스 모델이다.

유저가 회원가입을 하면 위의 모델처럼 id, password가 생긴다.

 

로그인은 get이 아닌 post 방식으로 요청이 들어온다.

그러므로 controller를 post로 지정해야 한다.

 

app.post("/login", (req, res) => {
  req.session.loggedin = true;
  return res.redirect("/");
});

 

session은 req에서 접근할 수 있다.

위처럼 req.session의 요소를 직접 초기화하면 유저에게 세션을 줄 수 있다.

만약 유저가 로그인 여부에 따라 제공하는 기능을 다르게 하려면 아래의 코드로 간단하게 확인할 수 있다.

 

if(req.session.loggedIn){   # 로그인 되어있을 때
	} else{             # 비로그인 상태일 때
    }

 

 

 

 

 

[Node.js] 쿠키(Cookie), 세션(Session) Part 1
2021. 10. 28. 17:56 - 프론트맨

웹서버에서 로그인 기능을 구현할 때 유저를 인증해야 하는 상황이 생긴다.

예를 들어 구글을 방문할 때마다 로그인을 해야 한다면 정말 번거로울 것이다.

브라우저는 이런 번거로움을 줄이기 위해 쿠키와 세션을 사용한다.

 

 

쿠키(Cookie)

 

쿠키에는 유저의 정보를 담을 수 있다.

쿠키는 이름, 값, 만료일(저장 기간 설정), 경로 정보로 구성되어 있다.

웹서버는 클라이언트로부터의 요청에 응답하기 전 필요에 따라 쿠키를 생성해 유저에게 전달한다.

도메인마다 각각 다른 쿠키를 제공하는데, 만약 클라이언트가 같은 도메인에 다시 방문하면 

갖고 있던 쿠키를 서버에 전송하게 되고 서버는 쿠키에 있는 정보를 보고 유저를 인증한다.

쿠키는 텍스트 형태로 사용자의 PC에 저장되고 저장할 수 있는 용량에 한계가 있다.

 

 

세션(Session)

 

서버에 클라이언트의 상태 정보를 저장하는 기술이다.

브라우저는 클라이언트에게 Session ID를 부여하는데

이것을 쿠키에 넣어서 서버에 전송하면 서버는 Session ID를 보고 유저를 인증할 수 있다.

Object의 형태이며 사용자의 PC에 저장되는 쿠키와 달리 서버에 저장되고 용량 제한이 없다.

그리고 파일로 저장되는 쿠키에 비해 보안이 강하다는 장점이 있다.

 

 

 

Cookie, Session 사용법

 

Node.js에서 쿠키와 세션을 사용하는 방법이다.

 

npm i express-session

 

먼저 위의 명령어로 라이브러리를 설치해준다.

그리고 express-session 라이브러리를 import 한다.

 

const session = require('express-session')

 

package.json을 사용한다면 아래처럼도 가능하다.

import session from "express-session";

 

클라이언트가 아무것도 하지 않고 가만히 있는 동안에는 서버와의 교류가 없다.

클라이언트가 서버에 요청을 보내고 서버가 응답을 하는 순간에만 정보를 주고받을 수 있기 때문에

쿠키, 세션은 요청과 응답의 중간인 미들웨어를 통해서 구현해야 한다.

 

먼저 간단한 서버를 만들어보겠다.

 

import express from "express";

const app = express();

app.get("/", (req, res) => {
  res.send("Welcome!");
});
app.listen(4000, () => {});

 

화면에 Welcome! 을 출력해주는 간단한 서버이다.

이제 코드에 세션을 추가해보겠다.

 

import express from "express";
import session from "express-session";

const app = express();

app.use(
  session({
    secret: "asdfasfsdf",
    resave: false,
    saveUninitialized: false,
    cookie: {
      maxAge: 14 * 24 * 60 * 60 * 1000,
    },
  })
);
app.get("/", (req, res) => {
  res.send("Welcome!");
});
app.listen(4000, () => {});

 

앞서 말했듯이 미들웨어 함수인 app.use를 통해 세션을 생성해야 한다.

세션에는 여러 가지 매개변수를 설정할 수 있다.

 

secret

secret에 들어간 값을 이용해서 세션 ID가 생성된다.

보안상 중요한 값이기 때문에 .env 파일에 넣어서 사용해야 한다.

 

resave

 

세션 ID가 변경되지 않았을 때 다시 저장할 것인지를 설정할 수 있다.

웬만한 경우에는 다시 저장하는 것이 서버 작동 효율을 떨어뜨릴 수 있기 때문에 

false 값을 적용한다.

 

saveUninitialized

 

true 값을 적용하면 새로운 유저가 유입될 때마다 세션 ID를 생성한다.

모든 유저를 데이터베이스에 저장하면 용량이 부담되기 때문에

꼭 필요한 경우가 아니면 false 값을 적용한다.

보통은 유저가 로그인을 할 때 세션 ID를 생성한다.

 

cookie-MaxAge

 

쿠키의 사용 기간을 정한다.

밀리초 단위로 설정해야 하므로 위의 코드는 2주를 의미한다.

 

 

유저의 세션 ID를 생성하면 서버에도 세션 ID가 저장된다.

그래서 다음에 방문할 때 유저의 쿠키에 있는 세션 ID를 저장된 ID와 비교해서 유저를 인증할 수 있다.

하지만 세션 ID를 서버에 저장하면 서버가 재시작될 때마다 저장된 ID가 사라진다.

그래서 세션 ID는 데이터베이스에 저장해야 한다.

세션을 데이터베이스에 저장하려면 추가로 라이브러리를 설치해야 한다.

 

 

각각의 데이터베이스마다 설치방법이 다르지만 나는 MongoDB를 사용하기 때문에

 

npm i connect-mongo

 

import MongoStore from "connect-mongo";

 

위처럼 connect-mongo를 설치 후 import 해준다.

그리고 세션에 store값을 추가해준다.

 

import express from "express";
import session from "express-session";
import MongoStore from "connect-mongo";

const app = express();

app.use(
  session({
    secret: "asdfasfsdf",
    resave: false,
    saveUninitialized: false,
    cookie: {
      maxAge: 14 * 24 * 60 * 60 * 1000,
    },
    store: MongoStore.create({ mongoUrl: "mongodb://127.0.0.1:48945/project" }),
  })
);
app.get("/", (req, res) => {
  res.send("Welcome!");
});
app.listen(4000, () => {});

 

이렇게 MongoDB에 세션을 연결시킬 수 있다.

mongoUrl 역시 자신만 알 수 있게 .env 파일에 저장하는 것이 좋다.

 

 

이번 포스팅에서는 쿠키와 세션, 세션 설치 후 세팅, 그리고 MongoDB에 연결하는 것까지 알아봤다.

다음에는 세션을 어떻게 사용하는지 다뤄보겠다.

[Node.js] dotenv(.env)로 환경변수 만들기
2021. 10. 26. 23:29 - 프론트맨

웹 페이지를 만들다 보면 비밀스럽게 관리해야 할 값이 생긴다.

예를 들어 데이터베이스의 URL 주소나 (유저의 정보가 기록되어 있다.)

쿠키를 암호화하는 secret 변수, 고유 API 값과 같은 정보들을

다른 누군가가 볼 수 있다면 문제가 생길 것이다.

 

dotenv 라이브러리를 사용하면 비밀스러운 변수들을 한 파일에 모아놓을 수 있다.

 

dotenv 설치

 

npm install dotenv

 

dotenv를 설치한 후에는 .env 파일을 만든다.

파일 위치는 gitignore, package.json 파일과 같은 최상단에 위치해야 한다.

 

 

.env 파일에 사용할 변수 입력

 

// .env

DB_URL = "mongodb://127.0.0.1:49816/project"
API_KEY = "a4db08b7-5729-4ba9-8c08-f2df493465a1"

 

 

.gitignore에 .env 파일명 입력

 

// .gitignore

.env

 

github에 .env 파일이 공개되지 않게 .gitignore 파일에 .env 파일명을 적는다.

 

 

 

.env 파일 import

 

require("dotenv").config()

 

.env의 변수를 사용할 파일에서 위의 코드를 입력하면 된다.

.env 파일은 가능한 한 빨리 import 하는 것이 좋다.

 

위처럼 import 하는 방식은 .env 변수를 쓸 파일마다 위의 코드를 적어야 한다.

서버를 만들면 파일끼리 연결되어 있는 게 보통이기 때문에

실행하는 파일 하나에만 아래의 코드를 입력하는 것이 편리하다.

 

import "dotenv/config";

 

.env 변수 사용하기

 

process.env.(변수명) 의 형태로 사용하면 된다.

예를 들어 데이터베이스를 생성할 때 DB의 URL이 필요한데

위에서 만든 변수를 활용해서 아래와 같이 입력할 수 있다.

 

mongoose.connect(process.env.DB_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

 

 

 

[Node.js] bcrypt로 패스워드 암호화하기
2021. 10. 26. 22:24 - 프론트맨

유저가 계정을 생성할 때 비밀번호를 그대로 데이터베이스에 저장하면

사이트가 해킹당했을 때 유저의 정보까지 넘어가는 최악의 상황이 생길 것이다.

Hash를 사용하면 비밀번호를 암호화해서 유저의 데이터를 안전하게 보관할 수 있다.

 

 

Hash란?

Hash는 수학으로 만들어진 암호화 알고리즘이다.

만약 A라는 인풋을 Hash에 넣으면 항상 B라는 같은 아웃풋이 나온다.

그리고 Hash는 일방적이므로 B에서 거꾸로 A를 유추하는 것이 불가능하다.

 

해쉬 함수는 인풋이 비슷해도 아웃풋은 완전히 다르다.

예를 들어 HelloHello! 는 완전히 다른 결과를 나타낸다.

 

Hello

185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

 

Hello! →

334d016f755cd6dc58c53a86e183882f8ec14f52fb05345887c8a5edd42c87b7

 

 

사용방법

1. 유저가 계정을 생성하는 즉시 비밀번호를 암호화해서 데이터베이스에 저장한다.

 

2. 유저가 로그인할 때, 입력받은 비밀번호를 같은 방법으로 암호화한 다음 데이터베이스와 비교한다.

 

서버는 유저의 비밀번호가 뭔지 모른다. 

같은 인풋이면 항상 같은 아웃풋이 나오는 해쉬 함수의 원리를 이용해서

암호화된 비밀번호끼리 비교할 수 있다.

 

 

 

 

먼저 비밀번호를 암호화하는 방법이다.

Node.js에서는 bcrypt 라이브러리로 해쉬 함수를 쉽게 사용할 수 있다.

유저가 입력한 정보를 데이터베이스에 저장하기 직전에 

Mongoose의 미들웨어 함수를 사용해서 비밀번호를 암호화한다.

Mongoose와 MongoDB에 대해서 궁금하다면 아래의 글을 참조하기 바란다.

 

MongoDB 데이터 생성, 삭제하는 방법

웹 서버를 운영하려면 데이터베이스가 필요하다. 물론 단순한 웹페이지 같은 경우는 예외겠지만 로그인 같은 기본적인 기능만 넣으려 해도 필수적으로 있어야 하는 것이 데이터베이스다. MongoDB

squidcoding.tistory.com

 

 

 

유저의 계정을 생성하는 모델이다.

bcrypt.hash 메서드에는 두 개의 매개변수가 들어가는데 

첫째는 변환할 문자열

두 번째는 Salting 할 횟수이다.

 

Salting은 말 그대로 소금 친다는 의미인데,

문자열을 해쉬 함수에 넣기 전에 임의의 문자열을 덧붙여서

보안을 강화하는 방법이다.

 

터미널에서 암호화된 비밀번호가 데이터베이스에 저장된 것을 확인할 수 있다.

 

 

이제 입력받은 비밀번호를 데이터베이스의 비밀번호와 비교해야 한다.

 

const userId = "abc";
const userPW = "1234";

const checkPW = async () => {
  const user = await Account.findOne({ id: userId }); // 데이터베이스에서 Account 모델 찾기
  const checkPW = await bcrypt.compare(userPW, user.password); 
  console.log(checkPW);
};
checkPW();

 

먼저 입력받은 id로 Account 모델을 찾아서 user 변수에 저장한다.

그리고 bcrypt.compare 메서드에 매개변수로 (입력받은 PW, DB에 있는 PW) 를 넣으면 된다.

 

코드를 실행해보면 true가 출력된다.

만약 틀린 비밀번호를 입력하면 false가 출력된다.

 

 

MongoDB 데이터 생성, 삭제하는 방법
2021. 10. 23. 23:53 - 프론트맨

웹 서버를 운영하려면 데이터베이스가 필요하다.

물론 단순한 웹페이지 같은 경우는 예외겠지만

로그인 같은 기본적인 기능만 넣으려 해도

필수적으로 있어야 하는 것이 데이터베이스다.

 

MongoDB는 유명한 데이터베이스로 Mongoose와 같이 사용하면

자바스크립트로 많은 기능을 다룰 수 있다.

 

오늘은 Mongoose와 MongoDB의 기본 사용법에 대해 다뤄보았다.

 

1. MongoDB 서버에 연결하기                             

2. 모델 생성하기                             

3. MongoDB 터미널에서 직접 데이터 다루기

 

 

MongoDB 서버에 연결하기

먼저 MongoDB가 서버에 연결되어 있어야

서버에서 데이터베이스에 값을 넣고 빼올 수가 있다.

 

// database.js

import mongoose from "mongoose";

mongoose.connect("mongodb://127.0.0.1:27017/project", {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

 

따로 database.js 라는 파일을 만들었다.

mongodb://127.0.0.1:27017/project

connect 메서드의 인자로 위의 내용을 입력해야 하는데

MongoDb를 실행했을 때 나오는 id와

만들고 싶은 데이터베이스의 이름(project)을 입력해야 한다.

그대로 실행하면 콘솔 창에 경고가 나오는데 

두 번째 인자를 입력해서 경고를 없앨 수 있다.

 

그리고 서버를 돌리는 파일에서 위의 파일명을 업로드하면 데이터베이스가 생성되다.

 

import "./db";

 

모델 생성하기

 

Mongoose에서는 데이터를 저장할 형식을 지정할 수 있다.

이것을 스키마라고 하는데 사용자가 데이터를 입력하면 

값을 데이터베이스에 넣기 전에 검사해서 지정한 형식이 아니면 에러를 발생시킨다.

 

사람의 프로필을 생성하는 모델이다.

 

import mongoose from "mongoose";

const personSchema = new mongoose.Schema({
  name: { type: String, required: true },
  age: { type: Number, default: 20 },
  height: Number,
  weight: Number,
});

 

new 키워드로 스키마를 생성해서 변수에 넣어준다.

지정할 형식이 두 개 이상이면 중괄호를 사용하고

하나만 있으면 생략해도 된다.

 

required: true 는 사용자가 필수로 입력하도록 설정하는 것이다.

default 는 사용자가 입력하지 않았을 때 기본값을 지정한다.

 

 

 

이렇게 정의된 스키마는 모델로 등록해서 사용할 수 있다.

 

const Person = mongoose.model("Person", personSchema);

 

mongoose.model 메서드의 첫 번째 인자는 MongoDB에 들어갈 이름,

두 번째는 지정한 스키마 변수 이름이다.

 

이제 Person 변수로 데이터를 만들 수 있다.

 

Person.create({
  name: "James",
  age: 20,
  height: 180,
  weight: 80,
});

 

create 메서드로 간단하게 데이터를 생성할 수 있다.

물론 보통은 직접 입력하는 것보다 사용자에게 입력받은 데이터를 사용한다.

 

 

 

MongoDB 터미널에서 직접 데이터 다루기

 

위에서 생성한 데이터를 MongoDB 터미널에서 직접 다루는 것도 가능하다.

터미널에서 MongoDB를 실행하면 이상한 문자가 쫙 뜨면서 > 모양의 화살표가 나온다.

그 화살표 옆에 명령어를 입력하면 된다.

 

MongoDB 실행화면

 

만약 명령어에 대해서 모르거나 기억이 안 나면

help 명령어를 입력하면 기본 명령어와 설명이 나온다.

 

 

먼저 show dbs를 입력하면 데이터베이스 목록이 나온다.

나 같은 경우는 위에서 입력한 project 가 나왔다.

 

 

데이터베이스 안으로 들어가려면 use(데이터베이스명)을 입력한다.

나는 use project 를 입력했다.

switched to db project 라는 문구가 뜨면 정상적으로 실행된 것이다.

 

 

아까 생성한 Person 모델을 보려면 show collections 를 입력하면 된다.

여기서 특이한 점이 있는데 우리가 지은 모델명과는 다른 걸 볼 수 있다.

이유는 모르겠지만 MongoDB는 모델명을 소문자 그리고 복수형으로 알아서 변경한다.

아까 생성한 Personpeople로 변경되어 있었다.

 

 

db.(모델명).find() 를 입력하면 모델 안의 데이터가 출력된다.

ex) db.people.find()

 

 

만약 모델 안에 많은 데이터가 들어있고 그중에 삭제하고 싶은 것이 있다면

db.(모델명).remove({}) 를 사용할 수 있다.

엔터를 치면 WriteResult({ "nRemoved" : 1 }) 라는 문구가 뜨는데

지운 데이터의 개수를 의미한다.

 

중괄호 안에는 속성을 입력해서 원하는 데이터를 삭제할 수 있다.

ex) db.people.remove({name:"James"})

만약 아무것도 입력하지 않으면 모두 삭제된다.

 

 

remove를 사용하면 데이터는 삭제되지만 모델 자체는 삭제되지 않는다.

db.(모델명).drop()을 입력하면 true를 반환하면서 모델이 삭제된다.

ex) db.people.drop() 

[Node.js] Mongoose 설치하기
2021. 10. 20. 23:00 - 프론트맨

서버에서 사용할 데이터베이스가 필요해서 MongoDB를 설치했다.

그다음으로 MongoDB와 자바스크립트를 연결하는 라이브러리가 필요한데

Mongoose가 그중 가장 유명하다.

오늘은 Mongoose를 설치하고 

 

먼저 터미널에 아래의 코드를 입력한다.

 

npm i mongoose

 

설치가 끝나면 새 파일을 만들어서 mongoose 라이브러리를 import 한다.

 

// database.js

import mongoose from "mongoose";

mongoose.connect("mongodb://127.0.0.1:27017/project");

 

그리고 MongoDB와 연결해야 하는데 mongoose.connect의 값으로는 

MongoDB를 실행시켰을 때 나오는 url 주소 + 데이터가 들어갈 폴더명 적는다.

 

MongoDB 실행

 그리고 마지막으로 메인으로 사용할 자바스크립트 파일에서 

database.js 파일을 import 하면 된다.

 

// main.js

import "./database";

 

그냥 파일의 주소만 적으면 그 뒤는 자바스크립트가 알아서 해준다.

나 같은 경우는 database.js 파일이 같은 주소에 있어서 위처럼 입력했다.

확장자  .js  는 생략해도 된다.

[Node.js] Pug - mixin을 활용한 파일 정리
2021. 10. 20. 16:15 - 프론트맨

Pug에서는 데이터를 불러와서 바로 html에 출력할 수 있다.

그러나 만약 데이터를 처리하는 부분이 길어진다면 코드가 복잡해질 것이다.

이럴 때 mixin을 사용해서 코드를 파일로 분리할 수가 있다.

 

 

단순히 코드 블록을 include 하는 것과의 차이점은 

mixin은 데이터를 다룬다는 것이다.

마치 함수를 만드는 것과 같다.

 

다음은 사람의 프로필을 출력하는 페이지이다.

 

// main.js

import express from "express";
const app = express();

const profiles = [ 	// 프로필 생성
  { name: "민석", age: "21", height: 175, job: "백수" },
  { name: "상윤", age: "21", height: 173, job: "프로게이머" },
  { name: "동희", age: "22", height: 180, job: "군인" },
];

const profile = (req, res) => { 
  return res.render("profile", { profiles }); // profile.pug에 profiles 넘겨줌
};

app.get("/profile", profile);
app.set("view engine", "pug");

app.listen(4000, () => {});

 

변수 profiles에 프로필을 object 형태로 저장하고

profile.pug 파일에 넘겨주었다.

 

이제 profile.pug에서 반복문으로 프로필을 출력한다.

 

// profile.pug

doctype html
html(lang="en")
    head
        title profile
    body 
        each profile in profiles 
            div 
                h3 #{profile.name}
                ul 
                    li 나이: #{profile.age}
                    li 키: #{profile.height}
                    li 직업: #{profile.job}

 

Pug에서는 each in 을 사용해서 배열이나 객체에 접근할 수 있다.

 

출력 결과

출력 결과

여기서 mixin을 사용하면 파일로 나눌 수가 있다.

 

// controllProfile.pug

mixin controllProfile(profile)
    div 
        h3 #{profile.name}
        ul 
            li 나이: #{profile.age}
            li 키: #{profile.height}
            li 직업: #{profile.job}

 

mixin 함수명(매개변수) 형식으로 사용한다.

함수 선언과 비슷하다.

 

그리고 작성한 mixin 파일을 불러오면 된다.

 

// profile.pug

include controllProfile

doctype html
html(lang="en")
    head
        title profile
    body 
        each profile in profiles 
            +controllProfile(profile)

 

위에서 mixin 파일을 include 하고 

아래에서 +함수명(매개변수) 형식으로 함수를 호출하면 끝이다.

 

결과 화면

출력 결과

 

웹사이트가 커질수록 데이터베이스도 점점 커지게 된다.

그럴 때 mixin 기능을 잘 활용하면 깔끔하게 코드를 작성할 수 있을 것이다.

[Node.js] Pug - partial (복붙 최소화하기)
2021. 10. 20. 12:21 - 프론트맨

만약 똑같은 부분을 모든 파일에 복붙 한다면 굉장히 귀찮을뿐더러

수정할 곳이 생긴다면 모든 파일에 들어가서 하나하나 바꿔야 된다는 불상사가 생길 것이다.

 

다행히도 Pug는 html 파일을 따로 나눠서 include, extends 하는 기능을 제공한다.

이 기능을 사용하면 수정할 곳이 생겨도 파일 하나만 수정하면 모든 파일에 변경이 적용된다.

 

 

include

 

만약 모든 페이지마다 footer를 달아야 한다면 include를 사용할 수 있다.

먼저 footer.pug 파일을 만든다.

 

// footer.pug

footer COPYRIGHT(C) 2021 ALL RIGHTS RESERVED.

 

이제 다른 Pug 파일에서 footer.pug의 경로를 include 하면 된다.

 

// hello.pug

doctype html
html(lang="en")
    head
        meta(charset="UTF-8")
        meta(http-equiv="X-UA-Compatible", content="IE=edge")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        title Document
    body 
        h1 hello
    
    include footer1.pug

결과 출력

 

실행해보면 위의 결과가 나오는 것을 확인할 수 있다.

만약 footer의 내용을 수정하려면 footer.pug만 바꿔주면 된다.

 

 

 

extends

 

html 파일에는 doctype부터 html, head, body까지 겹치는 부분이 정말 많다.

extends를 사용하면 그런 불편함을 줄일 수 있다.

기본적인 틀을 가진 한 파일만 만들면 다른 파일에선 extends 기능으로 불러올 수 있다.

 

// base.pug

doctype html
html(lang="en")
    head
        meta(charset="UTF-8")
        meta(http-equiv="X-UA-Compatible", content="IE=edge")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        title Document
    body 
        header
        	block header	// block을 지정
        main
        	block content
    
    include footer1.pug

 

기본적인 틀 외에 각 페이지마다 다른 곳은 위처럼 block을 이름과 함께 지정할 수 있다.

 

이제 다른 파일에서 base.pug를 extends 하면 된다.

 

// hello.pug

extends numList.pug 

block header 
    h1 페이지에 오신 걸 환영합니다

block content 
    h2 Hello

base.pug에서 지정한 block의 이름을 적고 그 아래에 내용을 적으면 된다.

 

실행 결과

 

이렇게 include와 extends를 활용하면

똑같이 사용하는 내용을 한 파일에서 다룰 수 있다는 엄청난 장점이 있다.

Pug를 사용한다면 이 기능은 필수인 것 같다

[Node.js] Pug 라이브러리 설치 및 사용법
2021. 10. 19. 21:57 - 프론트맨

Node.js의 res.send를 사용하면 간단하게 페이지에 문자를 띄울 수 있다.

하지만 페이지가 복잡해지고 자바스크립트 문법까지 들어간다면 한계에 부딪힐 것이다.

 

Pug 라이브러리를 사용하면 간편하게 html을 작성할 수 있고

기본적인 자바스크립트 문법도 같은 파일에 작성할 수 있다.

 

 

먼저 Pug를 설치하는 방법이다.

터미널의 아래의 코드를 입력한다.

 

npm install pug

 

Pug와 Express를 연동하려면 Express의 기본값 세팅을 바꿔줘야 한다.

 

Express 공식문서

 

app.set 메서드로 view engine을 Pug로 변경한다.

 

app.set("view engine", "pug");

 

위의 공식문서를 보면 view와 관련된 파일은 views 폴더 안에 넣어야 한다고 나와있다.

views라는 폴더를 만들고 그 안에 main.pug와 같은 형식의 파일을 만든다.

 

만약에 views 폴더가 제일 위에 있지 않고 다른 폴더에 감싸 져 있다면 

한 가지 더 설정을 해주어야 한다.

( project/views O

  project/src/views X )

 

만약 위와 같이 scr폴더 안에 views 폴더를 넣고 싶다면 app.set으로 설정을 변경한다.

app.set("views", process.cwd() + "/src/views");

"views"의 기본값은 process.cwd() + /'views'이다.

 

 

 

Pug의 편리한 점은 html 코드에서 태그를 닫지 않아도 된다는 점이다.

 

1에서 5까지의 list를 화면에 출력하는 예제이다.

 

// numList.pug

doctype html
html(lang="ko")
    head
        title Document
    body 
        ul
            li 1
            li 2
            li 3
            li 4
            li 5

 

Pug는 Python처럼 탭으로 각 태그를 구분한다. 

이제 위의 numList.pug 파일을 main.js 파일에 연결한다.

 

// main.js

import express from "express";
const app = express();

const num = (req, res) => {
  return res.render("numList");
};

app.get("/num", num);
app.set("view engine", "pug");


app.listen(4000, () => {});

 

res.render 메서드에 pug 파일의 이름을 넣으면 pug의 내용이 화면에 출력된다.

 

출력 결과

 

1~5를 변수로 만드는 것도 가능하다.

 

// main.js

import express from "express";

const app = express();

const num = (req, res) => {
  const count = 1;
  return res.render("numList", { count: count });
};

app.get("/num", num);
app.set("view engine", "pug");


app.listen(4000, () => {});

 

count 변수를 선언하고 object 형태로 numList.pug 파일에 넘겨준다.

 

// numList.pug

doctype html
html(lang="ko")
    head
        title Document
    body 
        ul
            li #{count++}
            li #{count++}
            li #{count++}
            li #{count++}
            li #{count++}

 

위에서 넘겨받은 count 변수를 #{ } 안에서 사용할 수 있다.

실행해보면 같은 결과가 나타나는 것을 확인할 수 있다.

 

출력 결과