Vue 프로젝트 생성 및 js 파일로 Vue Componet (library) 만들기

제가 vue 를 쓰는 방법은 전체 vue 앱을 만드는 형태가 아닌 일부 part 만 vue로 변환해서 사용합니다.
우선 vue를 쓰게 된 이유 부터 여러 사람이 쉽고 빠르게 개발하기 위해서 사용을 했습니다.

그러나 .vue 로 된 형태의 전체 앱으로 만들게 되면 새로운 IDE 를 사용해야 한다거나 서버를 nodeJS 서버를 사용해야 한다거나 등의 문제가 발생하기도 하기 때문입니다.

또한 기존의 개발되어 있던 사이트를 전체로 갈아 엎어버리지는 못하기도 하지요.
그렇기 때문에 일부의 영역만 vue 로 개발을 하게 됩니다. 또한 그렇게 하다보면 component 화 시켜서 재사용을 하고 싶어질 때도있습니다.

물론 쌩으로 프로젝트에 컴포넌트를 만들어서 사용할 수는 있으나 재사용성이나, 코드확인의 번거로움이 있을 수 있지요.
js 형태로 Component 를 만들게 되면 templete 를 확인하기가 어렵습니다.



그러나 element-ui 같이 js import 를 통해 vue component 를 사용한다면 어떨까란 생각이 들었고, 
이것저것 찾아봤지만 제가 딱 원하는 형태의 것을 검색하지 못했습니다. (제 검색실력이 부족해서일수도 있고..)

그래서 이 글을 정리하게 됐습니다.

이 글은 element-ui 같은 library componet 를 개발하기 위한 예제를 수행해볼 수 있는 글입니다.
어렵지 않게 가능할 것이고, 이 방법을 익히면 생각보다 유용할 것 같습니다.

# 사전준비
nodeJs
npm

# Vue Cli 설치 및 테스트
vue-cli 설치
아래 명령어를 사용하여 global 영역에 vue-cli 를 설치합니다.
npm install -g @vue/cli

무언가를 다운로드 하고 설치하는 것을 확인할 수 있습니다.

설치가 완료 되면 아래와 같은 화면이 나타납니다.

vue-cli 설치 확인
제대로 설치 됐는지 확인하기 위해서는 아래 명령어를 사용합니다.
아래 이미지와 같이 vue/cli 관련된 내용들이 나오면 정상 설치 된 것입니다.
npm -g list | grep vue

# Vue 프로젝트 생성 (vue-cli or vue ui)

vue 프로젝트를 생성하는 것은 cli 와 ui 방식으로 하는 두가지 방식이 있습니다.
ui 방식은 아직 beta 이지만, 윈도우를 주로 사용한 입장에서는 뭔가 더 알기 쉽게 생성이 가능한 것 같아서 추가로 정리해 둡니다.

vue-cli 를 통한 생성
cli를 통한 설치를 진행하고자 하면 아래 명령어를 통하여 프로젝트를 생성합니다.
vue create {프로젝트명}

빠른 테스트를 위하여 default로 선택합니다

vue-cli 설치 할 때 처럼 무언가를 다운로드하고 프로젝트를 구성하는 것을 확인할 수 있습니다.

다운로드 및 프로젝트 구성이 완료 되면 아래와 같이 화면에 나타납니다.
제일 마지막에 적혀 있는 것 처럼 '생성한 프로젝트명' 으로 폴더가 생기고, 해당 폴더에서 실행하면 테스트 구동이 됩니다.

설명에 적혀 있었던 대로 아래 명령어를 수행합니다.
npm run serve
해당 명령어를 수행하면 nodeJS 로 구성된 웹 서버를 구동시켜 줍니다.
그럼 아래와 같이 local URL 을 노출 시켜 주는데 브라우저를 통하여 해당 url 로 접속합니다.

정상적으로 테스트 페이지가 열리는 것을 확인할 수 있습니다.

vue ui 를 통한 생성
아래 명령어를 수행하면 vue ui 웹 화면이 열립니다.
vue ui

아래와 같은 창이 열리게 되고 "+ 새 프로젝트를 만들어보세요" 버튼을 클릭하여 새로운 프로젝트를 생성할 수 있습니다.

프로젝트 폴더를 지정하고 git 연결은 하지 않도록 하고.. 나머지 옵션은 뭐 대충 기본으로 선택해서 진행합니다.

프리셋도 cli 때와 마찬가지로 default 로 진행합니다.

로딩 이미지가 나오고 조금 기다리면 아래와 같이 프로젝트가 생성 된 것을 확인할 수 있습니다.

test-componet 폴더가 생성이 되고 해당 폴더 밑에 파일도 정상적으로 된 것을 확인할 수 있습니다.

