TypeScript와 Bun을 활용한 효과적인 CLI 개발 방법
2025-02-06 11:43:22TypeScript와 Bun으로 CLI 만들기
현대 개발 환경에서 CLI(명령줄 인터페이스)는 개발자의 필수 도구로 자리 잡았습니다. 그래픽 사용자 인터페이스(GUI)보다 더 많은 제어와 유연성을 제공하는 CLI는 특히 자동화 작업에서 빛을 발합니다.
이번 포스트에서는 TypeScript와 빠르고 통합적인 JavaScript 런타임인 Bun을 이용하여 CLI를 만들어 보겠습니다. 참고로 이 내용은 YouTube 영상에서도 시청 가능합니다.
CLI 설계 및 파일 업로드 프로그램 만들기
프로젝트 구성 및 초기 설정
먼저, Bun 프로젝트를 생성하고 메아(Meow) 패키지를 설치하여 CLI 플래그 파싱을 시작합니다. 다음과 같이 진행하세요:
mkdir s3upload && cd s3upload
bun init -y
bun add meow
이로써 s3upload라는 Bun 프로젝트가 생성되고, Meow 패키지가 설치되었습니다. Meow는 CLI의 인수와 플래그를 손쉽게 파싱할 수 있도록 도와줍니다.
프로그램 인수 정의하기
프로그램 실행에 필요한 플래그와 옵션을 정의합니다. 파일과 디렉터리를 업로드할 수 있도록 --file 및 --dir 옵션을 추가합니다. AWS S3와 같은 스토리지와 통신하기 위한 인증 정보도 필요합니다:
const cli = meow(`
Usage
$ s3upload <bucket>
Options
--file, -f 업로드할 단일 파일
--dir 업로드할 디렉토리
--region AWS 리전
--endpoint S3 엔드포인트/URL
--access-key-id AWS 액세스 키 ID
--secret-access-key AWS 시크릿 액세스 키
--help 도움말 표시
--version 버전 정보 표시
`, {
importMeta: import.meta,
flags: {
file: {
type: 'string',
shortFlag: 'f',
},
dir: {
type: 'string',
},
region: {
type: 'string',
},
endpoint: {
type: 'string',
},
accessKeyId: {
type: 'string',
},
secretAccessKey: {
type: 'string',
},
}
});
Bun의 S3 클라이언트를 활용한 파일 업로드
이제 Bun의 S3 클라이언트를 이용하여 파일과 디렉터리를 S3에 업로드하는 기능을 구현합니다. 우선 파일 업로드 코드를 작성합니다.
async function upload(bucket: string, flags: typeof cli.flags) {
if (!flags.file && !flags.dir) {
console.error("Either --file or --dir must be specified");
process.exit(1);
}
const client = new S3Client({
bucket: bucket,
region: flags.region,
accessKeyId: flags.accessKeyId,
secretAccessKey: flags.secretAccessKey,
endpoint: flags.endpoint,
});
if (flags.file) {
const key = basename(flags.file);
await client.write(key, Bun.file(flags.file));
console.log(`✓ Uploaded ${key} to ${bucket}`);
return;
}
}
파일 플래그가 지정된 경우, client.write() 메서드를 사용하여 파일을 업로드합니다. S3Client 인스턴스는 사전에 설정된 인증 정보를 활용하여 S3 서비스와 연결됩니다.
재귀적으로 디렉터리 내용 읽어오기 및 업로드
디렉터리의 내용을 읽고 모든 파일을 업로드하는 코드입니다:
async function upload(bucket: string, flags: typeof cli.flags) {
if (flags.dir) {
const directoryContent = await readdir(flags.dir, {
recursive: true,
withFileTypes: true,
});
const files = directoryContent.reduce((acc: string[], dirent) => {
if (dirent.isFile()) {
acc.push(
dirent.parentPath
? dirent.parentPath + "/" + dirent.name
: dirent.name
);
}
return acc;
}, []);
for (const file of files) {
await client.write(file, Bun.file(file));
console.log(`✓ Uploaded ${file} to ${bucket}`);
}
console.log(`Uploaded ${files.length} files to ${bucket}`);
}
}
readdir() 함수는 지정된 디렉터리의 내용을 읽고, 모든 파일을 업로드합니다. 이 과정으로, 지정된 디렉터리의 모든 파일을 효과적으로 S3 버킷에 업로드할 수 있습니다.
결론
이 글에서는 Bun과 TypeScript를 활용하여 S3 컴패터블 스토리지에 파일을 업로드할 수 있는 CLI 프로그램을 제작했습니다. 이러한 CLI는 프로그래머에게 효율적이고 강력한 도구가 될 것입니다.
추가로 도움이 될 만한 다른 리소스를 확인해 보세요: