[DSC] Node + React로 웹 플랫폼 제작기 2주차

600g (Kim Dong Geun)·2020년 5월 10일
3
post-custom-banner

2주차 할 것

  • Lambda Function 설명
  • Request,Response 설치
  • Express Framework 설치
  • Express.js 살펴보기
  • http method 설명
  • React 설치
  • 리액트 파일 구조 설명
  • 버튼 커스텀 하기

Lambda 함수란?

우리는 기존의 언어에서 함수를 선언 할 때, 항상 이름을 명시했어요.

function helloworld(){
	//내용들
}

위 처럼 말이죠.

자바같은 경우 함수를 인자로 전달할 수 없었기 때문에, 함수가 이름을 가지는건 당연했어요.

그런데 javascript는 변수나 함수의 인자로 함수를 전달 할 수 있어요.

이것을 일급 함수라고 하는데 용어만 기억해두시고 넘어가도 되는 부분입니다.

(참고: 자바는 일급객체는 맞지만 일급 함수는 될 수 없어요)
(참고2: 자바스크립트는 일급객체와 일급함수 모두 맞아요)

아무튼 코드로 예를들어보겠습니다.

const printHello = function helloWorld(){
	console.log("helloworld");
};

위처럼 변수에 함수의 값을 할당하거나

function Helloworld(runFucntion){
  console.log("start Function");	
  runFunction();
}

Helloworld(function() {
console.log("helloworld")}
);

함수의 인자로 또 함수가 들어가는게 가능했죠.

함수를 인자로 작성하는데 있어 1회성으로 함수가 들어가는 경우가 생겼어요.

그런데 그런 경우에 이름을 매번 붙여주기가 프로그램을 작성하는데 효율적이지 못했어요.

그래서 나온 것이 익명함수에요.

익명함수를 한번 적용해볼께요.

[익명함수 적용 전]

const printHello = helloWorld;

function helloWorld(){
  console.log("hello world!");
}

[익명함수 적용 후]

const printHello= function(){
	console.log("hello world");
}

함수의 이름을 붙이지 않아도 printHello라는 변수가 이 함수를 들고 있기때문에
printHello()를 실행시키면, 코드를 좀 더 줄이고 빠르게 프로그래밍 할 수 있어요.

그런데 function이라고 붙여주는 것도 이제 귀찮은거에요.

그래서 나온것이 Arrow Function 혹은 Lambda Function이라고 해요.

[람다 함수 적용 후]

const printHello = () => {
	console.log("Hello world");
}

function (){ } 을 () => {} 로 대체한 것이 Lambda Function

앞으로 함수 표현을 쓰지 않고 많은 부분에서 Lambda Function을 사용하도록 할꺼에요!

Request, Response란?

앞서 서버를 설명할 때, 사용자의 요청(Request)을 받아서 응답(Response)를 주는 도구라고 했죠?

저번시간에 우리는 localhost:8080이라는 요청을 보냈고, Hello world라는 응답을 받았어요.

const http=require("http");

//Server에 대한 정의
const server = http.createServer(function(request,response){
	console.log("we get the request");
 	response.write("hello world!");
  	response.end();
});

server.listen(8080); //Server on!

위 코드 내용을 다시 들여다 보도록 할께요!

우리는 server라는 객체 내에 http.createServer()가 리턴한 값을 저장할꺼에요.

그 이후에 server.listen(8080)을 실행함으로써, 서버를 실행시키게 되는거죠.

즉, http.crateServer내에 fuction(request,response)을 어떻게 정의 하느냐에 따라 서버의 동작도 달라지는 것이에요.

그렇다면 request, response 무엇을 하는 친구인지 한번 확인해볼게요.

위 코드를 실행 시킨 뒤, localhost:8080 으로 한번 들어가 볼까요?

저희는 localhost:8080이라는 값으로 들어가게 됨으로써 서버에 요청을 주는 겁니다.

어떻게 확인하냐구요?

서버를 킨 터미널에 저희가 URL에 주소를 칠 때마다 we get the request 값이 들어간 모습을 알 수 있습니다.

