라이브러리가 어떻게 만들어지는지 궁금해져서 간단한 실습으로 npm 라이브러리를 만들어보기로 했다. (with gpt)
라이브러리를 만들 폴더를 생성하고 npm을 초기화한다.
mkdir react-fadein
cd react-fadein
npm init // package.json 생성
참고) package.json에는 아래와 같은 메타 정보가 들어간다.
- 프로젝트 이름
- 버전
- 설명
- 진입 파일 (main)
- 스크립트 (scripts)
- 의존성 목록 (dependencies, devDependencies)
npm init을 입력하면 위의 메타 정보들에 대한 질문이 나오는데, 기본값으로 설정하고 빠르게 스킵하고 싶으면 아래 명령어를 대신 사용하면 된다.
npm init -y
아래와 같이 간단한 구조를 만들어주고 index.js에 코드를 작성해준다.
react-fadein/
├─ src/
│ └─ index.js
├─ package.json
└─ README.md
src/index.js
간단하게 화면에 보이는 요소를 페이드인 해주는 컴포넌트를 만들었다.
import React, { useRef, useState, useEffect } from "react";
export const FadeIn = ({ children, duration = 500, delay = 0 }) => {
const ref = useRef();
const [visible, setVisible] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setVisible(true);
observer.disconnect();
}
},
{ threshold: 0.1 }
);
if (ref.current) {
observer.observe(ref.current);
}
return () => observer.disconnect();
}, []);
const style = {
opacity: visible ? 1 : 0,
transform: visible ? "translateY(0)" : "translateY(20px)",
transition: `opacity ${duration}ms ease-out ${delay}ms, transform ${duration}ms ease-out ${delay}ms`
};
return (
<div ref={ref} style={style}>
{children}
</div>
);
};
아래와 같이 package.json을 설정한다.
{
"name": "react-fadein-doozuu",
"version": "0.1.0",
"main": "src/index.js",
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"keywords": ["react", "fadein", "animation", "hook", "component"],
"author": "Doozuu",
"license": "MIT"
}
참고
- name : npm에 배포할 때 쓰이는 고유 이름, 소문자만 사용해야 한다.
- version : 초기 단계는 0.1.0을 사용하고 재배포를 할 때는 반드시 버전을 올려야 한다.
npm version patch # 0.1.0 → 0.1.1 npm version minor # 0.1.0 → 0.2.0 npm version major # 0.1.0 → 1.0.0
- main : 패키지의 진입 파일이다.
- peerDependencies : 라이브러리가 필요로 하는 외부 라이브러리 버전 조건을 명시한다.
- keywords : npm 검색에서 쓰이는 키워드로 자유롭게 설정해주면 된다.
- author : 패키지 작성자 정보이다.
- license : 이용 허가 조건이다. MIT는 무료 사용, 상업적 사용, 수정/배포 모두 가능하다는 뜻이다.
배포 전에 Babel을 이용해 JSX를 JS로 빌드해준다.
JSX는 브라우저나 Node가 바로 이해하는 표준 자바스크립트가 아니기 때문에 배포 전에 트랜스파일이 필요하다.
바벨 설치
npm install --save-dev @babel/cli @babel/preset-env @babel/preset-react
루트 경로에 .babelrc 파일을 만들고 아래와 같이 설정한다.
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
package.json에 빌드 스크립트를 추가해주고 main을 src 대신 빌드된 파일이 있는 lib로 변경해준다.
"main": "lib/index.js",
"scripts": {
"build": "babel src --out-dir lib"
}
최종적으로 아래와 같은 형태가 된다.
{
"name": "react-fadein-doozuu",
"version": "1.0.1",
"main": "lib/index.js",
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"scripts": {
"build": "babel src --out-dir lib"
},
"keywords": [
"react",
"fadein",
"animation",
"hook",
"component"
],
"author": "Doozuu",
"license": "MIT",
"devDependencies": {
"@babel/cli": "^7.28.3",
"@babel/preset-env": "^7.28.5",
"@babel/preset-react": "^7.28.5"
}
}
아래 명령어를 이용해 빌드를 진행해준다.
npm run build
터미널에 아래 명령어를 입력해서 npm에 로그인한다. (계정 없으면 만들기)
npm login
이제 배포를 진행하면 끝!
npm publish
이제 라이브러리를 사용하고자 하는 프로젝트에서 설치해 사용하면 된다.
npm install react-fadein-doozuu
사용 예시
import "./App.css";
import { FadeIn } from "react-fadein-doozuu";
function App() {
return (
<div className="App">
<FadeIn>
<h1>text text</h1>
</FadeIn>
</div>
);
}
export default App;
빌드를 안 한 상태로 배포를 진행했더니 오류가 발생했다.
Failed to compile. SyntaxError: /Users/doozuu/test/node_modules/react-fadein-doozuu/src/index.js: Support for the experimental syntax 'jsx' isn't currently enabled (32:5):
JSX 문법이 트랜스파일되지 않아서 JSX를 JS로 변환해주어야 한다. 이를 위해서는 위에 한 것처럼 Babel을 이용해 라이브러리를 빌드 후 배포해주어야 한다.
만약 잘못해서 재배포를 할 때는 다시 npm에 로그인 하고 버전을 업데이트해서 배포해준다.
npm login
npm version patch
npm publish
라이브러리를 만드는 과정이 복잡할 것 같아서 언젠가 만들어봐야지 생각만 하고 미루고 있었는데 생각보다 간단했다. 이제 방법을 알았으니 앞으로 더 적극적으로 라이브러리를 만들어봐야지!