반응형

Node 18버전에서 vuepress 1.9.9 버전 설치에 오류가 있어서 포기했다가, 다시 Node 16버전으로 낮춰서 설치했습니다. 아직 Beta버전인 2.0.0 보다 오류가 적은 것 같습니다. 설치하니 기본적으로 검색 툴이 활성화되고, Vue 컴포넌트 추가도 components 폴더에 만드니 별다른 설정없이 인식이 됩니다. 그리고 무엇보다도 태그 요소 추가가 너무 쉽게 진행됩니다. Vuepress2로 하려고 시도하며 공부해서인지 금방금방 작성이 되네요. 다시 Vuepress 1으로 재작성해야겠습니다...ㅠㅠ

 

1. 설치

npm init

npm i -D vuepress@next

 

2. ./docs/README.md 파일 생성

### Hello Vuepress

 

3. ./gitignore 파일 생성

node_modules
.cache
.temp

 

4. package.json파일 수정

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "vuepress dev docs",  // 추가
    "build": "vuepress build docs"  // 추가
  },

 

5. 실행

npm run dev

 

6. 구조

.
├── docs
│   ├── .vuepress (Optional)
│   │   ├── components (Optional)
│   │   ├── theme (Optional)
│   │   │   └── Layout.vue
│   │   ├── public (Optional)
│   │   ├── styles (Optional)
│   │   │   ├── index.styl
│   │   │   └── palette.styl
│   │   ├── templates (Optional, Danger Zone)
│   │   │   ├── dev.html
│   │   │   └── ssr.html
│   │   ├── config.js (Optional)
│   │   └── enhanceApp.js (Optional)
│   │ 
│   ├── README.md
│   ├── guide
│   │   └── README.md
│   └── config.md
│ 
└── package.json

 

7. docs/.vuepress/config.js

화면구성 참조용으로 제가 작업했던 내용 공유해놓겠습니다.

module.exports = {
  title:"Hello, Vuepress",
  themeConfig: {
    logo: '/assets/img/logo.png',
    nav: [
      { text: 'Home', link: '/' },
      { text: 'Guide', link: '/guide/' },
      { text: 'External', link: 'https://google.com' }
    ],
    sidebar: [
      {
        title: 'Today I Learned',  // required
        path: '/foo/',      // optional, link of the title, which should be an absolute path and must exist
        collapsable: false, // optional, defaults to true
        sidebarDepth: 1,    // optional, defaults to 1
        children: [
          {title: '1 설치(v2)',path:'/pages/1_설치.md'}, 
          {title: '2 레이아웃(v2)',path: '/pages/2_레이아웃.md'},
          {title: '3 검색창(v2)',path: '/pages/3_검색창.md'},
          {title: '4 Vue컴포넌트(v2)',path: '/pages/4_Vue컴포넌트.md'},
          {title: '5 태그(v2)',path: '/pages/5_태그.md'},
          {title: '6 vuepress v1설치',path: '/pages/6_v1설치.md'}
        ],
      },
      {
        title: 'Group 2',
        children: [ /* ... */ ],
        initialOpenGroupIndex: -1 // optional, defaults to 0, defines the index of initially opened subgroup
      }
    ]
  }
}

 

8. 태그 리스트 컴포넌트 만들기

태그 리스트 컴포넌트를 생성 후 README.md에서 확인해보겠습니다.

 

docs/.vuepress/components/TagList.vue

<template>
  <div class="tag-list">
    <h3>Tags :</h3>
    {{ tags }}
  </div>
</template>

<script>
export default {
  computed:{
    tags() {
      // 모든 태그를 가져옵니다.
      const tagSet = new Set()
      this.$site.pages.forEach(page => {
        if (page.frontmatter.tags) {
          page.frontmatter.tags.forEach(tag => {
            tagSet.add(tag)
          })
        }
      })
      return [...tagSet].sort()
    }
  }
}
</script>

 

9. README.md

대쉬 3개(---) 사이에 적어놓은 부분을 frontmatter라고 합니다. 이 부분은 해당 md파일의 주요 정보들을 적어놓는 용도로 사용하는데, docs폴더 내부에 테스트를 위해 몇가지 md파일들을 생성해놓고 아래와 유사하게 frontmatter를 작성해둡니다. tags에 1.js, 2.js 등 여러가지 키워드를 넣었습니다.