그렇다면 그 결과는 response를 통해

다음과 같이 받았겠죠?

그렇다면 우리는
https://search.naver.com/search.naver?query=손흥민

https://search.naver.com/search.naver?query=아이유
를 쳤을때 서로 다른 Response를 받을 수 있는 것을 알 수 있습니다.

그런데 저희는 localhost:8080/[아무URL] 을 쳐도 똑같은 응답이 나오는 걸 알 수 있습니다.

그럼 서버는 이런 url을 어떻게 구분 하는 것일까요?

이제 부터 알아볼께요!

code를 바꿔보겠습니다.

const http =require("http");

const server = http.createServer((request,response)=>{
	console.log(request);  //이 부분이 바꼈습니다!.
  	response.write("hihi");
  	response.end();
});

server.listen(8080);

request객체를 출력해라 라는 것인데요

그리고 다시 서버를 실행 한 뒤, localhost:8080으로 들어가보겠습니다.
그리고 다시 노드 터미널을 확인해보시면

이런 화면이 뜨셨나요? 뭔가 많습니다. 와 여러분들의 정보들이 알게 모르게 이 request 객체에 담겨서 서버쪽으로 전송이 되었던 겁니다.

그럼 다시

const http = require('http');
const url = require('url');

http.createServer((req,res)=>{
    const path = url.parse(req.url).path;
    res.write(path);
    res.end();
}).listen(8080);

코드를 작성해볼께요.

그리고 다시 node로 위 코드를 실행해볼게요,

그리고 언제나 다시 localhost:8080으로 들어가 봅시다.

그러면 '/' 만 뜨는걸 확인할수 있나요

그러면 다시 localhost:8080/123을 한 번 쳐볼게요.

결과값이 /123으로 나오는걸 확인 할 수 있을까요.

네 여러분은 이제 url 별로 요청을 쉽게 나눌수 있습니다.

어떻게요? 다음과 같은 코드를 한 번 작성해 보겠습니다.

const http = require('http');
const url = require('url');

const server = http.createServer((req,res)=>{
const path = url.parse(req.url).path;
  switch(path){
      case "/test":
        res.write("test");
        break;
      case "/hello":
        res.write("helloWorld");
        break;
      default:
     	res.write("end");
    }
  
  res.end();
});

server.listen(8080);

여러분은 사용자가 요청하는 url에 따라 다른 서비스를 이렇게 구현을 해준거에요.

그런데 이렇게하면 간단한 프로그램은 쉽게 만들 수 있지만 규모가 큰 프로그램은 쉽게 만들 수 없어요.

그래서 Express Framework가 여기서 나옵니다.

Express Framework 설치하기

Express Framework란?

Express는 웹 및 모바일 애플리케이션을 위한 일련의 강력한 기능을 제공하는 간결하고 유연한 Node.js 웹 애플리케이션 프레임워크입니다.

출처:https://expressjs.com/ko/guide/routing.html

그러면 여러분께 Express Framework를 설치하는 방법을 가르쳐 드릴꺼에요.

그런데, 우리는 총 6주차에 과정을 가지고 있어요.

그래서 저희는 좀 더 설정을 빠르게 할 수 있는 Express Generator를 사용할겁니다.

그럼 설치 해보도록 하겠습니다!

npm install express-generator -g

설치가 되셨으면 여러분들이 저장하고 싶은 폴더로 가셔서

express [projectname명] --view=ejs

을 치시면 막 설치가 진행 될 겁니다!.

--view=ejs는 붙이셔도 되고 안붙이셔도 됩니다. (어차피 안쓸거라..ㅎㅎ)

Express 살펴보기

설치를 하시면 다음과 같은 폴더 구조를 띄게 될겁니다.

기본적으로 Model View Contorller 구조로 express가 만들어져 있을 겁니다.

저희는 Express 하나하나에 대해 배우는 것 보다 속성으로 배워가보겠습니다.

현재 저희가 필요한 것은 routes와 public 그리고 app.js입니다.

