BeNI 2022. 12. 12. 01:31
728x90

 

1. Node.js 와 npm

1) Node.js

: JavaScript 엔진으로 빌드 된 JavaScript 런타임

 

2) npm

Node Packaged Manager,  모듈을 웹에서 받아서 설치하고 관리해주는 프로그램

 

+ nvm : Node.js의 버전을 관리해주는 프로그램

+ npm n : 맥 버전 node.js 버전 관리

nvm use 14 // node js 버전을 14버전으로 바꿈

 

 

2. npm 프로젝트 빌드

npm init
npm init -y // 질문 생략

 

1) package.json 파일 구성

{
  "name": "프로젝트 이름",
  "version": "1.0.0",
  "description": "설명",
  "scripts": {
	// 사용자 빌드 키워드
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    // 개발 환경에서의 의존성
  },
  "dependencies": {
    // 실제 프로젝트 관련 모듈(일반 의존성)
  }
}

* 현재 만드는 뷰 프로젝트는 외부에서 접근할 진입점이 필요 없어서 main 옵션을 생략해도 된다.

* 버전에 ^ 표시는 그 버전 이상이라는 의미(2, 3번째 숫자만)

 

2) npm으로 뷰 설치

npm install vue // 기본 버전 설치
npm info vue // 뷰 설치 정보 보기
npm i vue@3.2.9 // 3.2.9 버전 설치

npm un(install) vue // 뷰 삭제

 

 

3. npx

: x는 동작한다는 의미. serve라는 패키지를 동작시킨다.

- npm도 설치되면 자동으로 npx 도 설치됨

 

📌 설치 방법

npx serve
npm i serve --save-dev(-D)
 
 

 

 

4. parcel

1) 설치 모듈

npm init -y
npm i vue
npm i -D parcel  (devdependency 로 들어감)

 

2) 과정

ⓐ 루트 프로젝트에 index.html, main.js, App.vue 생성

 

ⓑ index.html에 main.js 불러오기

<script defer src="./main.js"></script>

*defer 옵션 쿼리셀렉터 가 정상적으로 실행될수 있게함

 

ⓒ main.js에 App 컴포넌트 불러오기

import * as Vue from "vue"; // 뷰는 따로 이름을 정해줘야함
import App from "./App.vue";

Vue.createApp(App).mount("#app");
 
 

ⓓ App.vue 작성

// 기본 구조
<template>
</template>

<script>
export default {
  data() {
    return {
    };
  },
};
</script>

<style lang="scss"> 
// scss 작성하려면 npm i sass -D 로 설치
</style>
 
 
ⓔ package.json script 작성
  "scripts": {
    "dev": "parcel ./src/index.html",
    "build": "parcel build ./src/index.html"
  },

* script 내용을 실행할 때는 사용자 키워드 앞에 npm run을 붙여야 한다.
* 빌드하면 dist 폴더가 생성되고, 난독화된 html js파일이 들어있다.
 
 
✅ parcel로 빌드시 gitignore 내용
node_modules/ 
.vscode/
.idea/
.DS_Store/​
 
 

 

5. webpack

1) 설치 모듈

npm init -y
npm i -D webpack webpack-cli

 

2) 루트 디렉토리에 webpack.config.js 생성

const path = require("path");

module.exports = {
  entry: "./src/main.js", // 시작 지점
  output: {
    path: path.resolve(__dirname, "dist"), // 절대 경로여야한다.
    // filename: (default) main
  },
};

* __dirname : 실행 시 현재 파일 경로로 바뀐다.(루트 디렉토리가 됨)

* path.resolve : 두 path를 합침 => 현재디렉토리/dist  경로가 됨

 

3) script 작성 후 빌드

  "scripts": {
    "build": "webpack"
  },

* npm run build

* 명령어 실행 후 dist 폴더에 난독화된 합쳐진 코드파일이 만들어져 있다.

 

 

6. webpack으로 Vue 프로젝트 빌드

1) 설치 모듈

