[Note] Vue&Node.js express 하나의 서버로 연동, meta tag 동적으로 업데이트, Heroku 배포

bbio3o·2021년 8월 20일
0

👩‍💻 노트

목록 보기
7/10
post-thumbnail

Requirements

- social media url 링크 공유 할때 동적으로 meta tag 변환해 주고 싶음
vue에서 SPA 방식으로는 불가능해보임 서버사이드 렌더링 필요
-> meta tag를 동적으로 백에서 변환 해주고 vue에서 index.html 빌드 하지 않고 서버의 커스텀 index.html 사용
-> vue와 node express 서버 따로 사용하는 것이 아니라 node express가 쓰는 localhost:3000 서버로 통일


📌 /backend/index.js

// bakend/index.js 
const express = require('express');
const exphbs  = require('express-handlebars');
const dotenv = require('dotenv');
const cors = require('cors');

dotenv.config();

const app = express();

app.engine('handlebars', exphbs());
app.set('view engine', 'handlebars');
app.use(cors());
// 절대경로 추천
app.use(express.static(__dirname + '/frontend/dist'));

const aws = {
  getImageUrl({id}) {
    if (id == 'logo') {
	...코드 중략
    }
  }
}

let OG_TITLE = 'EXAMPLE TITLE';
let OG_DESCRIPTION = 'EXAMPLE DESC';
let OG_TYPE = 'website';
let OG_URL = 'https://www.google.com/';

app.get('*', function (req, res) {
  // imgage id 정보 query로 받아서 동적으로 데이터 바꿔주기
  const metaImage = aws.getImageUrl({id: req.query.id})

  res.render('home', {
    helpers: {
      OG_TITLE,
      OG_DESCRIPTION,
      OG_TYPE,
      OG_URL,
      metaImage,
      description(){
        return req.query.id || 0
      }
    }
  });
});

const PORT = process.env.PORT || 3000;

app.listen(PORT, err => {
  if (err) {
    console.log(err);
  } else {
    console.log(`Listening on PORT ${PORT}`);
  }
});

module.exports = app

📌 /backend/views/home.handlebars

vue에서 작성된 부분

<noscript><strong>We're sorry but frontend doesn't work properly without JavaScript enabled. Please enable it to
      continue.</strong></noscript>
  <div id="app"></div>
  <script src="/js/chunk-vendors.js"></script>
  <script src="/js/app.js"></script>

📌 /backend/views/layouts/main.handlebars

<!DOCTYPE html>
<html>
  <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">
    <meta name="description" value="{{ description }}">
    <meta property="og:title" content="{{ OG_TITLE }}" />
    <meta property="og:description" content="{{ OG_DESCRIPTION }}" />
    <meta property="og:type" content="{{ OG_TYPE }}">
    <meta property="og:url" content="{{ OG_URL }}">
    <meta property="og:image" content="{{ metaImage }}" />
    <meta property="og:image:width" content="1200" />
    <meta property="og:image:height" content="1200" />

    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@SamsungMobile">
    <meta name="twitter:creator" content="@SamsungMobile">
    <meta name="twitter:image" content="{{ metaImage }}">
    <meta name="twitter:title" content="{{ OG_TITLE }}">
    <meta name="twitter:description" content="{{ OG_DESCRIPTION }}">
    <title>Example App</title>

    <link href="/css/app.css" rel="preload" as="style">
    <link href="/css/app.css" rel="stylesheet">
  </head>
  <body>
    {{{body}}}
  </body>
</html>

📌 /frontend/vue.config.js

index.html 빌드를 vue에서 하지 않고 백엔드 에서 넘겨줌

// vue.config.js
module.exports = {
  // disable hashes in filenames
  filenameHashing: false,
  // delete HTML related webpack plugins
  chainWebpack: config => {
    config.plugins.delete('html')
    config.plugins.delete('preload')
    config.plugins.delete('prefetch')
  }
}

📌 /backend/package.json

{
  "name": "metadata-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js",
    "server": "nodemon index.js",
    "heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix frontend && npm run build --prefix frontend"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^10.0.0",
    "ejs": "^3.1.6",
    "express": "^4.17.1",
    "express-handlebars": "^5.3.3",
    "nodemon": "^2.0.12"
  },
  "engines": {
    "node": "15.12.0"
  }
}

engines 에 node 버전 정보 필요,
scripts에 "heroku-postbuild" 추가
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix frontend && npm run build --prefix frontend"

📌 Procfile(root에 생성)

헤로쿠 배포 실행을 위한 파일

web: node index.js

📌 Heroku 배포

$ heroku login
$ heroku create 프로젝트이름
-> root에 Procfile 생성
-> /backend/package.json scripts에 "heroku-postbuild" 아래와 같이 추가
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix frontend && npm run build --prefix frontend"
$ git add .
$ git commit -m "commiit msg"
$ heroku git:remote -a 프로젝트이름
$ git push heroku main
-> heroku 홈페이지에서 내가 만든 앱의 settings의 config vars에서 .env에 있는 키들 설정해줌

참고사항

  • 배포시 명령어 git heroku master가 아니라 git push heroku main 으로 변경
  • const PORT = process.env.PORT || 3000
    heroku 배포시 process.env.PORT 설정 꼭 필요 (배포 시에 heroku 페이지에서 setting의 config vars 에 .env파일의 키 설정 필요)
  • /backend/package.json에 node버전 설정 꼭 필요! 까먹고 안 넣었다면 넣은 뒤 cd frontend 로 가서 vue도 npm run build 다시 해줘야함
  • 배포시 오류 나면 로그 살펴보기
 $ heroku logs --tail
profile
그림도 그리는 개발자 🎨👩‍💻

0개의 댓글