Web/Vue.js

Vue.js__02 (Vue CLI)

5_ssssseung 2021. 5. 15. 01:57

 

Component

  • 기본 HTML 엘리먼트를 확장하여 재사용 가능한 코드를 캡슐화 하는데 도움을 줌
  • CS에서는 다시 사용할 수 있는 범용성을 위해 개발된 소프트웨어 구성 요소를 의미
  • 즉, 컴포넌트 개발을 함에 있어 유지보수를 쉽게 만들어 줄 뿐만 아니라, 재사용성의 측면에서도 매우 강력한 기능을 제공
  • Vue 컴포넌트 === Vue 인스턴스
  • Vue Component 구조 예시

image




SFC

Single File Component

  • Vue의 컴포넌트 기반 개발의 핵심 특징
  • 하나의 컴포넌트.vue라는 하나의 파일 안에서 작성되는 코드의 결과물
  • 화면의 특정 영역에 대한 HTML, CSS, JavaScript 코드를 하나의 파일(.vue)에서 관리
  • 즉, .vue 확장자를 가진 싱글 파일 컴포넌트를 통해 개발하는 방식
  • Vue 컴포넌트 === Vue 인스턴스 === .vue 파일



Vue CLI

  • Vue.js 개발을 위한 표준 도구
  • 프로젝트의 구성을 도와주는 역할을 하며 Vue 개발 생태계에서 표준 tool 기준을 목표로 함
  • 확장 플러그인, GUI, ES2015 구성 요소 제공 등 다양한 tool 제공

Node.js

  • 자바스크립트를 브라우저가 아닌 환경에서도 구동할 수 있도록 하는 자바스크립트 런타임 환경

    • 브라우저 밖을 벗어 날 수 없던 자바스크립트 언어의 태생적 한계를 해결
  • Chrome V8 엔진을 제공하여 여러 OS 환경에서 실행할 수 있는 환경을 제공

  • 즉, 단순히 브라우저만 조작할 수 있던 자바스크립트를 SSR에서도 사용 가능하도록 함


NPM

Node Package Manage

  • 자바스크립트 언어를 위한 패키지 관리자

    • Python의 pip가 있다면 Node.js에는 NPM
    • pip와 마찬가지로 다양한 의존성 패키지를 관리
  • Node.js의 기본 패키지 관리자

  • Node.js와 함께 자동으로 설치 됨


Vue CLI 설치

  • vue-cli 설치
$ npm install -g @vue/cli
  • 버전 확인
$ vue --version
  • 프로젝트 생성
$ vue create <my-first-vue-app>
  • run server
$ npm run serve



Babel & Webpack


Babel

JavaScript Transcomiler

  • 자바스크립트의 신버전 코드를 구버전으로 번역/변환 해주는 도구

  • 자바스크립트 역사에 있어서 파편화와 표준화의 영향으로 작성된 코드의 스펙트럼이 매우 다양

    • 최신 문법을 사용해도 브라우저의 버전별로 동작하지 않는 상황 발생
    • 같은 의미의 다른 코드를 작성하는 등의 대응이 필요해졌고 이러한 문제를 해결하기 위한 도구
  • 원시 코드(최신 버전)를 목적 코드(구 버전)으로 옮기는 번역기가 등장하면서 개발자는 더 이상 내 코드가 특정 브라우저에서 동작하지 않는 상황에 대해 크게 고민하지 않을 수 있음


  • Babel 동작 예시
// Babel Input: ES2015 arrow function
[1, 2, 3].map(n => n + 1);

// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
  return n + 1;
});

Webpack

static module bundler

  • 모듈 간의 의존성 문제를 해결하기 위한 도구

Module

  • 모듈을 단지 파일 하나를 의미 (ex. 스크립트 하나 === 모듈 하나)
  • 배경

    • 브라우저만 조작할 수 있었던 시기의 자바스크립트는 모듈 관련 문법 없이 사용 되어짐
    • 하지만 자바스크립트와 애플리케이션이 복잡해지고 크기가 커지자 전역 스코프를 공유하는 형태의 기존 개발 방식의 한계점이 드러남
    • 그래서 라이브러리를 만들어 필요한 모듈을 언제든지불러오거나 코드를 모듈 단위로 작성하는 등의 다양한 시도가 이루어짐
  • 과거 모듈 시스템

    • AMD, CommonJS, UMD
  • 모듈 시스템 2015년 표준으로 등재 되었으며 현재는 대부분의 브라우저와 Node.js가 모듈 시스템을 지원


