Webpack은 JavaScript 애플리케이션을 위한 정적 모듈 번들러이다. - (웹팩 문서 참고)
간단히 말하자면 html에 들어가는 다수의 js 파일들을 하나의 js 파일로 만들어 주는 것을 의미한다.
웹팩은 '모듈(module)'을 위한 '번들러(bundler)' 라고 명시되어있다. 번들러란? JS,CSS, 이미지 등의 파일을 묶어주는 작업을 번들링(Bundling)이라고 하고 작업의 결과물은 '번들(Bundle)'이라고 한다. 웹팩 자체는 묶어주는 역할을 하기 때문에 번들러(Bundler)라고 칭한다. 번들링 과정이 끝나면 기존 스크립트에서 import/export가 사라지기때문에 type="module"이 필요없어진다. 따라서 번들링 과정을 거친 스크립트는 일반 스크립트처럼 취급한다.
SPA 즉, 하나의 HTML 페이지에서 여러 개의 js 파일을 포함하게 되면서 파일을 컴파일 할 때 다수의 js 파일을 불러오는데 시간이 오래 걸리게 된다. 그러한 부분을 해결하기 위해서 하나의 js 파일로 번들링 해주는 것이 필요하다. 생성된 번들 파일은 번들 파일의 용량을 최대한 줄이거나 분할하는 등 최적화되어야 하고 모든 브라우저에서 작동해야 한다.
웹 페이지에서 모듈을 사용하려면 해당 모듈과 모듈에서 사용하는 라이브러리를 로드해야 하는데 선후 관계를 따져 순서대로 로드해야 한다. 모듈의 수가 얼마 되지 않는다면 간단하게 로드할 수 있지만 수가 많아지면 매우 복잡해진다.
또한 이렇게 많은 양의 파일을 로드한다면 네트워크 병목현상이 발생할 수 있다.
하나의 자바스크립트 파일 안에 많은 양을 작성하면 해결할 수 있지만 이럴 경우 가독성도 떨어지고 유지보수도 힘들어진다.
이때, 번들링 된 파일을 로드하면 문제를 해결할 수 있다.
모듈을 번들링 하는 과정 중, 모듈이나 외부 라이브러리의 의존성들을 로드하기 때문에 선후 관계를 따질 필요가 없으며, 여러 파일로 작성된 모듈들을 연관된 특정 단위로 묶어서 하나의 파일로 만들기 때문에 병목현상도 예방할 수 있다.
자바스크립트간의 종속성 문제뿐만 아니라 css 및 이미지와 같은 파일도 번들링해서 하나의 파일로 합쳐줘 네트워크 요청을 최소화해준다. 이것은 다시 말하면 http 요청 횟수를 줄일 수 있음을 의미한다. 빠른 서비스 제공과 더불어 자바스크립트 외의 리소스 포맷의 모듈도 사용할 수 있다. css든 이미지든 사용하려는 곳에 해당 리소스를 import해주기만 하면 웹팩이 알아서 빌드해준다.
웹팩의 자동화 덕분에 코드수정시 다시 빌드하고 새로고침하지 않아도 바로바로 빌드결과를 확인할 수 있다.
또한 모든 웹자원이 모듈형태로 로딩이 가능하고 불필요한 것을 로딩하지 않는다. 즉, 필요할 때 필요한 것만 로딩한다.
웹팩은 프로젝트에 필요한 모든 모듈을 매핑하고 하나 이상의 번들을 생성하는 디펜던시 그래프를 생성한다.
1. node.js 설치 _ 웹팩은 노드 모듈중에 하나이다. 그렇기 때문에 기본적으로 Node.js 가 설치되어있어야한다.
2. react개발을 위한 작업폴더 생성 > npx creact-react-app "폴더명" 또는 개별적으로 만들기
* 개별적으로 파일 만들 경우
pakage.json 파일 생성 > npm init -y
index.html 파일과 index.js 파일 생성
3. npm install react-dom , npm install react-router-dom 설정
4. webpack 설치 및 설정
npm install --save-dev webpack webpack-dev-server webpack-cli html-webpack-plugin
** 각 실행명령 해석
4-1. --save-dev : 배포가 아닌 개발할 때 필요한 패키지이므로 --save-dev 옵션을 준다
4-2. webpack : 웹팩 설치
4-3. webpack-dev-server : 코드를 수정했을 때 다시 빌드하고 새로고침하지 않아도 바로 빌드결과를 확인할 수 있도록 dev-server를 설정
4-4. webpack-cli : 터미널에서 명령어로 실행하기 위해 webpack-cli도 함께 설치. webpack-cli를 사용하면 API로 webpack과 상호 작용할 수 있다.
4-5. html-webpack-plugin : dist의 main.js를 스크립트 파일로 포함하는 HTML문서를 dist 디렉토리 내에 자동으로 생성
webpack.config.js 파일내 template에 원본으로 사용할 HTML 문서 경로를 넣어주면된다. 이 플러그인을 사용하지않고 빌드하면 dist 디렉토리에 html파일이 생성되지 않는다. -> dist 디렉토리 내의 빌드결과물만으로는 렌더할 수 없음을 의미.
5. html 파일로더 및 css 파일로더 , 이미지 파일로더 설치
html 파일로더 - npm install --save-dev html-loader
css 파일로더 - npm install --save-dev css-loader style-loader
이미지 파일로더 - npm install --save-dev file-loader
6. package.json 에서 코드 수정하기
script부분에
"start": "webpack server --mode development" 를
"build": "webpack --progress --mode production"로 build 명령어를 추가
( start명령어를 사용하면 webpack-dev-server가 실행된다는 의미, 편의상 모드는 개발모드로 설정, build는 production모드로 설정 )
** 웹팩 실행시 필요에 따라 --mode 옵션을 줄 수 있다. 'development', 'production', 'none' 세 가지 값을 정할 수 있다. 환경변수에 있는 DefinePlugin을 'development' 또는 'production'으로 바꾸고 웹팩이 각 모드에 맞는 빌트인 최적화를 할 수 있도록 한다. 'none'으로 지정하면 최적화를 허용하지 않는다. 별도로 지정하지 않으면 기본값인 'production' 모드로 실행된다.
webpack.config.js 파일에서 mode: 'development'로 지정해둘 수도 있는데, 개발과 배포 버전을 번갈아가면서 실행하기 위해서는 CLI에서 옵션을 주는 방법이 낫겠다.
7. webpack.config.js 파일 생성 _ 참조블로그(https://365kim.tistory.com/35)
웹팩으로 어디를 번들링해서 패키징을 할지와 관련된 설정을 webpack.config.js 파일을 생성해 저장.
웹팩의 core concepts 은 Entry, Output, Loader, Plugin 이다. (웹팩홈페이지)
1) Entry 설정
엔트리포인트는 웹픽이 번들링을 시작할 메인파일이다.
webpack은 번들링 과정에서 '디펜던시 그래프(dependency graph)'를 그린다.
특정 지점에서 출발해서, 애플리케이션에 필요한 모든 모듈을 포함하는 그래프를 재귀적으로 완성해 나간다. 한 파일이 다른 파일을 필요로 하면 이를 '디펜던시(dependency)'가 있다고 해석하는데, 이 방식으로 웹팩은 이미지 또는 웹 글꼴과 같이 코드가 아닌 리소스도 디펜던시로 관리할 수 있게 된다. 그래프를 모두 그리고 나면 이 모든 모듈을 소수의 번들로 묶어서 (보통 하나의 번들로 묶는다) 브라우저에 로드될 준비를 마친다.
이때 우리는 webpack이 어디를 출발지점으로 해서 그려나가면 좋을지 알려주어야 한다. config파일에서 entry 속성을 설정해서 웹팩이 어떤 모듈로부터 시작해서 디펜던시 그래프를 그려나갈지 명시해줄 수 있다. 'entry' 속성의 기본값은 './src/index.js'이지만 다른 Entry Point를 지정할 수도 있다. (여러 개도 지정 가능)
2) Output 설정
output 은 웹팩이 번들을 꾸리고 나서 결과물을 어디로 내보낼지 지정하는 속성이다. 기본값으로 메인 결과물인 bundle.js 파일은 ./dist/bundle.js에, 그 외 파일은 ./dist 폴더에 내보내 진다. 파일 이름(filename), 경로(path)를 별도로 지정할 수 있고, clean을 true로 설정하면 지정한 결과물이 내보내지는 디렉토리(본 예제에서는 dist)안에 사용하지 않는 파일을 알아서 정리해준다. 이외에도 수많은 커스텀 옵션을 설정할 수 있다.
※
path vs public path _ webpack dev server의 path와 publicPath를 반드시 구분하여 파악해야 함
- publicPath 옵션
다른 도메인이나 CDN에서 일부 또는 모든 출력 파일을 호스팅 하려는 경우 사용할 수 있으며 Webpack Dev Server에서는 출력 파일의 URL 경로로 사용된다.
output.path : 번들링한 결과가 위치할 번들링 파일의 절대 경로
output.publicPath : 브라우저가 참고할 번들링 결과 파일의 url 주소를 지정. (CDN을 사용하는 경우 CDN 호스트 지정)
3) Loader 설정하기
이제까지 자바스크립트 외의 리소스도 번들링할 수 있다고 했지만, 사실 웹팩은 기본적으로 JavaScript와 JSON 파일만 이해할 수 있다. 이 때 필요한 것이 Loader이다. 사용하려는 포맷에 대응하는 Loader를 설정해주면 다른 포맷의 리소스도 디펜던시 그래프에 추가할 수있게 된다.
Loader를 설정하려면 'test'와 'use' 두 가지 필수 속성을 적어주어야 한다. 'test'는 어떤 파일을 변환할지 지정하는 속성으로, 보통 /\.txt$/과 같이 정규표현식으로 작성한다. 이 때, /\.txt$/ 과 같이 따옴표 없이 작성해야한다. '/\.txt$/' 또는 "/\.txt$/"와 같이 따옴표를 넣으면 빌드가 제대로 안될 것이다,,, 'use'는 파일을 변환할 때 어떤 로더를 사용해야하는지 명시하는 속성이다.이는 웹팩 컴파일러에게 다음과 같이 말하는 것과 같다.
웹팩 컴파일러야! 디펜던시 그래프를 그리다가 'test'에 지정된 파일형식을 발견하잖아? 그러면 번들에 넣기 전에 내가 'use'에 지정한 로더로 꼭 변환해줘야해~! |
이렇게 Loader를 설정해주면 포맷에 얽매이지 않은 자유로운 import가 가능하다. 예를 들어 js파일에서 import '../css/index.css';과 같이 해당 모듈에서 필요한 css파일을 import해올 수 있다. 웹팩을 사용하기 전에는 상상할 수 없었던 일이다! 이 기능은 다른 번들러에서는 지원되지 않을 수도 있다고 한다.
주의할 점은 config에 바로 rules 속성을 쓰는게 아니라 반드시 module.rules에 정의해 주어야 한다는 것이다. (틀리면 웹팩이 알아서 경고해주기는 한다.)
** 중요도 순서
entry > module > plugin > output -> 엔트리에서 시작해 모듈 플러그인들을 거쳐 아웃풋으로 나오는 구조
8. Babel 설정하기
바벨은 ES6+ 문법으로 작성된 js파일을 ES5문법으로 트랜스파일링 해준다.
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
8-1. babel-loader : 모듈을 입력받아 원하는 형태로 변환한 후 새로운 모듈을 출력해서 웹팩에 전달
8-2. @babel/core : babel-loader는 babel-core를 이용해서 소스코드를 변환
8-3. @babel/preset-env : 원하는 문법으로 변환
8-4. @babel/preset-react : 리액트 문법을 변환
babel 로더를 추가한 webpack.config.js 파일.
모듈 번들링 관점에서 모듈간의 의존성을 고려하여 로딩을 시도하는데 resolve는 모듈을 어떤 위치에서 어떻게 로딩할지에 관해 정의한다.
.babelrc 파일을 생성하고 바벨 관련 설정을 지정한다.
9. 터미널에서 npm run build
-> dist 디렉토리에 bundle.js 파일과 index.html이 생성된다.
10. npm run start
개발자 도구 console 에서 웹팩이 설치되었음을 알 수 있다.
[Next.js] Next.js 시작하기 (nextJs 설치 / 클라이언트렌더링, 서버렌더링 - use client / page / layout / url설정 / url:key값 설정) (1) | 2025.04.17 |
---|---|
[React] Proxy서버 이용 + 사이드서버(Node.js) 이용하기 (0) | 2024.04.08 |
[React] Webpack 깃허브 배포하기 (0) | 2024.02.22 |
[React] axios 데이터 전송하기 (0) | 2023.08.24 |