---
title: 'Vuepress2 태그시스템'
date: '2023-07-06'
tags:
  - JavaScript
  - 2.js
---

# KMS Data 검색 속도 건 관련

이 문서에서 사용하는 태그 목록을 출력합니다.
<!-- {{ $site }} -->

<TagList />

 

<결과>

반응형
반응형

서버리스 앱 만들기의 마지막 단원으로 Vue.js 프론트 앱을 배포해보도록 하겠습니다. 

 

1. 앱 만들기

Vue 앱을 만들어줍니다.

vue create node_post_vue .    // .을 찍으면 현재 폴더에 프로젝트를 생성합니다.

vue add router  // 곧바로 router 라이브러리를 함께 설치해줍니다.

 

필요한 라이브러리를 아래와 같이 설치해줍니다.

npm i vuex axios

간단히 백엔드에서 보내오는 데이터를 읽어다 표현해주는 것만 할건데도 Store를 구성하고 각 컴포넌트에서 Store state를 이용해야하는게 좀 불편해 보이네요. 그래도 한번만 세팅해놓으면 다음부터는 비교적? 편하게 작업을 할 수 있다고 생각하고 진행하셔요^^;;

 

 (1) ./src/main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import {store} from './store/store.js'

createApp(App)
.use(router)
.use(store)
.mount('#app')

 

(2) ./src/App.vue

<template>
  <router-view/>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
</style>

 

 (3) ./src/router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

 

  (4) ./src/components/HelloWorld.vue

<template>
  <div class="hello">    
    <ul>
      <li class="post" v-for="post in postlist" :key=post>
        <div class="title">
          {{ post.title }} 
        </div>
        <div class="content">
          {{ post.content }} 
        </div>
        <div class="lower">
          <div>...by {{ post.creator }} </div>
          <div>on {{ post.publish_date.split('T')[0] }}</div>
        </div>
      </li>
    </ul>
  </div>
</template>

<script scoped>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  computed:{
    postlist(){            
      return this.$store.state.posts;
    },    
  },
  created(){
      this.$store.dispatch('onLoad');
    }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
ul {
  text-align: center;
  list-style-type: none;
  margin: 0 auto;
  padding: 0;
  width: 800px;
}
.post {
  /* display: inline-block; */
  margin: 10px 10px;  
  border: 1px solid #42b983;
  border-radius: 15px;
  padding: 8px;
}

.post .title{
  text-align: left;
  font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
  font-size:larger;
  font-weight: 900;
  color:#222;
}
.post .content{
  text-align: left;
  font-size:small;
  padding: 5px;
  height: 80px;
  color:#999;
}
.post .lower{
  text-align: right;
  color:grey;
  font-size:small
}
a {
  color: #42b983;
}
</style>

 

  (5) ./src/store/store.js

import { createStore } from 'vuex';
import axios from 'axios';

axios.defaults.baseURL = 'https://vmsahpyntz.eu10.qoddiapp.com';
axios.defaults.headers.post['Content-Type']='application/json;charset=utf-8';
axios.defaults.headers.post['Access-Control-Allow-Origin']='*';

export const store = createStore({
  state:{
    posts:[]
  },
  mutations:{
    updateState(state, payload){
      Object.keys(payload).forEach((key) => {
        state[key] = payload[key];
      });
    }
  },
  actions:{
    async onLoad(context){
      const res= await axios.get('/');
      const post = res.data;
      // console.log(res);
      
      context.commit('updateState',{
        posts:[...context.state.posts, ...post],
      })
    },
  }
});

 

2. gitlab에 배포하기

저는 회사 특성상 github 접근이 불가능해서 gitlab을 주로 사용합니다. 사용 방법은 github과 동일합니다.

git remote add origin [gitlab주소: 대활호 빼고]
git pull origin main
git add .
git commit -m "initial commit"
git push origin main // main인지 master인지 본인의 branch를 잘 확인하고 진행합니다.

 

3. Netlify에서 연동하기

Netlify에 접속해줍니다. 계정이 없다면 적당한 방법으로 계정을 생성해주셔요.

"Sites  >  Add new site  >  Import an existing project"를 클릭해줍니다.

아래 그림에서 본인의 저장소가 있는 곳을 선택합니다. 저는 Gitlab

 

