728x90

Module Bundler


일단 module bundler를 설명하기 전에 buildsystem에 대해서 이야기해야할 것 같다.

그런데 필자가 블로그를 하면서 정말 짜증나는건 설명했던걸 또 설명하는 것이다.

매번 학기가 바뀔 때 마다 똑같은 수업을 하는 교수님, 선생님의 마음을 여기서 이해할 수 있었다.

그래서 build system에대한 설명은 이 gulp포스팅의 도입부로 대채하려고 한다.

이거 읽고 넘어오시면 될거같다.


webpack은 사실 프론트엔드 빌드 시스템을 평정하다시피한 혁명적인 프로그램이다.

주 역활은 모듈번들러인데 모듈번들러를 잘 소개한 설명은 아래의 그림을 보면 이해할 수 있다.


웹을 구성하는 요소는 크게 보면 4가지이다.


html - 웹을 마크업 하는 언어, 쉽게 이야기하면 웹을 표현하는 언어이다.

css - 각각의 컴포넌트에 디자인을 표시하는 방식이다.

js - 웹에서 동작하는 스크립트 언어이다. 동적화면을 만드는데 필요하다.

resouce - 이미지(png, jpg 등),폰트(fft 등)등의 여러 요소들이다.

즉 실제로 여러분이 필요한것은


1개의 html파일, 1개의 css파일 1개의 js파일과 여러개의 resource파일이다.

물론 css나 js는 동적로딩을해서 여러개로 로딩해도 상관은 없다. 그러나 효율적인 구조는 하나만을 로딩하는 것이다.

그래서 한개씩으로 만들면 효율적이고 좋다고 할 수 있다.


그러나 실제로 이렇게 개발하지는 않는다.

왜냐하면... 굳이 설명할 필요가 있을 지는 모르겠는데 당연히 웹의 구조가 커지면서

저거를 한개씩으로 개발하는 경우는 크게 없다.


현실

html - 여래개의 template(pug,ejs 등)혹은 컴포넌트(vue)들로 html을 구성한다. 그리고 컴파일 반드시 필요하다.

css - sass, scss, less, stylus등으로 마크업한하고 서로 의존해서 구성한다. 그리고 컴파일 반드시 필요하다.

js - 여래개의 js파일로 원래 분리하지만 이를 html에서 여러번 불러 오거나 아니면 여러 js를 컴파일해서 합치거나 typescript,coffeescript등으로 번역한다.

resource - 여러개가 여러파일에 의존되서 처리하기 복잡하다.


쉽게 말해서 여러가지의 파일을 적절하게 묶어주는게 바로 모듈 번들러의 역활이다.

실제로는 한개의 html을 분리해서 작업한다면 반드시 묶어줘야한다. 이는 선택이 아닌 필수이다.

그리고 css를 여러개 사용한다고해서 나눠서 로딩하는것 보단 묶어서 한개로 로딩하는게 여러면에서 좋을 것이다.

js역시 하나로 올리는것보다 묶어서 올리는게 좋다.

이 작업을 해주는 것이 바로 웹팩이라고 생각하면된다.

이 작업에 대해서 browserify에서도 같은 설명을 해뒀으니

좀더 자세한설명을 듣고싶다면 이포스팅에서의 모듈번들러와 모듈로더의 설명을 보자.


웹팩은 이러한 특성상 웹에서는 자주쓰이지만 nodejs에서는 필자 생각에는 gulp가 좀더 쓰기 좋은것 같다.

이름도 webpack인건 그러한 이유 때문이라고 생각한다.


설명은 길게 했으니 이제 본격적으로 기본프로젝트를 만들어 보도록하자.


webpack 프로젝트 만들기, 일반 js합치기


먼저 프로젝트 구조를 잡자.

여러분이 만들고 싶은대로 만들면된다.



필자의 프로젝트 구조이다.



프로젝트를 잘보면 사실 index.html은 현재 존재하지도 않는 dist/bundle.js를 포함하고 있다.

여러분이 똑똑하다면 왜 이렇게 만들었는지 이해할 수 있을 것이다.

그 이유는 바로 dist/bundle.js가 바로 우리가 만들 javascript파일이기 때문이다.


이는 추후의 목표이고 일단 webpack셋팅을 해보자.




npm install -g webpack

npm install -g webpack-cli


일단 당연히 전역으로 webpack을 설치해준다.

이제부터 webpack을 명령어로 사용할 수 있게 된다.


그다음은 webpack.config.js를 만든다.

이는 webpack이 자동으로 webpack프로젝트라고 인식하게 해준다.


var path = require('path');

module.exports = {
entry: {
main: ['./src/main.js'],
},
output: {
filename: 'bundle.js',
path: path.join(__dirname,'./dist')
}
};

가장 기본적인 구조가 될 것이다.

이 구조를 크게 벗어나지 않는다.

설명을 해드리도록 하겠다.


entry - 진입점을 의미한다. 쉽게 이야기해서 저녀석에 연관된 모든 녀석을 하나로 묶어주겠다는 의미이다.

output - 결과가 나올 파일을 의미한다. 


좀더 설명하자면 entry포인트에 main이라고 적혀있는데 이 엔트리 포인트의 이름을 main으로 지정하겠다는 의미이다.


entry: {
'./src/main.js',
},

사실 엔트리 포인트가 단 하나라면 위처럼도 작성이 가능하다.

하지만 추천하는 방식도 아니고 앞으로 쓸일도 없으므로 이런것도 있구나 하고 알아두는게 좋다.


output의 경우 각각의 entry포인트에 대입해서 만들게된다.

위의 예제의 경우 엔트리포인트게 하나이므로 output도 한개가 된다.

그 결과는 당연히 dist폴더의 하위에 위치하게 된다.

이제 빌드 해봅시다.



webpack


명령어를 치면 이제 번들링이된다.



번들링된 코드를 보면 어느정도 minify(코드 공백 다없애서 최소화시킨다.)가 된걸확인할 수 있다.

이제 html을 실행해보자.


index.html은 이제 bundle.js가 존재하게 되므로 위의 파일이 제대로 동작하게 되는걸 확인할 수 있다.


만약 entry포인트가 두개 이상이라면 위처럼 쓸 수 없다.

왜냐하면 output이 단 한개이기 때문이다. 그래서 output파일이 멀티로 출력되게 대응하게 만들어야한다.


var path = require('path');

module.exports = {
entry: {
main: ['./src/main.js'],
},
output: {
filename: '[name].bundle.js',
path: path.join(__dirname,'./dist')
},
};

[name]이라고 붙으면 여기는 자동으로 entry와 대응된다.

즉 위의 번들링은 main.bunde.js가 생기게 된다.

엔트리포인트가 여러개라 하더라도 다 만들 수 있다.

+ Recent posts