Moduel 의존성 문제

  • 모듈의 수가 많아지고 라이브러리 혹은 모듈 간의 의존성(연결성)이 깊어지면서 특정한 곳에서 발생한 문제가 어떤 모듈간의 문제인지 파악하기 어려워짐 (의존성 문제)
  • Webpack은 모듈간의 의존성 문제를 해결하기 위한 존재하는 도구

Bundler

  • 모듈 의존성 문제를 해결해주는 작업이 Bundling이고 이러한 일을 해주는 도구가 Bundler

    • Webpack은 다양한 Bundler 중 하나
  • 모듈들을 하나로 묶어주고 묶인 파일은 하나(혹은 여러개)로 만들어짐

  • Bundling된 결과물은 더 이상 순서에 영향을 받지 않고 동작하게 됨

  • Bundling 과정에서 문제가 해결되지 않으면 최종 결과물을 만들어 낼 수 없기 때문에 유지, 보수 측면에서도 매우 편리해짐

    • snowpack, parcel, rollup.js 등의 webpack 이외에도 다양한 모듈 번들러 존재
  • Vue CLI는 이러한 Babel, Webpack에 대한 초기 설정이 자동으로 되어 있음


  • 의존성 문제 예시

image

image


  • Webpack 도식화

image


Vue CLI 구조

  • node_modules

    • node.js 환경의 여러 의존성 모듈
  • public/index.html

    • Vue 앱의 뼈대가 되는 html 파일
  • src/assets

    • webpack에 의해 빌드된 정적 파일
  • src/components

    • 하위 컴포넌트들이 위치
  • src/App.vue

    • 최상위 컴포넌트
  • src/main.js

    • webpack이 빌드를 시작할 때 가장 먼저 불러오는 entry point
    • 실제 단일 파일에서 DOM과 data를 연결했던 것과 동일한 작업이 이루어지는 곳
    • Vue 전역에서 활용할 모듈을 등록할 수 있는 파일
  • babel.config.js

    • babel 관련 설정이 작성된 파일
  • package.json

    • scripts - 사용할 명령어 script
    • dependencies - 개발 + 배포 환경에서까지 활용할 모듈
    • devDependencies - 개발단계에서만 활용할 모듈
  • package-lock.json

    • node_modules에 설치되는 모듈과 관련해서 모든 의존성을 설정 및 관리

      • 팀원 및 배포 환경에서 정확히 동일한 종속성을 설치하도록 보장하는 표현
      • 사용할 패키지의 버전을 고정
    • 개발 과정간의 의존성 패키지 충돌 방지


Pass Props & Emit Events

  • 부모는 자식에게 데이터를 전달(Pass props)하며, 자식은 자신에게 일어난 일을 부모에게 알림(Emit event)

    • 부모와 자식이 명확하게 정의된 인터페이스를 통해 격리된 상태로 유지할 수 있음
  • props는 아래로, events는 위로

  • 부모는 props를 통해 자식에게 데이터를 전달하고, 자식은 events를 통해 부모에게 메시지를 보냄

image


Props

  • prop는 상위 컴포넌트의 정보를 전달하기 위한 사용자 지정 특성

  • 하위 컴포넌트는 props 옵션을 사용하여 수신하는 props를 명시적으로 선언해야 함

  • 즉, 데이터는 props 옵션을 사용하여 하위 컴포넌트로 전달됨

  • !주의!

    • 하위 컴포넌트의 템플릿에서 상위 데이터를 직접 참조할 수 없음
  • props 컨벤션

    • in HTML

      • kebab-case
    • in scirpt

      • camelCase