먼저 app.js 부터 살펴보겠습니다.

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// 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')));

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 중 일부
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

app.use('/',indexRouter);
app.use('/users',usersRouter);

indexRouter와 usersRouter가 전부 routes폴더에서 들고왔다는 것을 알 수 있습니다.

그러면 routes 폴더를 하나하나 살펴보겠습니다.

  • /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;
  • /routes/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;

그럼 저희는 이 코드를 이해하기 위해 간단하게 결과부터 봅시다.

express가 설치됐으면 설치된 폴더로 접근해서 npm start를 입력해주세요.

그러면 서버가 실행이 될겁니다.

이번에는 localhost:3000을 들어가볼게요

그리고 localhost:3000/users/를 한번 들어가볼게요.

그리고 다시 위 코드를 한 번 볼게요.

이해가 되시나요?

routes 폴더 내에 코드를 정의 함으로써 요청에 대한 응답을 정의 할 수 있습니다.

저희가 아까 했던 작업을 매우 편하게 하는 것을 볼 수가 있습니다.

네, 그러면 저희는 localhost:3000/dsc/dsc에 들어가면 hello world가 나오도록 한번 출력을 해볼까요?

routes 폴더 내에 dsc.js 를 만듭니다.

그리고 다음과 같이 정의를 해주세요.

- routes/dsc.js

const express = require('express');
const router = express.Router();

router.get("/dsc",(req,res)=>{
	res.send("hello world");
})

module.export = router;

그리고 이 라우터를 저희가 사용하겠다 라는 것을 app.js에 등록 해주는 것입니다.

- app.js

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
const dscRouter = require('./routes/dsc');

app.use('/',indexRouter);
app.use('/users',usersRouter);
app.use('/dsc',dscRouter);

하고 다시 노드를 실행해보겠습니다.

그리고 localhost:3000/dsc/dsc 에 접속해보겠습니다.

저희가 원한 데이터가 출력이 됐나요?

이정도 까지 했으면 여러분들은 노드에 대해서 80%는 다익혔다고 볼 수 있습니다.

실제로 서버에 대한 기본적인 기능은 사용자의 요청에 대해서 응답을 내주는 것이기 때문에,

이제는 여러분이 어떻게 서비스를 짜느냐에 문제입니다.

당장 여러분들은 위에서 배운것만 이용해서 서비스를 제작할 수도 있습니다.

HTTP Method에 대해 설명

저희는 http://www.naver.com, http://velog.io/@ehdrms2034 처럼 http 프로토콜이 접두사로 붙은 url을 많이 보실 수 있을 겁니다.

앞서 말했듯이 web 브라우저에 url을 입력해서 서버에 요청을 한다고 했습니다.

그러한 방식외에도 여러가지 방법으로 http에 대한 요청을 보낼 수 있습니다.

간단하게 알아보도록 하겠습니다!!.

http는 GET,POST,PUT,DELETE로 구성된 4가지의 Method가 존재한다.

GET Method

서버에서 정보를 가져올때(Get) 요청하는 메소드
웹 브라우저에서 url을 쳐서 서버에 정보를 요청하는 것이 여기에 해당.
Ex) 검색, 게시글 조회

POST Method

Request Body를 인자에 담아서 전송, 서버에 정보를 저장할 때 요청하는 것이 여기에 해당
Ex) 회원가입, 게시글 작성

Put Method

파일을 전송하기 위한 Method, 혹은 서버에 정보를 수정할 때 요청하는 것이 이곳에 해당
Ex) 방문자수 증가, 회원정보 수정

Delete Method

서버에 저장된 정보를 삭제 할 때 요청하는것이 이곳에 해당
Ex) 게시글 삭제, 파일 삭제, 회원 탈퇴

그럼 Express에선 어떻게 적용할까?

아까 /routes/dsc.js 코드를 다시 볼까요?

router.get("/dsc",(req,res)=>{
	res.send("hello world");
});

기억하시나요?
router.get("/dsc",~~~); 로 함수가 정의된 모습을 볼 수 있습니다.

무슨 뜻일까요?

