JavaScript

번들러 Rollup 세팅해보기

citron031 2024. 6. 7. 21:56

Javascript 라이브러리를 만들 때, 번들링을 하면 여러 장점이 있다.

  • Tree Shaking을 하여 불필요한 코드가 최종 결과물에 포함되지 않도록 할 수 있다. (최종 번들 크기를 줄일 수 있)
  • 모듈화된 코드들을 하나의 js 파일로 만들기 때문에, 네트워크 요청 비용을 절감하고 코드의 보안성을 높일 수도 있다.
  • 다양한 플러그인을 사용할 수 있고, 필요한 폴리필을 자동으로 포함시킬 수 있으 transpiling을 간편하게 설정할 수 있다. (다양한 환경에서 코드가 호환되도록 할 수 있다.)
  • HMR(Hot Module Replacement)과 같은 개발환경을 구축하는데도 도움이 된다.
  • 소스 맵(Source Map)을 생성하여 디버깅을 쉽게 할 수 있다. (번들된 코드가 아닌 원본 코드의 위치와 내용을 확인할 수 있다)
  • JS 코드 뿐만이 아니라 플러그인을 추가하여 타입스크립트, CSS, 폰트와 같은 리소스 자바스크립트로 관리할 수 있다.

 

이번에 사용해볼 번들러는 Rollup이다.

Vite가 가장 대중적인 번들러지만, 라이브러리를 만들기 위해서는 Rollup이 좀 더 설정하기 편할 것 같기에 Rollup을 선택했다.

(Vite는 좀 더 브라우저 기반 기능들이 많았다. dev 서버나 HMR 등등...)

Rollup은 CommonJS 및 AMD와 같은 이전의 특이한 솔루션 대신 코드에 표준화된 ES 모듈 형식을 사용한다.

 👻 사실 Vite는 내부적으로 Rollup을 사용한다.

 

사용 예제 🎶

npm i rollup @rollup/plugin-typescript tslib -D

 

rollup을 설치한다.

그리고 typescript를 사용할 것이기에 타입스크립트 플러그인도 설치했다.

 

그리고 rollup.config.ts을 작성해준다.

플러그인 옵션에 설치한 타입스크립트 플러그인을 추가한다.

🥝 minifyInternalExports을 활성화해 번들링 결과물 코드의 길이를 더 짧게 최적화할 수 있다.

import { defineConfig } from 'rollup';
import typescript from '@rollup/plugin-typescript';

export default defineConfig({
  input: 'index.ts',
  output: {
    file: 'dist/index.js',
    format: 'cjs',
    minifyInternalExports: true,
  },
  plugins: [
    typescript({
      declaration: true, // d.ts 파일 생성
      declarationDir: 'dist/types', // 빌드 후 type 파일 위치
      exclude: ['node_modules/**'], // type을 생성하지 않음
    }),
  ],
});

🥔 external을 설정하여 번들링에서 제외할 파일을 선택할 수도 있다.

 

🍇 input을 여러개 추가하고 각각 번들링 결과물을 만들고자 한다면 다음과 같이 설정한다.

import { defineConfig } from 'rollup';
import typescript from '@rollup/plugin-typescript';

export default defineConfig({
  input: {
    index: 'index.ts',
    cli: 'src/cli.ts',
  },
  output: {
    dir: 'dist',
    format: 'cjs',
    minifyInternalExports: true,
  },
  plugins: [typescript()],
});

빌드 결과물은 dist/index.js, dist/cli.js가 된다.

 

그리고 rollup을 사용하기 위해서 tsconfig.json의 module설정을 esnext로 설정해준다.

moduleResolution 설정도 node10으로 해준다. (상대경로, 절대경로로 불러오는 것이 아니면, node_modules에서 불러오도록 한다)

{
  "compilerOptions": {
    "target": "es2016",
    "module": "esnext",
    "moduleResolution": "node",
    "declaration": true,
    "outDir": "dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
  },
  "exclude": ["examples"]
}

 

그리고, 이제 rollup으로 빌드하기 위해서 다음의 명령어를 실행한다.

npx rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript

 

package.json에 script를 작성함으로써, 더 짧은 명령어로 실행할 수 있다.

  "scripts": {
    "build": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
    "build:tsc": "tsc",
    "test": "jest"
  },

 

https://www.npmjs.com/package/colors-helper-tools

 

colors-helper-tools

help use color style ✨. Latest version: 1.5.9, last published: 3 days ago. Start using colors-helper-tools in your project by running `npm i colors-helper-tools`. There are no other projects in the npm registry using colors-helper-tools.

www.npmjs.com

위의 라이브러리는 실제 rollup을 사용하여 빌드하고 배포한 라이브러리인데, tsc로 빌드한 결과물과 rollup을 사용하여 빌드한 결과물의 차이를 확인할 수 있다.

 

tsc로 빌드한 경우, 모든 파일에 대한 빌드 결과물 js가 생성된다.

반면, rollup으로 빌드한 경우는 위와 같이 하나의 파일로 빌드가 된것을 확인할 수 있다.

🙌 rollup.config.js에서 output에 설정한 js파일 하나만이 생성된다.

 

🍎 terser 설정하여 min bundle

// rollup.config.mjs
import json from '@rollup/plugin-json';
import terser from '@rollup/plugin-terser';

export default {
	input: 'src/main.js',
	output: [
		{
			file: 'bundle.js',
			format: 'cjs'
		},
		{
			file: 'bundle.min.js',
			format: 'iife',
			name: 'version',
			plugins: [terser()]
		}
	],
	plugins: [json()]
};

 

 

👻 참고자료

https://www.npmjs.com/package/rollup

 

rollup

Next-generation ES module bundler. Latest version: 4.18.0, last published: 16 days ago. Start using rollup in your project by running `npm i rollup`. There are 7392 other projects in the npm registry using rollup.

www.npmjs.com

https://rollupjs.org/command-line-interface/#configplugin-plugin

 

Command Line Interface | Rollup

 

rollupjs.org

 

 

😊 잘못된 내용이 있다면 댓글을 남겨주세요 ~