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
먼저 번들링이라는걸 이해해야하는데
우리가 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
tip. 만약 프로젝트가 방대해 부분적으로 번들링 했을 때 유리한 경우 rollup기능을 이용하면 됨
2022-11-27 업데이트
'vue.js > 기술' 카테고리의 다른 글
[vue] 비동기 컴퍼넌트 lazy loading | _defineAsyncComponent() (0) | 2022.04.14 |
---|---|
[vue] 클래스 바인딩하는 여러 방법 (0) | 2022.04.12 |
[vue] 이벤트 버블링 관련 수식어 (0) | 2022.03.17 |
[vue] debounce 사용하기 feat.(throttle) (0) | 2022.03.16 |
[vue] $nextTick 사용하기 (0) | 2022.03.16 |
댓글