본인의 프로젝트를 선택합니다.

 

배포 세팅을 하게 되됩니다. 배포할 브랜치, 빌드 명령어(npm run build), 배포 디렉토리(일반적으로 /dist) 를 확인하고, 아래에 Deploy Site를 눌러주면 배포가 시작됩니다.

 

배포가 완료되면 아래와 같이 화면이 변경되며, 배포된 url이 표시가 됩니다. 

 

해당 링크를 클릭하면 우리가 만든 사이트가 나타납니다.

 

이제 수정사항이 생길때마다 Gitlab으로 배포만 하면 자동으로 Netlify도 업데이트됩니다. 

지금까지 DB, Backend 서버, Frontend 서버를 모두 서버리스로 구현해보았습니다.

 

~~~끝~~~~

반응형
반응형

프론트엔드 프레임워크 하면 Angular / React / Vue 그리고 최근 부각되고 있는 Svelte가 있는데요. 전문 개발자는 아니지만 조금은 손대본 경험을 토대로(Angular제외..) 특성을 알아보도록 하겠습니다.

 

Stackoverflow Ranking에서 여러 프로그래밍 언어 및 프레임워크에 대한 점유율, 선호도 등 자세한 정보는 확인하실 수 있습니다. 해당 정보에 따르면 웹 프레임워크의 점유율은 아래 그래프와 같습니다. 이 중에 프론트엔드 프레임워크만 보면 React가 제일 상단에 있고, jQuery, Angular, Vue 그리고 한참 아래쪽에 Svelte가 있네요

 

< 점유율 >

 

역시 Stackoverflow Ranking에 따르면 이번엔 Svelte가 제일 위에 있고, 그다음 React, Vue이고 Angular가 하위에 있는 모습입니다. Svelte가 가장 신생 프레임워크인데, 선호도 측면에서는 많은 개발자들이 만족하고 있다는 의미네요.

 

< 가장 사랑받는 / 피하고싶은>

 

그럼 각 프레임워크의 특징을 한번 살펴보겠습니다.

1. Angular

Angular는 구글에서 만든 Javascript 프레임워크로 초기 1.0버전에서는 AngularJS, 2.0버전부터는 그냥 Angular라고 칭했습니다. 특이한 것은 1.0은 Javascript, 2.0은 Typescript를 기본 언어로 채택하였습니다. Angular는 필요한 요소들을 모두 포함하고 있는 것이 특징입니다. 그만큼 다른 라이브러리들을 추가로 설치할 필요가 없으며, 대신 학습해야할 양이 많은 것으로 알려져 있습니다. 

양방향 데이터바인딩을 지원하며, 태그이름, 템플릿 파일, CSS파일 정보를 decorator문법을 이용하여 전달하는 선언적 코딩 스타일을 사용한다는 특징을 갖고 있습니다. 

 

 

2. React

React는 페이스북에서 만든 라이브러리입니다. 라이브러리냐 프레임워크냐로 갑론을박이 많이 있었지만, 최근에는 라이브러리다라는 의견이 대체적으로 받아들여지고 있는 모습입니다. React는 Virtual-DOM이라는 개념을 적용하였습니다. DOM은 HTML문서를 제어할 수 있는 API 트리 자료구조인데, 실제 DOM을 사용하여 변경시마다 모든 요소를 Update하기에는 무거우며 속도가 느려지는 한계가 있어 가상 DOM이라는 개념을 적용하고 있습니다. 이는 Vue도 마찬가지입니다. 

또다른 특징으로는 Component에 의한 재사용 가능한 UI 생성을 들 수 있으며, 이를 위해 내부적으로 JSX라는 특별한 문법을 사용합니다. 이는 자바스크립트에 HTML을 내포한듯한 모습을 하고 있습니다. 

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Hello React
        </a>
      </header>
    </div>
  );
}

Component로 각 요소를 구분해가며 전체 페이지를 구축해가는 방식은 개발자들이 쉽게 접근할 수 있도록 도왔던 것으로 보입니다. Props, State 등의 개념을 익히다가 나중에 상태관리자로 Redux라는 개념을 사용할 때즈음 되면 슬슬 멘붕이 오기 시작합니다. 요즘은 Redux toolkit를 써서 쉽게 접근할 수 있도록 했다고는 하지만, 개념이 바뀌는 것은 아니므로  학습곡선이 완전히 낮아졌다고 하기는 힘들어보입니다.

 