npm init -y
npm i vue vue-loader @vue/compiler-sfc 
npm i -D webpack webpackcli webpack-dev-server
npm i -D html-webpack-plugin
npm i -D css-loader vue-style-loader
npm i -D sass sass-loader
npm i -D copy-webpack-plugin
npm i -D eslint eslint-plugin-vue
  • npm init -y : 기본 설정으로 프로젝트 초기화
  • vue, vue-loader :  뷰 관련 모듈, 웹펙으로 뷰를 로드하기 위한 모듈
  • @vue/compiler-sfc : 뷰 파일을 컴파일 하기 위한 모듈(뷰랑 버전 같아야함)
  • webpack : 웹팩 관련 모듈
  • webpack-cli : 터미널에서 명령어를 입력할 수 있게하는 도구
  • webpack-dev-server : 개발 서버를 오픈하는 용도의 모듈
  • html-webpack-plugin : 웹팩 실행 결과물에 html 파일을 자동으로 작성해주는 도구

       * 위 모듈이 없으면 dist 내 index.html 파일을 작성해줘야한다.

  • css-loader vue-style-loader : css 파일 불러오기 위한 모듈/ vue css 로드하기위한 모듈 
  • sass sass-loader : sass 이용하기 위한 모듈
  • copy-webpack-plugin 디렉토리를 카피하여 dist에 들어갈 수 있도록 설정하는 플러그인

      * 이미지나 파비콘 사용할 때 보통 쓰는 플러그인

  • eslint : 코드 작성 규칙 지정하는 모듈 (루트 경로에 .eslintrc.json 파일 생성 해야함)

 

 

2) webpack.config파일 작성

ⓐ entry, output 옵션
entry: "./src/main.js",
output: {
    path: path.resolve(__dirname, "dist"),
    clean: true,
},

- entry : 시작 지점 파일 경로

- output : 최종 파일 경로

* clean : 최종 경로에 쓸데없는 파일은 삭제해주는 옵

 

ⓑ module 옵션

 module: {
    rules: [
      {
        test: /\.vue$/,
        use: "vue-loader",
      },
      {
        test: /\.scss$/, // s?css 로하면 scss, css 둘다 가능
        use: ["vue-style-loader", "css-loader", "sass-loader"],
      },
    ],
  },

- module안에는 객체리터럴로, rules 옵션을 정의한다.

- rules는 객체 배열 형태로 test에 정의한 정규표현식과 일치한 파일들을 use에 있는 모듈을 사용하게 해준다.

* /\.vue$/ : .vue 로 끝나는 파일

- use 옵션은 순서가 있음! 제일 왼쪽부터가 제일 나중에 로드되야 하는 모듈이다.

 

 

ⓑ plugins 옵션

const { VueLoaderPlugin } = require("vue-loader");
const HTMLPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");

plugins: [
    new VueLoaderPlugin(),
    new HTMLPlugin({
      template: "src/index.html",
    }),
    new CopyPlugin({
      patterns: [
        {
          from: "static",
          // to: 'dist'
        },
      ],
    }),
  ],
- VueLoaderPlugin : vue-loader를 사용하기 위한 플러그인
- HTMLPlugin : html-webpack-plugin 사용하기 위한 플러그인(template: 어떤 파일을 import 할껀지)
* 이 플러그인은 자동으로 path.resolve를 사용하기 때문에 상대 경로로 작성해도된다.
- CopyPlugin : static 폴더를 dist 경로로 복사해주는 플러그인 (to는 output 옵션때문에 생략가능)
* 루트 경로에 static 폴더를 만들어 주고 이미지나 파비콘을 해당 폴더에 넣으면 됨
 

 

ⓒ mode 옵션

 

- 개발 용인지, 배포 용인지 구분하기 위해 사용
- 이 옵션을 사용하지 않으면 package.json파일 내 script에 직접 배포용인지 개발용인지 기입해 줘야한다.
* 옵션 없어도 오류는 안남
  "scripts": {
    "dev": "webpack-dev-server --mode development", // 개발서버 오픈
    "build": "webpack --mode production"
  },

 

ⓓ devServer 옵션

devServer: {
  port: 1234,
},
- 개발 서버 옵션으로 포트번호 지정 가능(기본값 8080)
 

node modules에 설치된 패키지 이름을 그대로 가져와서 ㅆ르수이승ㅁ

패키지 안, index.js에 의해 export 되는거임

 

