Set up Bun for Midnight development
Bun은 Node.js와 npm보다 상당히 빠른 성능을 제공하는 최신 JavaScript 런타임입니다. 이 가이드에서는 Midnight Network 개발에 Bun을 사용하는 방법을 다룹니다. 설치, 설정, 호환성 고려사항, 모범 사례를 포함합니다.
Prerequisites
시작하기 전에 다음을 갖추고 있어야 합니다:
- JavaScript/TypeScript 기본 지식
- 커맨드라인 사용 경험
- 패키지 매니저(npm, yarn) 이해
이 튜토리 얼에는 Docker가 필요 없습니다. Docker는 실제 Midnight proof server를 실행할 때만 필요합니다.
완성된 프로젝트 구조는 다음과 같습니다:
Install Bun
개발 머신에 Bun을 설치합니다.
Install Bun on Mac
- 아래 명령을 실행합니다:
curl -fsSL https://bun.sh/install | bash
이 스크립트가 시스템에 맞는 Bun 바이너리를 다운로드하여 ~/.bun/bin에 설치합니다.
- 설치를 확인하세요.
터미널을 닫고 다시 연 후 실행합니다:
bun --version
예상 출력 예시:
bun --version이 "command not found"를 반환하면 수동으로 Bun을 PATH에 추가하세요.
export PATH="$HOME/.bun/bin:$PATH"
Install Bun on linux or WSL
Linux 또는 WSL(Windows Subsystem for Linux)에서의 설치 방법입니다.
- 필수 의존성 설치
Bun 설치에 unzip이 필요합니다.
sudo apt update
sudo apt install unzip -y
- Bun 설치
공식 Bun 설치 스크립트를 실행합니다:
curl -fsSL https://bun.sh/install | bash
- 쉘 구성 재로드
bun 명령을 사용할 수 있도록 환경을 새로고침합니다:
source ~/.bashrc
- 설치 확인
bun --version
설치된 Bun 버전이 출력되면 성공입니다.
- "command not found" 수정 (필요한 경우)
bun을 찾을 수 없는 경우 설치 디렉토리를 PATH에 추가하세요:
export PATH="$HOME/.local/bin:$PATH"
Install using the installer script
Compact 컴파일러를 설치합니다. Bun과 별개의 독립형 도구로, Compact 언어로 작성된 스마트 컨트랙트를 Midnight 블록체인에서 실행 가능한 코드로 변환합니다.
- Compact 설치 프로그램을 사용하여 설치합니다:
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh
기본적으로 $HOME/.local/bin에 설치됩니다.
- 컴파일러 업데이트
이 튜토리얼에서 사용하는 버전으로 업데이트하세요:
compact update
- 설치 확인
Compact가 올바르게 설치되었는지 확인하세요:
compact check
성공하면 다음과 유사한 출력이 표시됩니다:
compact: aarch64-darwin -- Up to date -- 0.29.0
- "command not found" 수정 (PATH 문제)
다음 오류가 표시되면:
compact: command not found
Compact 설치 디렉토리($HOME/.local/bin)가 PATH에 없는 것입니다.
현재 터미널 세션에 추가하세요:
export PATH="$HOME/.local/bin:$PATH"
Install Midnight packages with Bun
Bun과 Compact 컴파일러가 준비되었으니, Midnight 애플리케이션 프로젝트를 생성합니다.
- 새 프로젝트 초기화:
mkdir my-midnight-app
cd my-midnight-app
bun init -y
기본 package.json이 생성됩니다.
- 필수 디렉토리 생성:
스마트 컨트랙트와 애플리케이션 소스 코드를 위한 폴더가 필요합니다.
mkdir src contracts
- Midnight 런타임 패키지 설치
호환성을 위해 특정 버전을 설치하세요:
bun add @midnight-ntwrk/compact-runtime@0.14.0
이 패키지로 다음이 가능합니다:
- 스마트 컨트랙트 실행
- 앱 데이터 관리
- ZK proof 작업
- TypeScript 타입 정의 사용
런타임 패키지 버전은 항상 호환성 매트릭스에서 확인하세요.
tsconfig.json파일 업데이트:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true
},
"include": ["src/**/*"]
}
이 설정으로:
- Bun이 import를 올바르게 해석합니다
- TypeScript가 정상 컴파일됩니다
- Midnight 런타임 패키지가 추가 설정 없이 동작합니다
Configure the project
package.json을 Bun 전용 스크립트로 업데이트하세요:
"scripts": {
"dev": "bun run --hot src/index.ts",
"start": "bun run dist/index.js",
"test": "bun test",
"install:midnight": "bun install",
"compile:contract": "compact compile contracts/message.compact contracts/managed",
"build:contract": "bun run compile:contract && bun build src/index.ts --outdir dist"
},
각 스크립트의 역할:
- dev: 핫 리로드로 개발 모드 실행
- start: 컴파일된 프로덕션 앱 실행
- test: Bun 테스트 러너로 테스트 실행
- install:midnight: Bun으로 프로젝트 의존성 설치
- compile:contract:
message.compact를 contracts/managed로 컴파일 - build:contract: 컨트랙트 컴파일 후 앱 엔트리를 dist 폴더로 번들링
Create smart contract with Compact
Midnight 블록체인에 메시지를 저장하고 읽는 간단한 Compact 스마트 컨트랙트를 만들고, TypeScript/Bun 애플리케이션에서 사용할 수 있도록 컴파일합니다.
- 스마트 컨트랙트 파일을 생성하세요.
contracts 디렉토리에 message.compact 파일을 만드세요:
touch contracts/message.compact
- 다음 코드를 추가하세요:
pragma language_version 0.21;
import CompactStandardLibrary;
// 공개 원장 상태 - 블록체인에서 볼 수 있음
export ledger message: Opaque<"string">;
// 블록체인에 메시지를 저장하는 회로(circuit)
// 메시지는 공개적으로 볼 수 있음
export circuit storeMessage(customMessage: Opaque<"string">): [] {
message = disclose(customMessage);
}
코드 설명:
pragma language_version 0.21;-- Compact 컴파일러 버전을 지정합니다.import CompactStandardLibrary;-- Midnight 컨트랙트용 표준 함수와 타입을 로드합니다.export ledger message: Opaque<"string">;-- 블록체인에message라는 공개 상태 변수를 선언합니다.export circuit storeMessage(...)-- 메시지를 저장하는 circuit입니다.disclose()로 메시지를 공개합니다.
- Compact로 컴파일
compact compile contracts/message.compact contracts/managed
.compact 컨트랙트를 애플리케이션이 사용할 수 있는 컴파일된 모듈로 변환하고, contracts/managed에 저장합니다.
Integrate compiled smart contracts with Bun
Compact 컨트랙트가 컴파일되었으니, Bun 기반 TypeScript 애플리케이션에서 사용해 봅니다.
Midnight 컨트랙트의 메시지 저장/읽기를 시뮬레이션하는 클라이언트를 작성합니다.
src/message-client.ts생성
touch src/message-client.ts
다음 코드를 추가하세요:
import { Contract, ledger } from "../contracts/managed/contract/index.js";
export class MessageClient {
private contract: Contract<any>;
constructor() {
this.contract = new Contract({});
}
async storeMessage(customMessage: string) {
console.log(`📦 (Simulated) Storing message: "${customMessage}"`);
// 실제 구현에는 적절한 Midnight 컨텍스트가 필요
return { success: true, message: customMessage };
}
async getMessage() {
console.log("📥 (Simulated) Fetching message from ledger...");
return "Hello Midnight!";
}
}
MessageClient 클래스에서 컴파일된 Compact 컨트랙트를 로드하고, storeMessage()와 getMessage() 메서드로 데이터 읽기/쓰기를 시뮬레이션합니다. 실제 Midnight 앱의 프로젝트 구조를 유지하면서 단순화한 예시입니다.
src/index.ts생성
애플리케이션 진입점입니다.
touch src/index.ts
다음 코드를 추가하세요:
import { MessageClient } from "./message-client";
async function main() {
console.log("🚀 Starting Midnight Message App...");
const client = new MessageClient();
console.log("📝 Storing message...");
await client.storeMessage("Hello Midnight!");
console.log("📖 Reading message...");
const message = await client.getMessage();
console.log("✅ Message:", message);
}
main().catch(console.error);
Midnight 앱을 부팅하고, MessageClient 인스턴스를 생성하여 메시지 저장 및 읽기를 수행합니다.
- Bun으로 앱 실행:
bun run --hot src/index.ts
Known limitations and workarounds
Bun은 큰 성능 향상을 제공하지만, Midnight 애플리케이션 개발 시 알아야 할 제한사항이 있습니다.
Native module compatibility
네이티브 Node.js 애드온을 사용하는 npm 패키지가 Bun에서 정상 동작하지 않을 수 있습니다.
해결 방법:
# 패키지가 실패하면 Node.js 호환 모드로 실행해 보세요
bun --bun run your-script.ts
# 또는 특정 스크립트에 대해 Node.js로 대체
node your-script.js
Package manager lock files
같은 프로젝트에서 Bun과 npm을 혼용하면 lock 파일 충돌이 발생할 수 있 습니다.
해결 방법:
# 하나를 선택하고 그것만 사용하세요. Bun을 사용하는 경우 npm 파일을 제거
rm package-lock.json
# npm을 사용하는 경우 Bun 파일을 제거
rm bun.lock
프로젝트에서 패키지 매니저는 하나만 선택하고, 팀 전체가 동일하게 사용하세요.
Environment variables
Bun은 .env 파일을 자동으로 로드하므로, 다른 환경 변수 도구와 충돌할 수 있습니다.
해결 방법:
# Bun은 .env를 자동으로 로드합니다. 라이브러리가 필요 없습니다
# 이를 비활성화해야 하는 경우:
bun --env-file= run your-script.ts
# 또는 다른 env 파일을 지정:
bun --env-file=.env.production run your-script.ts
Migration guide (npm → Bun)
기존 Node.js + npm 기반 Midnight 프로젝트를 몇 단계로 Bun으로 마이그레이션할 수 있습니다.
- Bun 설치
시스템에 Bun이 설치되어 있는지 확인하세요.
bun --version
찾을 수 없으면 Install Bun 단계를 진행하세요.
- npm 산출물 제거:
cd your-midnight-project
rm -rf node_modules package-lock.json
복원이 필요할 수 있으니 package-lock.json을 먼저 백업하세요.
- Bun으로 의존성 설치:
bun install
- 마이그레이션 확인
Bun에서 정상 동작하는지 테스트하세요:
bun run dev
Troubleshoot common issues
- 모듈을 찾을 수 없는 오류(Module Not Found Errors)
문제:
bun run --hot src/index.ts
'@midnight-ntwrk/compact-runtime' 모듈을 찾을 수 없음
해결 방법:
bun add @midnight-ntwrk/compact-runtime@0.14.0
- 버전 불일치 오류(Version mismatch errors)
문제:
CompactError: Version mismatch: compiled code expects 0.14.0, runtime is 0.9.0
Compact 컴파일러와 런타임 버전은 정확히 일치해야 합니다. 컴파일 전에 항상 버전 호환성을 확인하세요.
해결 방법:
일치하는 런타임 버전을 설치하세요:
bun add @midnight-ntwrk/compact-runtime@0.14.0
그런 다음 스마트 컨트랙트를 다시 컴파일하세요:
compact compile contracts/message.compact contracts/managed
- Compact 컴파일러 언어 버전 오류
문제:
Exception: message.compact line 1 char 1:
language version 0.21.0 mismatch
해결 방법:
스마트 컨트랙트의 언어 버전을 정확히 지정하세요:
pragma language_version 0.21;
범위 대신 정확한 버전 번호(예: 0.21)를 사용하면 컴파일러 버전 호환성 문제를 방지할 수 있습니다.
- Compact 컴파일러 설치 문제
문제:
Compact 컴파일러가 설치에 실패하거나 설치 후 동작하지 않습니다.
해결 방법:
- 설치 스크립트가 성공적으로 실행되었는지 확인하세요:
compact --version
- 명령을 찾을 수 없으면 PATH에 수동 추가하세요:
export PATH="$HOME/.compact/bin:$PATH"
- 재설치를 시도하세요:
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh
Next steps
Bun 설정이 완료되었으니 Midnight에서 DApp을 빌드할 수 있습니다. 다음 가이드를 참조하세요: