Rollup은 Webpack 같은 모듈 번들러입니다.
Rollup은 Webpack과 달리 코드들을 동일한 수준으로 호이스팅 한 후 번들링을 진행하기 때문에 속도가 빠르고 결과물이 가볍다는 장점이 있고 es 모듈 형태로 빌드를 할 수 있어 라이브러리나 패키지를 작업하는데 활용할 수 있습니다.
그렇다면 Rollup이 속도도 빠르고 결과물이 가벼운데 Webpack보다 좋은것이 아니냐라고 생각하실 수 있습니다.
Rollup이 성능면에서는 Webpack보다 좋을 수 있지만 안정성과, 개발서버가 다른 번들러보다 Webpack이 뛰어납니다.
라이브러리 작업에서는 Rollup을 사용하는게 성능면에서 이득을 볼 수 있다고 생각하시면 되겠습니다.
우선 프로젝트를 생성하여 줍니다.
yarn init
그리고 필요한 모듈들을 설치해주겠습니다.
//react
yarn add -D react react-dom
// babel
yarn add -D @babel/core babel-preset-react-app
// styled-components 기반으로 작성할 예정이라 설치하였습니다.
yarn add -D babel-plugin-styled-components
// typescript
yarn add -D typescript
// rollup
yarn add -D rollup rollup-plugin-typescript2 @rollup/plugin-commonjs @rollup/plugin-node-resolve rollup-plugin-peer-deps-external @rollup/plugin-image
이렇게 필요한 모듈들을 모두 다운 받고 우선 package.json을 수정하도록 하겠습니다.
react, react-dom 모듈을 devDependencies에서 peerDependencies로 이동을 시키도록 하겠습니다.
package.json
"peerDependencies": {
"react": 18.2.0,
"react-dom": 18.2.0
}
그리고 package.json 상단에 빌드 된 후 위치할 경로들을 적어줍니다.
{
...
"main": "dist/index.js",
"module": "dist/index.es.js",
"types": "dist/types/index.d.ts"
...
}
그리고 script에 빌드를 해주는 명령어를 선언해주겠습니다.
{
...
"scripts": {
"build": "tsc --emitDeclarationOnly & rollup -c"
},
...
}
그리고 babelrc.json 파일을 최상단 루트경로에 만들어주도록 합니다.
{
"presets": [["react-app", { "flow": false, "typescript": true }]],
"plugins": ["babel-plugin-styled-components"]
}
그리고 tsconfig.json 파일을 최상단 루트 경로에 만들어주도록 하겠습니다.
설정은 원하시는대로 커스텀 하시면 됩니다.
{
"compilerOptions": {
"declaration": true,
"declarationDir": "./lib",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"sourceMap": true,
"rootDir": "packages/src",
"outDir": "./dist",
"strict": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "react",
"baseUrl": "./",
},
"include": ["**/*.tsx", "**/*.ts", "@types", "index.ts"],
"exclude": ["node_modules", "build", "dist", "lib", "example",
"rollup.config.js.js"
]
}
이제 마지막으로 최상단 루트경로에 rollup.config.js 파일을 만들어줍니다.
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import resolve from '@rollup/plugin-node-resolve';
import image from '@rollup/plugin-image';
import babel from '@rollup/plugin-commonjs';
import typescript from 'rollup-plugin-typescript2';
import commonjs from '@rollup/plugin-commonjs';
const packageJson = require('./package.json');
const extensions = ['js', 'jsx', 'ts', 'tsx'];
const external = ['react', 'react-dom', 'styled-components'];
process.env.BABEL_ENV = 'production';
export default {
input: 'package/src/index.ts',
output: [
{
file: packageJson.main,
format: 'cjs',
sourcemap: true
},
{
file: packageJson.module,
format: 'esm',
sourcemap: true
}
],
plugins: [
peerDepsExternal(),
resolve({ extensions }),
babel({
extensions,
include: ['packages/src/**/*'],
exclude: /node_modules/,
babelHelpers: 'runtime'
}),
commonjs({
include: /node_modules/
}),
typescript({ useTsconfigDeclarationDir: true }),
image()
],
external
};
이제 간단한 컴포넌트를 하나 만들어서 번들링을 진행해보도록 하겠습니다.
package/src/Button/Button.tsx
import React, { FC } from 'react';
import ButtonProps from './Button.type
const Button: FC<ButtonProps> = ({ children, type }) => {
return (
<button type={type}>
{children}
</button>
)
}
export default Button
package/src/Button/Button.type.tsx
import React, { PropsWithChildren } from 'react';
export interface ButtonProps extends PropsWithChildren {
type: string
}
package/src/Button/index.tsx
export { default as Button } from './Button/Button';
이제 npm run build를 하면 끝이 납니다!
다음 포스팅에는 npm에 라이브러리를 배포해보도록 하겠습니다~