ⓔ resolve 옵션

  resolve: {
    extensions: [".vue", ".js"],
    alias: {
      "~": path.resolve(__dirname, "src"),
    },
  },

- extentsion: 프로젝트 파일에서 import할 때 해당 확장자 생략 가능

- alias : 해당 디렉토리의 alias 지정 가능 (현재파일경로/src => ~ 가 됨)

더보기

= webpack.config.js 전체 내용 =

const path = require("path");
const { VueLoaderPlugin } = require("vue-loader");
const HTMLPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");

 

module.exports = {
  resolve: {
    extensions: [".vue", ".js"],
    alias: {
      "~": path.resolve(__dirname, "src"),
    },
  },
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: "vue-loader",
      },
      {
        test: /\.scss$/,
        use: ["vue-style-loader", "css-loader", "sass-loader"],
      },
    ],
  },
  plugins: [
    new VueLoaderPlugin(),
    new HTMLPlugin({
      template: "src/index.html",
    }),
    new CopyPlugin({
      patterns: [
        {
          from: "static",
          // to: 'dist'
        },
      ],
    }),
  ],
  // devServer: {
  //   port: 1234,
  // },
};

 

✅ gitignore 파일

node_modules/ 
.vscode/
.idea/
.DS_Store/
dist/

 

7. 컴포넌트 등록

 

1) 등록 방법

ⓐ 전역 등록

import { createApp } from 'vue'

const app = createApp({})

app.component(MyComponent)
app.component('my-component', MyComponent) // my-component 이름으로 컴포넌트 사용

 

ⓑ 지역 등록

- 해당 컴포넌트 내 components 옵션에 불러오면된다.

<template>
  <Hello />
</template>

<script>
import Hello from "~/components/Hello";
export default {
  components: {
    Hello,
  },
};
</script>

 

3) props

ⓐ 기본 사용 방법

export default {
  props: ['foo'],
  created() {
    console.log(this.foo) // 콘솔에 출력 가능
  }
}

 

- props의 타입 지정을 할 수 있다.

export default {
  props: {
    title: String,
    likes: [Number, String] // 둘 다 허용
  }
}

 

📌 프롭스 대소문자 : props에서 카멜케이스로 써도 html에서는 케밥케이스로 작성해야한다.

- props로 postTitle라고 썼으면 html 태그 에서는 post-title 이라고 써야함

 

 

ⓑ props의 데이터

- 하위컴포넌트에서 상위 컴포넌트의 data를 직접적으로 수정할수 없다.

export default {
  props: ['foo'],
  created() {
    // ❌ warning, props are readonly!
    this.foo = 'bar'
  }
}

 

4) non-props 속성

: props로 지정되지않은 나머지 속성들로 이루어진 객체

 

- 하위 컴포넌트에서 $attrs 로 가져올 수 있다.

<template>
  <h1 :class="$attrs.class">{{ id }} / {{ title }} / {{ email }}</h1>
  <h1>{{ id }} / {{ title }} / {{ email }}</h1>
</template>

- $attrs는 하위 컴포넌트의 내부 요소가 한 개일때 자동으로 하위 컴포넌트에 적용이 되는 속성임 

inheritAttrs: false; // 상속 안되게 하기

 

 

5) 커스텀 이벤트

- 상위 컴포넌트의 데이터를 하위 컴포넌트에서 변경하기

ⓐ 상위 컴포넌트

<Hello :message="msg" @update="msg = $event" />

- 하위 컴포넌트에서 지정한 'update' 이벤트가 실행되게 함

- $event는 하위컴포넌트에서 작성한 $event.target.value가 들어온다. 

 

ⓑ 하위 컴포넌트

<template>
  <label>
    <input
      :value="message"
      type="text"
      @input="$emit('update', $event.target.value)"
    />
  </label>
</template>
<script>

 

ex) 양방향 데이터 바인딩 사용하기

<Hello 
  v-model:message="msg"
  v-model:name="name" />
<template>
  <label>
    <input
      :value="message"
      type="text"
      @input="$emit('update:message', $event.target.value)"
    />
  </label>
  <label>
    <input
      :value="name"
      type="text"
      @input="$emit('update:name', $event.target.value)"
    />
  </label>
</template>
<script>

 

 

728x90