본문 바로가기
vue.js/기술

차세대 빌드 도구 vite (vue)

by 냉면돈가스 2022. 4. 7.

Webpack의 번들링과정이 길어 짜증날때 사용할 수 있는 빌드도구 vite를 써봄 (react에도 사용 가능)

 

우리는 vue를 사용할때 기본적으로 Webpack을 이용하여 빌드를한다.

vue create '프로젝트명'

위의 명령어로 vue project를 생성 시,

node_modules폴더나 package-lock.json 에 웹팩관련 모듈,설정들이 작성되어있어 vue는 웹팩을 기본으로 사용하는구나 알 수 있다.

 

다만 프로젝트의 크기가 커지면 커질수록 빌드할 시에 시간이 너무 오래걸린다. 

나같은 경우에는 프로젝트 생성만 10초쯤 걸리는듯.

 

이 대기시간이 짧은 빌드도구 vite가 있다해서 사용 해보기로 함

 

npm install -g vite
npm init vite@latest

먼저 vite를 설치 후, 프로젝트를 생성한다.

생성할 시에 

 - 프로젝트명,

 - 사용할 프레임워크 (vue,react등 vite에서 지원하는 것 들 중 선택)

 - description

등등을 순차적으로 선택,입력하여 설정할 수 있다.

 

모두 선택하면 해당 프로젝트가 생성되고 사용하면 된다.

 


 

해당 프로젝트로 이동 후, vue에서 사용하던 

npm run serve명령어는 npm run dev로 바꾸어서 입력하면 실행된다.

바꾸고싶을시엔 package.json의 scripts부분을 바꾸면 됨

 

 

단, node_modules는 자동으로 깔려있지않아 npm install을 한 번 해주어야 정상 작동됨

 


 

vite가 빠른 이유?

https://joshua1988.github.io/vue-camp/vite/intro.html#vite%E1%84%85%E1%85%A1%E1%86%AB

 

Introduction | Cracking Vue.js

Vite 비트(Vite) (opens new window)는 기존의 프런트엔드 개발 경험을 향상시켜줄 새로운 프런트엔드 툴입니다. Vue 창시자 에반 유가 만들었으며 현재 Vue, React, Svelte 등의 주요 프레임워크 커뮤니티에

joshua1988.github.io

 

먼저 번들링이라는걸 이해해야하는데

우리가 html,css,js로만 개발하던 때를 생각해보면

웹에 진입했을시 보통 html파일 받아오고, css파일 받아오고 js파일등 정적 파일들을 받아오게 되는데

만약 npm에서 여러 라이브러리들을 사용하여 수많은 js파일들까지 받아온다하면

웹 진입시에 수많은 요청이 일어나 그만큼의 자원이 소모되게된다.

 

이를 위해 웹팩에서 번들링이라는 개념을 사용하여

html,css,js등의 파일들을 한번에 묶어서 빌드 하는것이 번들링이고,

번들링덕분에 웹 진입시에 요청횟수가 최소화 되어 효율적이다.

 

이제 vite로 넘어가보면,

유사 번들러 도구들은

모든 소스코드에 대해 번들링작업이 이루어 져야 애플리케이션이 오픈된다합니다. (vite 공식문서 피셜)

vite는 이 문제를 dependencies / source code 

두 카테고리로 나누었고,

 

dependencies 는 개발시 내용이 바뀌지 않을 코드라 말하며,

source code 는 컴파일이 필요하며 주기적으로 내용이 바뀌는 코드라 말합니다.

 

여기서 dependencies 는 EsBuild의 사전 번들링을 이용하고,

source code쪽은 Native ESM 이라는 방식을 이용합니다.

 

이 Native ESM 이란것은 브라우저가 직접 판단해 그때 그때 필요한 파일들만 사용하는 방식이라는 듯 합니다.

(트리 쉐이킹)

 

 

1. vite는 ESM(자바스크립트 네이티브 모듈)을 사용한다고 하여 빠르다고 함.

2. 웹팩이전 만들때는 자바스크립트 레벨에서의 언어화 모듈이 없었다.

 

밑줄친 두 줄이 이해가 잘안돼서 추가조사함.


자바스크립트 모듈

 

1. 인라인

자바스크립트를 인라인 방식으로 사용한 방식

<!DOCTYPE html>
<html lang="en">
<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">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    function add(num1,num2) {
        return num1 + num2
    }  
</script>
</html>

이 방식으로는 add 함수를 다른 html에서 재사용할 수 없습니다.

물론 할 수는 있죠.

복사해서 붙여넣기로 다른 html파일에 넣어버린다면요.

 

 

 

2. script 태그로 불러오기

아래와 같이 주소를 참조해 가져온 후, 사용합니다.

<!DOCTYPE html>
<html lang="en">
<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">
    <title>Document</title>
    <script src="./module2_1.js"></script>
    <script src="./module2_2.js"></script>