vue ui 를 사용했으니까 실행까지 ui 를 통해 진행해보도록 하겠습니다.
작업목록 > serve > 실행 을 하면 "npm run serve" 가 수행이 되어 서버가 실행되는 것을 확인할 수 있습니다.



# component js 로 만들기 예제

IDE 를 이용하여 생성된 test-component 를 열어 줍니다.
저는 VS Code 를 사용하여 열었습니다. 

우선 자동으로 생성 됐던 "App.vue", "components/HelloWorld.vue" 파일을 삭제하고 시작하겠습니다.
그 다음 테스틀 위한 "components/firstComponent.vue", "components/secondComponent.vue" 파일을 생성하겠습니다.
하나의 프로젝트, 즉 1개의 js library 안에 여러개의 component를 구현하기 위해 2개의 component를 생성합니다.

components/firstComponent.vue
<template>
  <div class="firstComponent">
    <h1>First Component</h1>
    <span>{{message}}</span>
  </div>
</template>

<script>
export default {
  name: 'firstComponent',
  props: {
    message: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>


components/secondComponent.vue
<template>
  <div class="secondComponent">
    <h1>Second Component</h1>
    <div v-for="item in items" v-bind:key="item">
      {{item}}
    </div>
  </div>
</template>

<script>
export default {
  name: 'secondComponent',
  props: {
    items: Array
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>


생성한 component 를 import 하도록 "main.js" 파일을 아래와 같이 수정합니다.
코드 설명을 대충 하면 firstComponent 와 secondComponent 를 import 해서 각각의 component를 Vue.component install 하는 코드 입니다. 
나중에 component 가 또 추가가 되면 import 하는 부분과 const components 변수, export default 부분에 추가를 해주면 됩니다.

main.js
import First from './components/firstComponent.vue'
import Second from './components/secondComponent.vue'

const components = [
  First,
  Second
];

const install = function(Vue) { 
  components.forEach(component => {
    Vue.component(component.name, component);
  });
};

/* istanbul ignore if */
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}

export default {
  First,
  Second
}

마지막으로 build 하는 명령어를 추가하기 위해 "package.json" 파일을 수정합니다.
"scripts" 에 아래와 같이 "libbuild" 추가합니다.
"libbuild": "vue-cli-service build --target wc --name test-component 'src/main.js'"
제가 대충 구분을 하기 위해서 libbuild 라고 추가 했는데 본인이 생각하는 prefix 를 사용하시면 되겠습니다.
vue-cli-service 명령어에 포함되는 --name 은 생성한 component 프로젝트 명이어야 하고, 아까 수정한 main.js 파일을 빌드해야 합니다.


package.json
{
  "name": "test-component",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "libbuild": "vue-cli-service build --target wc --name test-component 'src/main.js'"
  },
  "dependencies": {
    "core-js": "^3.4.3",
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.1.0",
    "@vue/cli-plugin-eslint": "^4.1.0",
    "@vue/cli-service": "^4.1.0",
    "babel-eslint": "^10.0.3",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "vue-template-compiler": "^2.6.10"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}


아래 명령어를 수행하여 빌드를 진행합니다.
npm run libbuild
빌드가 완료 되면 dist 폴더에 생성되는 것을 확인할 수 있습니다.

빌드가 되면 demo.html 파일도 같이 생성 되는데, 이 파일은 외부 lib 형태의 vue 예제로 만들어주지는 않습니다.
그래서 아래와 같이 수정하여 외부 component 처럼 사용할 수 있는 것을 테스트 해 볼 수 있습니다.


dist/demo.html
<meta charset="utf-8">
<title>test-component demo</title>
<script src="https://unpkg.com/vue"></script>
<script src="./test-component.min.js"></script>


<div id="app">
    <first-component v-bind:message="message"></first-component>
    <second-component v-bind:items="items"></second-component>
</div>
<script>
     var vue = new Vue({
        el : "#app",
        data : function() {
            return {
                message : "test",
                items : [ "item1", "item2", "item3", "item4" ]
            }
        }
     });
</script>






Elasticsearch + nori + 사용자사전, 유의어사전


이전 글에서 Elasticsearch 및 nori 설치를 했습니다.
elasticsearch 및 nori 설치는 이전 글을 참고 부탁드립니다.
https://sooyeol86.blogspot.com/2019/12/elasticsearch-with-nori-feat-docker.html

이번 글에서는 사용자정의 사전이나 유의어사전을 추가하는 방법에 대해서 설명을 합니다.
추가적으로 nori 필터를 사용함에 있어서 품사에 대해서 어느정도 지식이 필요할 수 있기 때문에 품사에 대한 간략한 정리도 했습니다.


Elasticsearch에 nori를 설치 하면 기본적인 형태소 분석기 및 사전을 사용할 수 있습니다.
하지만, 때때로 사용자 정의 사전이나 유의어가 필요할 수도 있겠습니다.

예를 들면 "삼성전자" 라는 단어는 사전에 없는 단어이기 때문에 아래 이미지와 같이 "삼성" / "전자" 로 단어를 분리합니다.
  


이 단어를 한 단어로 사용을 하고 싶다면 사용자 정의 사전에 추가를 해야합니다.

그리고 "삼성전자" = "삼전" 이라고 표현을 할 수도 있겠는데, 따로 유의어를 등록하지 않으면 "삼전" 이라고 했을 때 "삼성전자" 에 대해서 검색을 해오지 못합니다.
유의어 사전에 "삼성전자,삼전" 이라고 등록을 해두면 "삼전" 검색 시 "삼성전자"도 같이 검색이 되겠지요.

그럼 간략하게 진행을 해보도록 하겠습니다.


  1. 사용자 사전 파일 생성
docker-elk/elasticsearch/config/ 폴더에 user_dic.txt 파일을 생성 하고 첫번째 Line"삼성전자" 라고 등록을 합니다.


  1. 유의어 사전 파일 생성
docker-elk/elasticsearch/config/ 폴더에 synonyms.txt 파일을 생성하고 첫번째 Line"삼성전자,삼전" 이라고 등록을 합니다.

  1. docker 설정 파일에서 user_dic.txt / synoyms.txt 파일 복사하도록 설정
docker-elk/elasticsearch/Dockerfile 을 열어서 아래 내용을 추가 합니다.
COPY config/user_dic.txt config/user_dic.txt
COPY config/synonyms.txt config/synonyms.txt


  1. docker 재실행
ctrl + c 혹은 docker-compose down -v 를 통하여 docker 를 전부 종료 합니다.
docker-compose up --build -d 를 통하여 docker 를 실행합니다. (-d 옵션은 background 에서 돌리는 옵션)

  1. 파일 추가 여부 확인
docker ps 를 하고 docker-elk_elasticsearch 에 대한 container_id 를 획득하여
docer exec -it [container_id] bash 를 수행합니다. (container 내부로 접속하는 명령어)

그런다음 config 폴더를 확인해보면 아래와 같이 user_dic.txt synonyms.txt 파일이 추가 된 것을 확인할 수 있습니다.


  1. 인덱스 생성 및 테스트
아래와 같이 인덱스를 생성합니다.
아래 filter 내용을 참고하여 nori_part_of_speech 에 대한 조정이 필요한 경우 조정해야 합니다.
인터넷에 돌아다니는 예제 들의 경우 이것저것 품사들을 제거해서 실제로 원하는 analyzer를 했을 때 결과물이 안나올 가능성도 큽니다.
구축하고자 하는 사이트에 맞게 해당 필터를 사용하시기 바랍니다.


PUT test2
{
  "settings": {
    "analysis": {
      "tokenizer": {
        "nori_user_dict": {
          "type": "nori_tokenizer",
          "decompound_mode": "mixed",
          "user_dictionary": "user_dic.txt"
        }
      },
      "analyzer": {
        "korean_analyzer": {
          "filter": [
            "pos_filter_speech", "nori_readingform",
            "lowercase", "synonym", "remove_duplicates"
          ],
          "tokenizer": "nori_user_dict"
        }
      },
      "filter": {
        "synonym" : {
          "type" : "synonym_graph",
          "synonyms_path" : "synonyms.txt"
        },
        "pos_filter_speech": {
          "type": "nori_part_of_speech",
          "stoptags": [
            "E", "J", "SC", "SE", "SF", "SP", "SSC", "SSO", "SY", "VCN", "VCP",
            "VSV", "VX", "XPN", "XSA", "XSN", "XSV"
          ]
        }
      }
    }
  }
}
아래와 같이 analyze를 실행하면 "삼전" / "삼성전자" 가 나오는 것을 확인할 수 있습니다.



POST test2/_analyze
{
    "analyzer":"korean_analyzer",
    "text":"삼성전자"
}

  1. 생성한 인덱스 필터에 대한 설명
자세한 설명 및 추가 사용가능한 필터는 elasticsearch 사이트 참고

nori_part_of_speech : 품사 제거 필터

nori_readingform : 한자 to 한글 필터


synonym_graph : 유의어 필터


  1. nori_part_of_speech 필터 사용을 위한 간략한 품사 정리
nori 의 경우 lucense/mecab 기반으로 만들어졌기 때문에, mecab 사전을 참고하면 조금 도움이 될 수 있습니다.
(Tag의 경우 lucene 을 참고 하고 사전은 mecab gitgub 참고)
간략하게 예제와 품사에 대한 설명을 적긴 했지만 헷갈릴수 있으니 헷갈리면 직접 찾아보시길 권장..

E : 어미 [Verbal endings]
어간 뒤에 놓이는 굴절 접사
ex) 하고,,습니다,,

IC : 감탄사 [Interjection]
말하는 이의 본능적인 놀람이나 느낌, 부름, 응답 따위를 나타내는 말의 부류
ex) 만세,맙소사,아이고

J : 조사 [Ending Particle]
주로 체언에 붙어 뒤에 오는 다른 단어에 대하여 가지는 문법적 관계를 표시하거나 그 말의 뜻을 도와주는 품사
ex) ~보다,~까지

