ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Social Media 만들기 - 1)앱 만들기 전 Setup 하기
    NODE.JS 2021. 5. 20. 13:06

    이번엔 소셜미디어를 만든다. 

    https://www.youtube.com/watch?v=JGwiXVvPcdk&list=PLs4co9a6NhMyAfSnDg1MKGwLdLx0OA07d&index=2&ab_channel=DevA.TVietNamDevA.TVietNam

     

     

    제일먼저 만들려는 프로젝트 폴더를 만들고, 

    프로젝트 터미널에서 npm init을 해준다. 

    그 이후 npm i express mongoose cors dotenv bcrypt jsonwebtoken cookie-parser를 해서 다운로드 해준다. 

    여기서 dotenv는 환경변수를 관리하는 프로그램이다. 

    서버에 추가로 npm i -D nodemon을 실행해서 노드몬을 설치해준다. 

     

     

    서버의 package.json을 다음과 같이 수정해준다. 

    {
      "name": "social-media-app",
      "version": "1.0.0",
      "description": "social media",
      "main": "server.js",
      "scripts": {
        "dev": "nodemon server.js"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "bcrypt": "^5.0.1",
        "cookie-parser": "^1.4.5",
        "cors": "^2.8.5",
        "dotenv": "^9.0.2",
        "express": "^4.17.1",
        "jsonwebtoken": "^8.5.1",
        "mongoose": "^5.12.10"
      },
      "devDependencies": {
        "nodemon": "^2.0.7"
      }
    }
    

     

    이후 서버안에 controllers, middleware, models, routes폴더를 생성해준다. 

     

     

    그 다음 npx create-react-app client를 진행해준다.

    그 후 npm i axios react-router-dom redux react-redux redux-thunk redux-devtools-extension moment를 해서 

    필요한 프로그램을 설치해준다. 

     

    다음 부트스트랩 사이트에 접속해서 separate파트를 복사하고, css부분을 복사해서 client의 index.html파일에 다음과 같이 붙여준다.

    타이틀은 원하는 타이틀로 변경해준다. 

    fontawesome, materialicon도 추가해준다. 

     

    https://getbootstrap.com/docs/5.0/getting-started/introduction/

     

    Introduction

    Get started with Bootstrap, the world’s most popular framework for building responsive, mobile-first sites, with jsDelivr and a template starter page.

    getbootstrap.com

    https://www.w3schools.com/icons/fontawesome5_intro.asp

     

    Font Awesome 5 Intro

    Font Awesome 5 Introduction Font Awesome 5 Font Awesome 5 has a PRO edition with 7842 icons, and a FREE edition with 1588 icons. This tutorial will concentrate on the FREE edition. To use the Free Font Awesome 5 icons, you can choose to download the Font A

    www.w3schools.com

    https://developers.google.com/fonts/docs/material_icons

     

    Material Icons Guide  |  Google Fonts  |  Google Developers

    An overview of material icons—where to get them and how to integrate them with your projects. What are material icons? Material design system icons are simple, modern, friendly, and sometimes quirky. Each icon is created using our design guidelines to de

    developers.google.com

      <head>
        <meta charset="utf-8" />
        <link rel="icon" href="./layout.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="theme-color" content="#000000" />
        <meta
          name="description"
          content="Web site created using create-react-app"
        />
        <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
        
        <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" >
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" ></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.min.js" ></script>
        <script src="https://kit.fontawesome.com/a076d05399.js" ></script>
        <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
        
        <title>Social-Media</title>

     

     

    server부분에 server.js와 .env 파일을 추가해준다. 

    server.js파일을 다음과 같이 변경해준다. 

    require('dotenv').config()
    const express = require('express')
    const mongoose = require('mongoose')
    const cors = require('cors')
    const cookieParser = require('cookie-parser')
    
    const app  = express()
    app.use(express.json())
    app.use(cors())
    app.use(cookieParser())
    
    app.get('/', (req, res)=>{
        res.json({msg:"Hello"})
    })
    
    
    const URI = process.env.MONGODB_URL
    mongoose.connect(URI,{
        useCreateIndex:true,
        useFindAndModify:false,
        useNewUrlParser:true,
        useUnifiedTopology:true
    }, err=> {
        if(err) throw err;
        console.log('Connected to mongodb')
    })
    const port = process.env.POR || 5000
    app.listen(port, ()=>{
        console.log('Server is running on port', port)
    })

     

    mongodb사이트에 가서 프로젝트를 생성하고, 

    클러스터를 생성한 뒤, 데이터 베이스 엑세스에 한명을 추가하고, 

    networkaccess는 다음과 같이 바꿔준다. 

    0.0.0.0 (모든 사람이 접근할 수 있게끔)

     

    클러스터 생성이 완성되면 connect->url복사해서 .env파일에 복사해준다. 

    MONGODB_URL = mongodb+srv://<아이디>:<비밀번호>@cluster0.suytn.mongodb.net/Social-Media?retryWrites=true&w=majority

     

    다음과 같이 연결됨을 확인할 수 있다. 

    apptest파일과 app.css, setuptest, logo 파일을 삭제해준다. 

    만약 여기서 에러가 난다면 

    client폴더로 가서 rm -rf node_modules를 하고 다시 npm install 을 통해서 다시 다운받는다. 

     

    App파일을 다음과 같이 변경해준다. 

    import {BrowserRouter as Router, Route} from 'react-router-dom'
    
    function App() {
      return (
        <Router>
          <input type="checkbox" id="theme" />
          <div className="App">
    
          </div>
        </Router>
      );    
    }
    
    export default App;  
    

     

    index.css를 다음과 같이 수정해준다. 

    * {
      padding: 0;
      box-sizing: border-box;
      margin: 0;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
        'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
        sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    code {
      font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
        monospace;
    }
    
    
    #theme:checked ~ .App {
      filter: invert(1)
    }
    
    .App {
      width: 100%;
      min-height: 100vh;
      background: white;
    }
    
    .main{
      max-width: 1000px;
      width: 100%;
      margin:auto;
    }

     

    체크박스 생성 확인
    누르면 invert되는 것을 확인할 수 있다. 

     

    client->src 폴더안에 components, redux, pages, utils, styles, images 폴더를 생성해준다.

     

    feather사이트에 가서 send아이콘을 다운받고 images폴더에 추가해준다. 

    https://feathericons.com/?query=send

     

    Feather – Simply beautiful open source icons

    Feather is a collection of simply beautiful open source icons. Each icon is designed on a 24x24 grid with an emphasis on simplicity, consistency and readability.

    feathericons.com

    loading.gif 파일과 홈페이지 로고파일로 만들이미지도 인터넷에서 다운받는다. 

     

    홈페이지 로고 이미지는 public 안에 넣어주고, loading.gif는 images폴더에 넣어준다. 

     

    index.html에 가서 다음과 같이 아이콘링크를 수정해준다. 

    <meta charset="utf-8" />
        <link rel="icon" href="./layout.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="theme-color" content="#000000" />

     

    pages에 register.js 파일과 login.js파일을 만들어준다. 

    rafce로 함수형으로 만든다. 

    import React from 'react'
    
    const Register = () => {
        return (
            <div>
                Register
            </div>
        )
    }
    
    export default Register
    
    
    import React from 'react'
    
    const Login = () => {
        return (
            <div>
                Login
            </div>
        )
    }
    
    export default Login
    

     

     

    src폴더안에 PageRender.js파일을 만들고 다음과 같이 입력해준다. 

    import React from 'react'
    import {useParams} from 'react-router-dom';//useparam을 이용해서 페이지를 가져온다. 
    import NotFound from './components/NotFound';
    
    
    const generatePage = (pageNum)=>{//pageNum을 요구한다. 
        const component = ()=> require(`./pages/${pageNum}`).default
    
        try {//페이지가 있으면 component만들고 
            return React.createElement(component())
        } catch (err){//없는 페이지면 Not Found가 뜨도록 설정한다. 
            return <NotFound />
        }
    }
    
    const PageRender = () => { 
        const {page, id} = useParams()
        let pageNum = "";
        if(id){//만약 아이디가 있으면 
            pageNum = `${page}/[id]`
        }else{//만약 아이디가 없이 page만 있으면 
            pageNum = `${page}`
        }
        return generatePage(pageNum)
    }
    
    export default PageRender
    

     

    components폴더안에 NotFound.js파일을 만들어준다. 

    import React from 'react'
    
    const NotFound = () => {
        return (
            <div className="position-relative"  style={{minHeight:'calc(100vh)'}}>
                <h2 className="position-absolute text-secondary" style={{top:'50%', left :'50%',transform: 'translate(-50%, -50%)' }}>
                    404 | NotFound.
                </h2>
            </div>
        )
    }
    
    export default NotFound
    

     

     

    App.js를 다음과 같이 수정해준다.

    import {BrowserRouter as Router, Route} from 'react-router-dom'
    import PageRender from './PageRender';
    
    function App() {
      return (
        <Router>
          <input type="checkbox" id="theme" />
          <div className="App">
            <div className="main">
              <Route exact path="/:page" component={PageRender}/>
              <Route exact path="/:page/:id" component={PageRender}/>
            </div> 
          </div>
        </Router>
      );    
    }
    
    export default App;  
    

     

    로그인페이지나 레지스터 같은 페이지로 이동하면 

    다음과 같이 해당 페이지 이름이 뜨지만, 

     

     

     

     

    없는 페이지로 이동하면 다음과 같이 Not Found 페이지가 나타난다. 

     

     

    index.css파일에 다음과같이 추가해주자. 

     

    * {
      padding: 0;
      box-sizing: border-box;
      margin: 0;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
        'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
        sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
    }
    
    code {
      font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
        monospace;
    }
    
    #theme {
      display: none;
    }
    
    #theme:checked ~ .App {
      filter: invert(1)
    }
    
    .App {
      width: 100%;
      min-height: 100vh;
      background: white;
    }
    
    .main{
      max-width: 1000px;
      width: 100%;
      margin:auto;
    }

     

     

     

     

     

     

     

     

     

     

     

     

Designed by Tistory.