3. Vue

Evan You에 의해 시작된 Frontend Framework로 React와 마찬가지로 Virtual-DOM의 개념을 사용합니다. Evan You는 Angular를 이용한 개발을 하던 중 본인이 필요한 기능들만 추려서 만들었다고 하고, 시기적으로도 React보다 1년 뒤에 나온만큼 Angular, React 등으로부터 영향을 받았을 것으로 보입니다. 단방향 데이터 바인딩만 지원하는 React와는 달리 Vue는 양방향 데이터바인딩을 지원합니다. React를 공부하다보면 Redux 상태관리자를 사용하면서 학습난이도가 올라가는데, Vue에서의 상태관리자인 Vuex는 이보다 훨씬 이해하기 쉬운 장점이 있습니다. 아래는 컴포넌트를 정의하는 샘플 Vue 코드인데, 보시면 template, script, style의 세 부분으로 나뉘어져 있습니다. 이런 구분에 대해서는 개발자마다 호불호가 있지만, 처음 접근하는 입장에서 가독성이 좋은 것은 큰 장점 같습니다.

<template>
    <div class="btn">
        <slot></slot> <!--버튼처럼 텍스트를 표시하기위한 속성-->
    </div>
    <h1 @dblclick="$emit('abc')">
		ABC
    </h1>
</template>
    
<script>
export default{
	emits: [
		'abc'
	]    
}
</script>

<style scoped>
.btn{
    display: inline-block;
    margin: 4px;
    padding: 6px 12px;
    border-radius: 4px;
    background-color: gray;
    color: white;
    cursor: pointer;
}
</style>

 

4. Svelte

기존의 Angular/React/Vue에이어 Svelte는 상당히 나중에 진출한 후발주자입니다. 그런데도 Stackoverflow Ranking에서 보면 개발자가 사랑하는 프레레임워크 2위를 차지할 정도로 관심도가 엄청나며(1위는 Phoenix), 다른 프레임워크들을 추격하고 있습니다. 

The State of JS 2021 Web Frontend Framework

svelte 는 라이브러리/프레임워크가 아닌 컴파일러라고 합니다. Svelte코드를 실행시점에서 해석하지 않고 컴파일 단계에서 Vanilla Javascript 번들로 만들기 때문에 다른 라이브러리를 함께 배포할 필요가 없어집니다. 또다른 특징으로는 React나 Vue처럼  Virtual-DOM을 사용하지 않고 실제 DOM을 직접 제어합니다. 성능적으로 작은 번들사이즈와 DOM의 직접제어 덕분에 다른 프레임워크보다 빠른 반응속도를 보여줍니다. 

문법은 개인적인 느낌이 Vue랑 유사하게 생겼습니다. 가시성도 좋고 쉽다고 생각이 듭니다. 화면 Update할 시점을 인식시켜주기 위한 특이한 용법들도 있습니다만 다른 라이브러리들의 학습곡선에 비할 바가 아니라고 생각됩니다. 상태관리에서도 redux, vuex와 같이 외부 라이브러리를 설치할 필요가 없이 내부에 store를 기본으로 내장하고 있습니다. 

<script>
let name = "teo.yu"
</script>

<div>Hello world! {name}</div>

<style>
div { color: red }
</style>

<번들사이즈 비교>

파일사이즈가 작으면 다운로드속도가 올라가서 체감속도가 빨라집니다. 아래 결과를 보면 Svelte가 가장 작은 사이즈를 보이고 있습니다.

 

이런 성능과 러닝커브 등의 잇점으로 최근 svelte의 인기가 올라가고 있는 것으로 보입니다. 하지만 아직까지 시장의 메인은 React, 그리고 최근에는 Vue도 많이 도입하고 있는 것 같습니다. 저도 Vue를 주로 사용하여 개인 프로젝트들을 만들고 있는데 React에서 어려운 개념들을 익히고 나서 접근해서인지, Vue 너무 좋습니다. 성능도 준수하게 뽑아주는 것 같고, Reference도 잘 되어있어서 당분간은 Vue를 활용할 것 같습니다. Svelte는 조금 더 저변이 넓어지면 그때 적용해볼까 합니다. 

반응형

+ Recent posts