MAG : 부사 [General Adverb]
동사, 형용사, 동사구, 문장 전체를 수식하는 역할을 맡는 품사
ex) 힘껏,즉시,번쩍

MAJ : 접속부사 [Conjunctive adverb]
문장과 문장 사이를 접속해(연이어) 주는 부사
ex) 그러나,왜냐하면,그리고

MM : 관형사 [Determiner]
체언 앞에 놓여서 체언의 내용을 자세히 꾸며 주는 품사
ex) ,,그딴,수천수만

NNB : 의존명사 [Dependent noun(following nouns)]
의미가 형식적이어서 다른 말 아래에 기대어 쓰이는 명사
ex) ,따름,동안,무렵,이상

NNBC : 분류사 [Dependent noun]
단위를 나타내는 명사
ex) 퍼센트,군단

NNG : 보통명사 [General Noun]
일반 개념을 표시하는 명사. 여러 가지 사물의 공통된 특성을 나타낸다

NNP : 고유명사 [Proper Noun]
특정한 대상이나 유일한 대상을 가리키는 명사의 일종.

NP : 대명사 [Pronoun]
사람이나 사물, 장소를 직접 가리키는 기능을 하는 품사
ex) 이것저것,귀하,그거

NR : 수사 [Numeral]
사물의 수량이나 순서를 나타내는 단어의 한 부류
ex) ,,예닐곱,오륙백