</head>
<body>
    <script>
        let a = 2;
        let b = 3;
        console.log(multiply(a,b));
    </script>
</body>
</html>

//module2_1.js

function add(num1, num2) {
    return num1 + num2;
}

//module2_2.js

function multiply(num1, num2) {
    return add(num1,num2) * num2;
}

 

이 방식도 의존성과 관련해서 문제가 있는것이 

multply함수는 add함수를 지닌 module2_1.js이 먼저 로딩되어있어야 실행이 가능합니다.

만약 module2_2.js파일이 먼저 로딩되어버리고 multiply()함수를 실행한다면 에러가 나겠죠.

또한, 두 module2.js파일에서 같은이름의 함수를 사용하여 문제가 생길 수 도 있습니다.

 

 

3. 해당 모듈을 지정하여 함수를 호출하기

<!DOCTYPE html>
<html lang="en">
<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">
    <title>Document</title>
    <script src="./module3.js"></script>
</head>
<body>
    <script>
        console.log(calc.multiply(2,3));
    </script>
</body>
</html>

 

module3.js

const calc = (function() {
    const add = function(num1, num2) {
        return num1 + num2;
    }
    const multiply = function(num1, num2) {
        return add(num1,num2) * num2
    }

    return {
        add : add,
        multiply: multiply
    }
})();

위 방법으로 모듈을 참조할 시엔 cala 모듈에 접근후 함수를 호출하기때문에 함수명이 겹칠 일은 없다.

허나 multiply함수에 add 함수를 사용하기 위해 같이 한페이지에 작성하는 단점이 있음

 

 

 

4. require 방식

<!DOCTYPE html>
<html lang="en">
<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">
    <title>Document</title>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
    <!-- <script src="./module4_1.js" type="module"></script> -->
    <script>
        require(['module4_1'], function(calc){
            console.log(calc(3,2))
        })
    </script>
</head>
<body>
</body>
</html>

 

//module4_1.js

define(["module4_2"], function (add){
    const multiply = function (num1,num2) {
        return add(num1,num2) * num2
    }
    return multiply

});

 

//module4_2.js

define([], function() {
    const add = function(num1, num2) {
        return num1 + num2;
    }
    return add

});

 

따로 require.js 제외하고는 스크립트 태그주소를 달 필요가 없으며

html의 require에서 module4_1을 호출하고,

module4_1.js에서 add함수를 이용하기 위해 module4_2.js를 추가 호출한다.

 

위의 순서가 지켜저 의존성의 문제,

2. script 태그로 불러오기에서의 문제가 고쳐지며

3. 한 js파일에 관련함수를 모두 작성하는 일도 없어짐.

 

 

5. import&export 방식

 

es6문법이 표준이 지정되면서 import&export 모듈화 방식을 사용할 수 있게 됨

이전에는 require.js와 같은 도움이 없다면 자바스크립트 레벨에서의 언어화 모듈이 없었다.

import&export 모듈화 방식이 나오게되면서 웹팩같은 번들러도 같이 나왔다.

 

<!DOCTYPE html>
<html lang="en">
<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">
    <title>Document</title>
    <script type="module">
        import {multiply} from './module6_1.js'
        console.log(multiply(2,3));
    </script>
</head>
<body>
</body>
</html>

 

module6_1.js

import {add,add2} from './module6_2.js'

export const multiply = function(num1, num2) {
    return add(num1,num2) * num2;
}

 

module6_2.js

export const add = function(num1, num2) {
    return num1 + num2;
}
export const add2 = function(num1, num2) {
    return num1 + num2;
}

 

require방식과 비교하면 only 내부코드에서 모듈이 돌아가며 (require.js사용안함)

여러가지 함수들을 export하고, 원하는것만 import 가능하다.

 

 

 

6. ESM 방식

 

import&export 부분을 보면 script태그에 type="module" 이라고 작성한 것이 보인다.

이것처럼 type을 지정해주면 브라우저에서 별도의 도구없이 자체적으로 소화 해낼 수 있는 모듈방식이 ESM이다.

 

vite에서 index.html을 살펴보면 ESM방식으로 main.js를 바로 첨부하였고,

한 단계 더 나아가 Native ESM 방식을 사용함으로써 빌드과정이 기존보다 유리한 것으로 보임.

https://vitejs-kr.github.io/guide/why.html#the-problems

 

Vite를 사용해야 하는 이유 | Vite

Vite를 사용해야 하는 이유 이런 문제점이 있었어요 브라우저에서 ESM(ES Modules)을 지원하기 전까지는, JavaScript 모듈화를 네이티브 레벨에서 진행할 수 없었습니다. 따라서 개발자들은 "번들링(Bundl

vitejs-kr.github.io

 

tip. 만약 프로젝트가 방대해 부분적으로 번들링 했을 때 유리한 경우 rollup기능을 이용하면 됨


2022-11-27 업데이트

 

댓글