http method중 get 타입을 가진 /dsc/dsc 요청이 오면 응답하겠다는 것입니다.

그렇다면 Post 방식으로 응답을 하려면 어떻게 만들어야 될까요?

눈치가 빠르신 분이시라면 이미 알고 계실 수도 있습니다.

위 코드에 다음과 같은 내용을 추가 해보겠습니다.

router.post("/dsc",(req,res)=>{
  res.send("you send me by Post Method!");
});

네 put과 delete도 같습니다.

그런데 웹브라우저에서는 localhost:/3000/dsc/dsc 해도 나타나지 않는 모습을 볼 수 있습니다.

웹브라우저에서 url을 요청하는 것은 모두 GET Method에 해당합니다.

그렇다면 어떻게 해야 될까요?

직접 서버요청을 하거나 Postman 혹은 curl 명령어 같은 방법으로 요청할 수 있습니다.

(강의 시간 때 시간남으면 직접 보여드리도록 하겠습니다!)

참고: 여러분은 이제 진짜 서비스를 만들 준비가 됐습니다.

리액트 설치

이제 프론트 앤드에 해당하는 부분을 공부해 보도록 하겠습니다.

리액트란?

페이스북이 제공하는 자바스크립트 라이브러리(프레임워크라 해도 손색없는)입니다.

동적인 웹을 좀 더 편하게 만들어주는 라이브러리라고 보시면 됩니다.

실제로 제가 작성하는 이 Velog.io도 리액트로 만들어져있습니다.

하나 하나 설명하기엔 시간관계상 넘어 가도록 할께요!

저희는 일단 이용만 해봅시다

create-react-app 설치

저희는 Express-generator를 통해서 Express를 좀 더 쉽게 설치했습니다.

그럼 리액트는 좀 더 쉽게 설치 할 수 있는 라이브러리가 없을까요?

없으면 설명을 안했겠죠ㅎㅎ React-create-app이 있습니다.

그럼 설치 해보록 하겠습니다.

npm install -g create-react-app

을 터미널 창에 쳐주세요. 그러면 라이브러리가 설치가 될텐데, 다 설치가 되셨다면

create-react-app [프로젝트명]

을 치시면 됩니다.

저는 다음과같이 프로젝트를 하나 생성해보도록 하겠습니다.

create-react-app week2-client

하셨으면 설치가 완료되고 폴더가 생성이 됐을텐데

cd week2-client(혹은 프로젝트명)

을 치고 들어가신 뒤

npm install

을 한번 더 치시구

npm start

를 치시면 리액트가 실행이 되고 웹브라우저가 실행이 됩니다.!!

이제 리액트를 개발할 준비가 되었습니다.

다음과 같은 화면이 떴나요?

그렇다면 리액트 구조에 대해서 간단히 설명해보도록 하겠습니다.

리액트 파일 구조 설명

다음과 같은 폴더 구조가 있는데 저희가 확인할 것은 src 폴더입니다.
(그 이외에는 필요가 없습니다.)

딱 한가지만 보면 됩니다.

어떤것일까요?

App.js

입니다.

리액트는 CSR(Client Side Rendering)임과 동시에 SPA (Single Page Application)라고도 불립니다.

다른거 다 필요없고 저희는 SPA만 봅시다.

Single Page Application, 하나의 페이지가 곧 하나의 앱입니다.
(물론 나중에 Next.js를 사용함으로써 코드 스플리팅을 진행합니다.. 저희는 기초니까요^^)

저희는 이 App.js를 수정함으로써 서비스를 수정해 나갑니다.

그럼 App.js를 다지우고 다음과 같이 만들어볼께요.

리액트는 이 사용자에게 나타내주는 이 View 부분을 Component라고 불립니다.

리액트에서 Component를 나타내는 방법은 크게 2가지가 있습니다

  1. Class Componet 구현법
import React from 'react';

class App extends React.Component{

  render() {
    return(
    <div>
      헬로우 월드!
    </div>
    )
 }
}

export default App;
  1. Functional Componet 구현법
import React from 'react';

 const App = () => {
  return(
  <div>
    헬로우 월드!
  </div>
  )
}