VA : 형용사 [Adjective]
품사의 하나로 사람이나 사물의 성질과 상태 또는 존재를 나타내는 말
ex) 가녀린,잔망스럽,올바른

VCN : 부정 지정사 [Negative designator]
지정사 : 어떤 대상을 지정할 때 사용하는이다아니다를 가리키는 품사
ex) 아니,아닌

VCP : 긍정 지정사 [Positive designator]
ex) ,보이,사이

VV : 동사 [Verb]
사람이나 사물의 움직임 또는 작용을 나타내는 말

VX : 보조용언 [Auxiliary Verb or Adjective]
조적 기능을 수행하는 동사의 부류. 즉 뒤에 있는 동사구가 앞의 동사에 어떤 보조의 의미를 첨가하는 기능을 한다
ex) 헷갈리,잡수

XPN : 체언접두사 [Prefix]
체언 : 조사의 도움을 받아 문장에서 주체의 구실을 하는 단어
ex) (새 것, 새 날)

XR : 어근 [Root]
단어의 실질적 의미를 나타내는 중심 부분
ex) 불그스름,희뿌염,일목요염

XSA : 형용사 파생 접미사 [Adjective Suffix]
접미사 : 접사의 하나로 낱말의 끝에 붙어 의미를 첨가하여 다른 낱말을 이루는 말
ex) 못마땅하,스럽

XSN : 명사 파생 접미사 [Noun Suffix]
ex) 치레,투성이

XSV : 동사 파생 접미사 [Verb Suffix]
ex) 되잖,시키

NA, UNA, Unknown, VSV : 알수없는 [unknown]
SC : 구분기호 [Separator (· / :)]
SE : 생략 [Ellipsis]
SF : 물음표,느낌표,마침표 [Terminal punctuation (? ! .)]
SH : 한자 [Chinese character]
SL : 외국어 [Foreign language]
SN : 숫자 [Number]
SP : 공백 [Space]
SSC 닫는 괄호 [Closing brackets]
SSO : 여는 괄호 [Opening brackets]
SY : 기타 기호 [Other symbol]


추가적으로 아래 사이트를 참고 하면 도움이 될듯 합니다.

간단한 AWS 웹 서버 구축 with mongodb (feat. Github and Docker)

오랫만에 블로그에 게시글을 업데이트 해봅니다. 최근에 AWS 로 서버 구축하는 것을 테스트 해본 것이 있어서, 이번 게시글에서는 AWS 를 사용하여 간단하게 웹 서버 구축하는 것을 진행하려고 합니다. AWS EC2 서버 프리티어 버전으로 1대 발급 받...