프론트 개발시 항상 CRA를 통해서 자동으로 개발 환경을 셋팅 했었다
이번에는 백엔드 토이 프로젝트 진행을 위해서 직접 개발 환경을 셋팅을 했었는데 환경 셋팅만 하루 가까이 걸린거같다...
환경 셋팅을 하며 만났던 webpack이 무엇인지 개념을 정리하고자 한다
webpack 이란?

webpack은 모던 JavaScript 정적 모듈 번들러이다
모듈 번들러란?
웹 애플리케이션을 구성하는 자원(HTML, CSS, Javscript, Images 등)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구를 의미한다.
간단하게 정리하면 프로젝트에 필요한 모듈들을 하나 이상의 파일로 압축하는 것이다
webpack의 탄생 배경
과거의 모듈
import / export 구문이 없었던 시절에는 <script> 태그로 외부 스크립트 파일을 불러왔다
이때 add.js와 output.js 파일은 각자의 독립적인 스코프를 갖지 않고 하나의 전역 객체를 공유한다

//add.js
function printText(text) {
console.log(text);
}
//output.js
printText('add.js 파일에 접근 가능');
add.js에 함수를 정의하고 output.js에서 함수 호출이 가능하다

이러한 방식으로 외부 스크립트를 불러오게되면 다른 파일에 중복된 변수명이나 함수명이 존재할 경우
충돌이 발생해 모듈화하기 어렵다
//output.js
var printText = 'output.js에서 재정의됨';
console.log(printText); // Uncaught SyntaxError: Identifier 'printText' has already been declared
IIFE(Immediately Invoked Function Expression)
그래서 과거에 즉시 실행 함수 표현(IIFE)을 사용하여 스코프 문제는 해결하였다
const result = (function () {
var name = 'jun';
return name;
})();
result; // "jun"
함수 내부에서 정의된 값은 외부에서 접근할 수 없으므로 선언한 함수를 즉시 실행하여 스코프 문제는 해결하였지만
모듈화 관점에서는 해결해야하는 문제가 아직 남아있었다
CommonJS와 AMD
자바스크립트를 브라우저뿐만 아니라 서버사이드 애플리케이션, 데스크탑 애플리케이션을 지원하도록 CommonJS가 등장하게 된다
exports 키워드로 모듈화를 하고 require() 함수로 불러오는 방식이다
CommonJS가 나오고 부터 모듈들이 독립적인 영역을 갖게되었고 의존성 관리도 편해졌다
하지만 CommonJS는 동기적으로 모듈을 불러온다 각각 모듈들을 하나씩 불러오고
모듈이 필요하지 않은 시점에도 미리 모듈을 불러온 상태여야한다
즉 필요한 모듈들을 다 다운로드 받기 전에는 아무것도 할 수 없는게 단점이다
AMD(Asynchronous Module Definition)는 파일들을 비동기적으로 불러오는 방식이다
CommonJS에서 분리되서 나온 그룹이기 때문에 exports와 require를 그대로 사용할 수 있다
필요한 파일들이 로컬에 저장되어 있어 바로 불러올 수 있는 서버사이드 환경에서는 CommonJS가 장점이 많고
필요한 파일들을 네트워크에서 다운 받아야 하는 브라우저 환경에서는 AMD가 장점이 더 많다
AMD 사용방법
https://requirejs.org/docs/download.html
Download RequireJS
All you need to start using require.js in the browser. The r.js file allows you to run the optimizer as well as run modules in Node, Rhino, Nashorn or xpcshell. If you are running in Node, and want to use npm to install this file via npm, see the Use with
requirejs.org
<title>Document</title>
<!-- requireJS 라이브러리 다운 -->
<script
type="text/javascript"
src="https://requirejs.org/docs/release/2.3.6/minified/require.js"
></script>
</head>
<body>
<script src="./define.js"></script>
<script src="./import.js"></script>
</body>
//define.js
define('moduleA', [ /*'dependency1', 'dependency2*/], function () {
return {
add: (a, b) => {
return a + b;
},
printText: text => {
console.log(text);
},
};
});
//import.js
require(['moduleA'], (module) => {
module.printText('AMD 방식으로 불러옴');
});

ESM 모듈(EcamScript modules)
ESM는 자바스크립트 공식 표준 모듈이다 export로 모듈을 만들고 import로 불러온다
하지만 ESM의 단점은 import하는 모든 파일을 네트워크 통신을 통해 불러온다

//main.js
import { printText } from './add.js';
import { a } from './test.js';
printText('ESM 방식');

css나 이미지 파일도 네트워크 통신으로 불러와야 했다
그래서 여러 모듈들을 한곳에 압축해서 모아주는 모듈 번들러인 webpack이 등장하게 되었다
webpack의 장점
- 코드 축소와 사용하지 않는 코드를 제거하는 tree shaking과 같은 최적화를 수행 함으로써 HTTP 요청 수를 감소하여 웹사이트 성능을 궁극적으로 향상시키고, 로딩 속도를 빠르게 향상 시켜준다.
- html, css, image, script 등 각각의 모든 파일을 하나의 파일들로 압축하여 웹 애플리케이션을 구성하게 해준다
- 다양한 플러그인을 통해 빌드 프로세스를 확장할 수 있는 플러그인 시스템이 있다
설치
npm i -D webpack webpack-cli
webpack 버전 4.0.0 이후로는 프로젝트를 번들링 하기 위한 설정 파일을 필요로 하지 않는다
하지만 사용자 요구에 따라 유연하게 설정 가능하다
webpack.config.js 설정
//webpack.config.js
import path from 'path'; //ESM 버전
const __dirname = path.resolve();
export default {
mode: 'development', // or 'production'
target: 'node', //번들링된 코드가 실행될 환경
entry: './src/index.ts', //최초 진입점(시작점 경로를 지정)
output: {
path: path.resolve(__dirname, 'dist'), //번들링 결과물이 위치할 경로
filename: 'build.js', //번들링된 파일 이름
},
module: {
rules: [ //번들링할 규칙 설정
{
test: /\.ts$/, //.ts로 끝나는 모든 파일
use: 'babel-loader', //번들링시 바벨로더를 사용하여 트랜스파일
},
],
},
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })] //플러그인 사용
};
등등 더 다양한 옵션들이 있다
번들링 명령어
npx webpack 또는 webpack
'이것저것' 카테고리의 다른 글
| AI 응답 속도 개선하기 (2) | 2024.08.21 |
|---|---|
| 동적 객체 생성 vs 정적 객체 생성 (0) | 2024.04.30 |
| 다마고치 응가 기능 어떻게 구현하지 (0) | 2024.04.24 |
| 쿠키, 세션, 토큰 (0) | 2024.03.28 |
| tsc, babel 차이점 (0) | 2024.03.19 |