현재까지 학습 내용
| 주제 | 설명 |
|---|---|
| 패키지 관리자 | npm, pnpm, yarn 등의 패키지 관리자 |
| 모듈 시스템 | CommonJS, ESM 등 모듈 시스템의 개념 이해 |
| 트랜스파일링 | 최신 문법을 구버전으로 변환 |
| 폴리필 | 구형 환경에서 최신 기능 지원 |
| 번들링 도구 | Webpack, Rollup, esbuild 등 |
이론적 기반을 바탕으로 직접 JS 패키지 만들기
패키지 개발은 다음과 같은 단계로 진행된다.
- 문제 정의 - 해결하고자 하는 문제를 명확히 정의하고 목표 설정
- 프로젝트 구조 설계 - 확장성과 유지보수성을 고려한 디렉토리 구조 설계
- 개발 환경 구성 - 생산적인 개발을 위한 도구 및 환경 준비
- 코드 작성 및 테스트 - 철저한 테스트를 통해 신뢰성 보장
- 문서화 - 협업자와 사용자가 이해할 수 있도록 문서 작성
패키지 개발을 위한 체크리스트
1. 아이디어 검증 및 기술적 타당성 검토
- 어떤 기능을 제공할 것인가?
- 해당 기능이 실제로 구현 가능한가?
- 기존 솔루션과 어떤 차별점을 제공하는가?
2. 라이선스 선택
| 라이선스 | 특징 |
|---|---|
| MIT | 가장 자유로운 라이선스, 상업적 사용 가능 |
| Apache 2.0 | 특허권 명시, 기업 친화적 |
| GPL | 파생 작업물도 오픈소스로 공개 필요 |
| ISC | MIT와 유사, npm 기본 라이선스 |
3. 적절한 이름 고르기
- npm에서 이미 사용 중인지 확인 (
npm search <name>) - 기억하기 쉽고 패키지의 목적을 반영하는 이름 선택
- 스코프 패키지 고려 (
@username/package-name)
4. 지원 환경
모든 환경에서 동작할 필요는 없다. 타겟 환경을 명확히 정의하자.
- Node.js only: 서버 사이드 전용
- Browser only: 클라이언트 사이드 전용
- Universal: 양쪽 모두 지원
5. 개발 환경 및 프로젝트 구조
- 코드 작성, 빌드, 번들링에 사용할 도구 선택
- 어떤 기술 스택을 사용할 것인가?
- 중요: 선택한 도구들이 서로 호환 가능한지 반드시 검토!
6. 의존성 관리 계획
| 유형 | 용도 | 예시 |
|---|---|---|
dependencies | 런타임에 필요한 패키지 | lodash, axios |
devDependencies | 개발/빌드 시에만 필요 | typescript, jest |
peerDependencies | 호스트 프로젝트가 제공해야 함 | react, vue |
7. CI/CD 설정
- 자동화된 테스트, 린팅, 타입 체크가 포함된 CI 파이프라인 구성
- 배포를 수시로 안정적으로 진행할 수 있는 시스템 마련
- GitHub Actions, CircleCI, Travis CI 등 활용
배럴 파일 (Barrel File)
정의
배럴 파일은 여러 모듈을 하나의 파일로 묶어서 다시 내보내는 파일이다. 모듈이 많은 대규모 프로젝트나 패키지에서 특정 모듈을 가져오는 것을 용이하게 할 목적으로 만들어졌다.
// src/index.js (배럴 파일)
export { Button } from './components/Button';
export { Input } from './components/Input';
export { Modal } from './components/Modal';
export { useForm } from './hooks/useForm';장점과 단점
| 구분 | 내용 |
|---|---|
| 장점 | 어디서 만들어졌는지 몰라도 최초 진입점에서 깔끔하게 import 가능 |
| 장점 | API 표면을 명확하게 정의할 수 있음 |
| 단점 | 변수명 충돌 발생 시 파일 자체 사용 불가 |
| 단점 | 모듈의 출처 파악이 어려움 |
| 단점 | Tree-shaking이 제대로 작동하지 않을 수 있음 |
Changesets를 활용한 배포
Changesets는 모노레포 및 일반 프로젝트에서 버전 관리와 변경 로그 생성을 자동화하는 도구이다.
설정 단계
1. changeset-bot 설치
GitHub Marketplace에서 changeset-bot을 설치하여 PR에 changeset 추가 여부를 자동으로 체크한다.
2. npm 토큰 발급
npm 계정에서 Automation 타입의 토큰을 발급받는다.
3. npm 토큰을 저장소에 저장
Settings → Secrets and variables → Actions → New repository secret
NPM_TOKEN이라는 이름으로 토큰을 저장한다.
4. 저장소에 changesets 설정
# @changesets/cli 설치
pnpm add -D @changesets/cli
# 초기화
pnpm changeset init5. GitHub Actions 권한 설정
Settings → Actions → General → Workflow permissions
Read and write permissions로 설정한다.
Changeset 작성 시 입력 내용
PR에서 "Click here if you're a maintainer who wants to add another changeset to this PR"을 클릭하면 마크다운 파일을 작성할 수 있다.
| 항목 | 설명 |
|---|---|
| 버전업 유형 | patch (기본값), minor (기능 추가), major (Breaking Change) |
| 변경 내용 | CHANGELOG.md에 추가될 내용이므로 자세하게 작성 |
CLI를 만드는 데 유용한 패키지
인자/명령어 파싱
commander.js
가장 널리 사용되는 CLI 프레임워크. 명령어, 옵션, 인자를 쉽게 정의할 수 있다.
import { program } from 'commander';
program
.name('my-cli')
.version('1.0.0')
.description('My awesome CLI tool');
program
.command('init <name>')
.description('Initialize a new project')
.option('-t, --template <type>', 'Template type', 'default')
.action((name, options) => {
console.log(`Creating project: ${name} with template: ${options.template}`);
});
program.parse();meow
Sindre Sorhus가 만든 경량 CLI 헬퍼. 간단한 CLI를 빠르게 만들 때 유용하다.
import meow from 'meow';
const cli = meow(`
Usage
$ my-cli <input>
Options
--rainbow, -r Include a rainbow
Examples
$ my-cli unicorns --rainbow
`, {
importMeta: import.meta,
flags: {
rainbow: {
type: 'boolean',
shortFlag: 'r'
}
}
});
console.log(cli.input); // ['unicorns']
console.log(cli.flags); // { rainbow: true }대화형 프롬프트
Inquirer.js
사용자와 대화형으로 입력을 받을 수 있는 라이브러리. 다양한 질문 유형을 지원한다.
import inquirer from 'inquirer';
const answers = await inquirer.prompt([
{
type: 'input',
name: 'projectName',
message: 'What is your project name?',
default: 'my-project'
},
{
type: 'list',
name: 'language',
message: 'Which language do you want to use?',
choices: ['JavaScript', 'TypeScript']
},
{
type: 'confirm',
name: 'useEslint',
message: 'Do you want to use ESLint?',
default: true
}
]);
console.log(answers);
// { projectName: 'my-app', language: 'TypeScript', useEslint: true }터미널 스타일링
chalk
터미널 출력에 색상과 스타일을 적용하는 라이브러리.
import chalk from 'chalk';
console.log(chalk.blue('Info: ') + 'Processing files...');
console.log(chalk.green('Success: ') + 'Build completed!');
console.log(chalk.red('Error: ') + 'Something went wrong');
console.log(chalk.yellow.bold('Warning: ') + 'Deprecated API used');
// 중첩 스타일
console.log(chalk.blue.bgWhite.bold(' INFO ') + ' Starting server...');ora
우아한 터미널 스피너(로딩 표시)를 제공하는 라이브러리.
import ora from 'ora';
const spinner = ora('Loading dependencies...').start();
// 작업 수행
await installDependencies();
spinner.succeed('Dependencies installed');
// 또는
spinner.fail('Failed to install dependencies');
// 또는
spinner.warn('Some dependencies have vulnerabilities');패키지 비교 요약
| 패키지 | 용도 | 특징 |
|---|---|---|
| commander.js | 명령어 파싱 | 기능이 풍부, 서브커맨드 지원 |
| meow | 명령어 파싱 | 경량, 간단한 CLI에 적합 |
| Inquirer.js | 대화형 프롬프트 | 다양한 입력 유형 지원 |
| chalk | 텍스트 스타일링 | 색상, 굵기 등 터미널 꾸미기 |
| ora | 로딩 스피너 | 비동기 작업 진행 표시 |
추가로 유용한 CLI 패키지
| 패키지 | 용도 |
|---|---|
| yargs | commander.js 대안, 강력한 인자 파싱 |
| prompts | Inquirer.js 대안, 더 가볍고 현대적 |
| boxen | 터미널에 박스 UI 생성 |
| cli-table3 | 터미널에 표 출력 |
| figures | 터미널 유니코드 심볼 (체크마크, X 등) |
| listr2 | 멀티 태스크 진행률 표시 |
| update-notifier | CLI 업데이트 알림 |