Homebrew Formula를 직접 만들어서 Node.js CLI 도구를 관리하면 npm이나 yarn과는 다른 방식으로 패키지를 제어할 수 있어요. 특히 시스템 전역 설치가 필요한 CLI 도구를 깔끔하게 관리하고 싶을 때 유용해요.
기본 Node.js 설치와 nvm 설치 중 선택하기
macOS에서 Homebrew로 Node.js를 설치하는 방법은 크게 두 가지예요. 단일 버전만 필요하면 직접 설치하고, 여러 버전을 관리해야 하면 nvm을 사용해요.
# 방법 1: Node.js 직접 설치
brew install node
# 설치 확인
node -v # v20.11.0 같은 버전 출력
npm -v # 10.2.4 같은 버전 출력
프로젝트마다 다른 Node.js 버전이 필요하다면 nvm이 더 적합해요. 설치 과정이 조금 복잡하지만 버전 전환이 자유로워요.
# 방법 2: nvm 설치 및 설정
brew install nvm
mkdir ~/.nvm
# ~/.zshrc 파일에 추가
echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrc
echo '[ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"' >> ~/.zshrc
# 쉘 재시작 후 Node.js 설치
source ~/.zshrc
nvm install --lts # 최신 LTS 버전 설치
nvm use --lts # 설치한 버전 사용
커스텀 Formula 작성의 핵심 구조
Node.js CLI 패키지를 Homebrew Formula로 만들 때는 Ruby 클래스를 작성해요. npm 레지스트리의 tarball URL을 직접 참조하는 방식이 가장 안정적이에요.
class MyNodeCli < Formula
desc "나만의 Node.js CLI 도구" # 패키지 설명
homepage "https://github.com/username/my-cli"
url "https://registry.npmjs.org/my-cli/-/my-cli-1.0.0.tgz"
sha256 "abc123..." # shasum 명령으로 계산한 해시값
depends_on "node" # Node.js 의존성 명시
def install
# npm 패키지를 libexec에 설치 (전역 오염 방지)
system "npm", "install", *std_npm_args
# 실행 파일을 bin 디렉토리에 심볼릭 링크
bin.install_symlink Dir["#{libexec}/bin/*"]
end
test do
# 버전 확인으로 설치 검증
assert_match version.to_s, shell_output("#{bin}/my-cli --version")
end
end
std_npm_args 헬퍼 메서드가 자동으로 적절한 npm 설치 옵션을 설정해줘요. 이 방식으로 전역 node_modules를 건드리지 않고 독립적인 환경을 구성할 수 있어요.
실제 Formula 작성 시 겪는 기술적 문제들
공식 문서대로 따라 해도 실제로는 여러 문제가 발생해요. 가장 흔한 문제와 해결 방법을 정리해봤어요.
# 문제 1: 심볼릭 링크 충돌 해결
def install
system "npm", "install", *std_npm_args
# 기존 방식 (충돌 가능성 있음)
# bin.install_symlink Dir["#{libexec}/bin/*"]
# 개선된 방식: 환경 변수 스크립트 사용
(bin/"my-cli").write_env_script "#{libexec}/bin/my-cli",
:NODE_PATH => "#{libexec}/lib/node_modules"
end
네이티브 애드온이 포함된 패키지는 빌드 의존성 추가가 필요해요.
# 문제 2: 네이티브 빌드 의존성 처리
depends_on "node"
depends_on "python@3.11" => :build # node-gyp용 Python
def install
# node-gyp rebuild 포함된 패키지 설치
system "npm", "install", "--build-from-source", *std_npm_args
bin.install_symlink Dir["#{libexec}/bin/*"]
end
SHA256 해시값 자동 계산과 버전 관리
Formula를 업데이트할 때마다 해시값을 수동으로 계산하는 건 번거로워요. 자동화 스크립트를 만들어두면 편해요.
#!/bin/bash
# update_formula.sh - Formula 자동 업데이트 스크립트
PACKAGE_NAME="my-cli"
VERSION="1.0.1"
# npm 레지스트리에서 tarball 다운로드
curl -L "https://registry.npmjs.org/${PACKAGE_NAME}/-/${PACKAGE_NAME}-${VERSION}.tgz" \
-o "/tmp/${PACKAGE_NAME}.tgz"
# SHA256 계산
SHA256=$(shasum -a 256 "/tmp/${PACKAGE_NAME}.tgz" | cut -d' ' -f1)
echo "url: https://registry.npmjs.org/${PACKAGE_NAME}/-/${PACKAGE_NAME}-${VERSION}.tgz"
echo "sha256: ${SHA256}"
# Formula 파일 자동 업데이트 (sed 사용)
sed -i '' "s/url .*/url \"https:\/\/registry.npmjs.org\/${PACKAGE_NAME}\/-\/${PACKAGE_NAME}-${VERSION}.tgz\"/" Formula/${PACKAGE_NAME}.rb
sed -i '' "s/sha256 .*/sha256 \"${SHA256}\"/" Formula/${PACKAGE_NAME}.rb
플랫폼별 호환성 처리 방법
macOS와 Linux에서 모두 동작하는 Formula를 만들려면 OS별 조건 처리가 필요해요.
class CrossPlatformCli < Formula
desc "크로스 플랫폼 Node.js CLI"
homepage "https://example.com"
url "https://registry.npmjs.org/cross-cli/-/cross-cli-1.0.0.tgz"
sha256 "xyz789..."
depends_on "node"
def install
system "npm", "install", *std_npm_args
# OS별 경로 처리
if OS.mac?
# macOS 전용 설정
bin.install_symlink Dir["#{libexec}/bin/*"]
# macOS의 경우 추가 권한 설정
chmod 0755, Dir["#{libexec}/bin/*"]
else
# Linux 전용 설정
bin.install_symlink Dir["#{libexec}/bin/*"]
# Linux에서는 다른 경로 사용
(share/"man/man1").install Dir["#{libexec}/share/man/man1/*"]
end
end
end
Formula 검증과 배포 전 체크리스트
작성한 Formula가 Homebrew 정책에 맞는지 확인하는 과정이 중요해요. brew 명령어로 자동 검사할 수 있어요.
# Formula 스타일 검사
brew style --fix Formula/my-cli.rb
# Formula 정책 준수 검사
brew audit --strict Formula/my-cli.rb
# 실제 설치 테스트
brew install --build-from-source Formula/my-cli.rb
# 설치된 패키지 동작 확인
brew test my-cli
로컬 Formula 저장소 관리하기
공식 homebrew-core에 등록하지 않고도 개인 저장소로 Formula를 관리할 수 있어요. 이게 진짜 DIY 패키지 매니저의 시작이에요.
# 개인 Formula 저장소 생성
mkdir -p ~/homebrew-formulae
cd ~/homebrew-formulae
git init
# Formula 파일 추가
cp my-cli.rb Formula/
# Homebrew에 탭으로 등록
brew tap-new username/tools
brew tap username/tools ~/homebrew-formulae
# 이제 설치 가능
brew install username/tools/my-cli
자체 Formula 저장소를 GitHub에 올려두면 팀원들과 쉽게 공유할 수 있어요. brew tap username/repo 명령 하나로 모든 커스텀 Formula를 사용할 수 있게 돼요.
전역 npm 설치의 문제점을 해결하면서도 버전 관리와 의존성 격리가 가능한 DIY 패키지 매니저는 특히 여러 프로젝트를 동시에 진행하는 개발 환경에서 큰 도움이 돼요. 초기 설정이 번거롭긴 하지만 한번 구축해두면 npm과 Homebrew의 장점을 모두 활용할 수 있어요.