export default App;

각각의 장단점이 있지만 대부분 React hooks라는 기능을 활용하여 2번으로 구현하곤 합니다!

그리고 리액트를 제작하기 위해서는 선수 과목으로

html, css, javascript에 대한 지시을 알고 있으면 굉장히 편합니다.

모르시는 분들이라면, 생활 코딩 HTML강의를 추천드립니다!!

각설하고, 리액트 뷰를 저희가 직접 제작해보도록 하겠습니다.

음 간단하게 로그인 뷰를 한 번 제작해볼까요?

버튼 뷰 커스텀 하기

그럼 리액트 뷰를 이용해서 Button을 한번 Custom 해볼꺼에요.

그전에

npm install node-sass sass-loader

를 쳐서 좀 더 편하게 코딩을 해볼꺼에요.

이 sass는 좀 더 기능이 많은 css라고 보시면 될 것 같아요!

Src 폴더내에 Componet 폴더를 만들고 그안에 CustomButton.js, CustomButton.scss라는 파일을 만들어 봅시다.

그리고 다음과 같이 프로그램을 코딩해보겠습니다.
- Component/CustomButton.js

import React from "react";
import './CustomButton.scss';

const CustomButton = ({children}) => {
  return (
  <button className="custom-button">
    {children}
  </button>
  );
};

export default CustomButton;

저희는 일반적인 버튼 뷰를 만들 겁니다.
그래서 리액트 함수형 리액트 컴포넌트 틀안에서
button 하나를 Return한다고 정의를 해 두었습니다.

- Component/CustomButton.scss

.custom-button{
    width: 300px;
    height: 40px;
    font-size: 1.3rem;
    color: white;
    background: rgba($color: #e3272b, $alpha: 0.8);
    border: none;
    outline: none;
    font-weight: bold;
    &:active{
        background: rgba($color: #e3272b, $alpha: 1.0);
    }
}

그리고 버튼의 스타일을 지정해줍니다.
그냥 생각나는대로 만들어봤습니다.

css 생소하신분들은 그냥 복사 붙여넣기 해주세요!

- App.js

import React from 'react';
import CustomButton from './Component/CustomButton';

const App = () => {
  return(
  <div>
    <CustomButton>
      버튼입니다.
    </CustomButton>
  </div>
  )
};

export default App;

그리고 제작한 CustomButton을 불러와서
App.js에 넣어줍시다. 반드시 CustomButton안에 Children이라는 속성이 있어야만
저렇게

<CustomButton>
  	내용 입력
  </CustomButton>

내용을 입력할 수 있습니다!.

아무튼 이렇게 해서 localhost:3000에 들어가 본다면

과 같은 결과가 나온 것을 확인하실 수 있을겁니다.

최종 점검

6주차에 끝내기에 양이 너무 많아서 이번에 좀 속도를 올려서 확확 강의를 했습니다.

중요한 부분만 이야기 했고 사실 노드나, 리액트 모두 배워야 할 양은 끝없이 많습니다.

기초에 대해서 설명을 했고 리액트나 노드에대해서 모르는 부분이 있으면 언제든지 질문 환영입니다.

리액트 같은 경우는 HTML + CSS + JAVASCRIPT에 대한 선수 지식을 많이 요구하다보니, 이해하기 힘든 부분이 있으실수도 있습니다.

리액트도 너무 빠르게 훑고 가서 다음주는 Props나 State에 대해서 한번 설명을 한뒤에

몽고 디비를 이용해서 Bit.ly 서비스를 한번 제작해보도록 하겠습니다.

시간이 만약 조금 지체되거나 어렵되고 느껴질경우 강의 주차를 좀 더 늘려서 7주차나 8주차 과정으로 변경할 생각도 있습니다.

자세한건 얼마나 진행이 되느냐에 따라서 말해드릴께요 ㅎㅎ

들어주셔서 감사합니다.

profile
수동적인 과신과 행운이 아닌, 능동적인 노력과 치열함
post-custom-banner

0개의 댓글