단방향 데이터 흐름

  • 모든 props는 하위 속성과 상위 속성 사이의 단방향 바인딩을 형성

  • 부모의 속성이 변경되면 자식 속성에게 전달되지만, 반대 방향으로는 불가능

    • 자식 요소가 의도치 않게 부모 요소의 상태를 변경함으로써 앱의 데이터 흐름을 이해하기 어렵게 만드는 일을 막기 위함
  • 부모 컴포넌트가 업데이트될 때마다 자식 요소의 모든 prop들이 최신 값으로 업데이트 됨


Emit event

  • $emit(event)

    • 현재 인스턴스에서 이벤트를 트리거
    • 추가 인자는 리스너의 콜백 함수로 전달
  • 부모 컴포넌트는 자식 컴포넌트가 사용되는 템플릿에서 v-on을 사용하여 자식 컴포넌트가 보낸 이벤트를 청취 (v-on을 이용한 사용자 지정 이벤트)


  • event 컨벤션

    • 컴포넌트 및 props와는 달리, 이벤트는 자동 대소문자 변환을 제공하지 않음
    • HTML의 대소문자 구분을 위해 DOM 템플릿 v-on 이벤트 리스너는 항상 자동으로 소문자 변환되기 때문에 v-on:myEvent는 자동으로 v-on:myevent로 변환
    • 이러한 이유로 이벤트 이름에는 kebab-case를 사용하는 것을 권장



Vue Router

  • Vue.js의 공식 라우터
  • 중첩된 라우트/뷰 매핑 모듈화 된 컴포넌트 기반의 라우터 설정 등
  • SPA 상에서 라우팅을 쉽게 개발할 수 있는 기능을 제공

router-link

  • index.js 파일에 정의한 경로에 등록한 특정한 컴포넌트와 매핑
  • HTML5 히스토리 모드에서, router-link는 클릭 이벤트를 차단하여 브라우저가 페이지를 다시 로드하지 않도록 함
  • a 태그지만 우리가 알고 있는 GET 요청을 보내는 a 태그와 조금 다르게 기본 GET 요청을 보내는 이벤트를 제거한 형태로 구성

router-view

  • 실제 component가 DOM에 부착되어 보이는 자리를 의미
  • router-link를 클릭하면 해당 경로와 연결되어 있는 index.js에 정의한 컴포넌트가 위치

components vs views

  • 컴포넌트를 만들어 갈 때 정해진 구조가 있는 것은 아님
  • 주로 아래와 같이 구조화 하여 활용
App.vue
  - 최상위 컴포넌트
  
views/
  - router(index.js)에 매핑되는 컴포넌트를 모아두는 폴더
  - ex) App 컴포넌트 내부에 About & Home 컴포넌트 등록
  
components/
  - router에 매핑된 컴포넌트 내부에 작성하는 컴포넌트를 모아두는 폴더
  - es) Home 컴포넌트 내부에 HelloWorld 컴포넌트 등록

History mode

  • HTML history API를 사용해서 router를 구현한 것
  • 브라우저의 히스토리는 남기지만 실제 페이지는 이동하지 않는 기능을 지원

Vue Router가 필요한 이유

  1. SPA 등장 이전

    • 서버가 모든 라우팅을 통제
    • 요청 경로에 맞는 HTML 제공
  2. SPA 등장 이후

    • 서버는 index.html 하나만 제공
    • 이후 모든 처리는 HTML 위에서 JS 코드를 활용해 진행
    • 즉, 요청에 대한 처리를 더 이상 서버가 하지 않음 (할 필요가 없음)
  3. 라우팅 처리 차이

    • SSR

      • 라우팅에 대한 결정권을 서버가 가짐
    • CSR

      • 클라이언트는 더 이상 서버로 요청을 보내지 않고 응답받은 HTML 문서 안에서 주소가 변경되면 특정 주소에 맞는 컴포넌트를 렌더링
      • 라우팅에 대한 결정권을 클라이언트가 가짐
    • Vue Router는 라우팅의 결정권을 가진 Vue.js에서 라우팅을 편리하게 할 수 있는 Tool을 제공해주는 라이브러리


'Web > Vue.js' 카테고리의 다른 글

Vue.js_03 (Vuex)  (0) 2021.05.16
Vue.js__01 (Vue Instance & Syntax)  (0) 2021.05.14
Vue.js_00 Intro  (0) 2021.05.14