Bun 이란?
node.js, deno 와 같이 javascript runtime 패키지 중 하나이다.
Bun의 공식 홈페이지에 의하면 pnpm보다l 17배, yarn보다 33배, pnpm보다 17배 빠르다고한다.
1. node.js
- C++을 기반으로 개발한 오픈 소스로,
- javascript라는 언어를 JIT컴파일러를 기반으로 기계어로 해석해주는
- V8엔진을 통해 빌드된 javascript 런타임 환경이다.
2. deno
- deno는 node환경에 여러 문제(보안, async, typescript 등)를 해결하기 위해 나왔다.
- V8엔진과 Rust, Typescript를 기반으로 작성하여 안정성이 높고,
- 패키지 의존성을 내부로 옮겨 npm이 필요 없고,
- 컴파일 없이 Typescript를 지원하고 있다!
3. Bun
- V8엔진을 사용하지 않고 사파리에서 사용하는 Webkit의 javascriptCore엔진에서 동작한다.
- 또한 C++ 과 Rust를 사용했던 Node와 Deno와 달리 더 저수준 언어인 Zig를 사용해서 개발하여 속도가 더욱 빠르다.
- npm패키지를 잘 지원해준다. 기존 node진영의 패키지들도 사용할 수 있기 때문에 거부감 없이 늘 쓰는 것처럼 사용할 수 있다.
- Webpack이 사라졌다. js, jsx, ts 심지어 css env파일까지 트랜스폼해준다. 즉 webpack이나 esbuild, vite 등이 필요 없어졌다.
Bun 이 빠르게 패키지를 설치할 수 있는 원리
Global cache
한번 설치된 패키지는 로컬의 `~/.bun/install/cache` 디렉토리에 바이너리 파일로 저장이 된 것을 확인할 수 있다. 이를 통해 로컬에서 해당 패키지를 재 Install할때마다 cache 디렉토리를 먼저 확인하여 설치하므로 굉장히 빠른 인스톨이 가능하다.
하지만 이는 동일한 로컬에서의 수행에서만 유의한 cache이므로, 만약 항시 새롭게 세팅되는 CI/CD 환경의 경우에는 큰 의미가 없는 기능이 될 것 같다.
패키지 설치 시 Global Cache로 빠르게 다운로드를 한다고 해서, Bun은 여전히 node_modules로 복사하는 과정이 필요한데, 실제로 install할 패키지 파일 내용들이 꽤 많기 때문에 시간이 꽤 걸릴 수 있음에도, 여전히 굉장히 빠르다. 이러한 빠른 복사가 가능한 이유는 빠른 System Call을 이용하게 때문인데, Linux는 hardllinks, MacOS에서는 clonefile을 이용한다.
bun.lockb
bun install하면 생성되는 파일로, yarn.lock.json이나 package.lock.json과 같이 의존성 디펜던시 정보들이 담겨있는 파일이다.
차이점은 이 파일은 바이너리 파일로 되어 있어서 직접 해당 내용을 확인해볼 수는 없다.
대신 해당 파일을 yarn.lock 형식으로 볼 수 있는 기능을 제공한다. 이를 통해 실제 내부 의존성 디펜던시의 정보들을 확인해볼 수 있다.
$ bun bun.lockb
bun.lockb 파일에는 아래와 같은 정보들이 들어있다.
- 설치할 패키지와 이에 의존하는 하위 디펜던시 정보.
- 디펜던시가 해결된 패키지 정보.
- 디펜던시 각 버전.
- MetaData.
- 호이스팅 된 Install 순서.
이러한 정보들을 담고있는 bun.lockb이 어떻게 빠를 수 있는걸까?
bun.lockb에서는 위 정보들을 Linear(선형)배열 형태로 저장하여 사용한다.
"선형 배열 형태로 담는다"는 것은 데이터들을 일렬로 연결하여 저장하는 방식을 말한다. 즉, 데이터를 연속적으로 저장하며 패키지들이 auto-incrementing되는 정수 ID 혹은 패키지 이름의 해시 값을 사용하여 참조하게 된다. (해시 값은 8자보다 긴 중복되지 않는 String 값을 사용한다.)
우선 이러한 방식을 쓰는 이유가, 이처럼 배열 형태를 이용하면, 참조하는 곳에서는 인덱스만 알면 원하는 곳을 직접 접근이 가능하기 때문에 빠르게 원하는 곳을 참조할 수 있고 파일의 구조를 단순하게 유지하고 데이터를 효율적으로 검색하고 수정할 수 있다. 하지만 이에 대한 단점은 아무래도 정렬되지 않은 순차적 저장 방식이다보니 최적화된 형태로 저장이 되어있지 않아 메모리 낭비가 심해질 수 있다.
Scope Dependency
특정 Scope를 지정해서 사용하는 디펜던시의 경우 npmrc, yarnrc 등을 선언하여 사용하는데, bun에서는 아직 npmrc 파일 읽기가 호환되지 않는다. (참고)
대신, bunfig.toml 파일을 통해 스코프 지정을 할 수 있다.
[install]
# set default registry as a string
registry = "https://registry.npmjs.org"
# set a token
registry = { url = "https://registry.npmjs.org", token = "123456" }
# set a username/password
registry = "https://username:password@registry.npmjs.org"
or, private registry 로 스코프를 지정하려면 다음과 같이 하면 된다.
[install.scopes]
# registry as string
"@myorg1" = "https://username:password@registry.myorg.com/"
# registry with username/password
# you can reference environment variables
"@myorg2" = { username = "myusername", password = "$NPM_PASS", url = "https://registry.myorg.com/" }
# registry with token
"@myorg3" = { token = "$npm_token", url = "https://registry.myorg.com/" }
사용 방법
bun install | npm install | package.json의 모든 종속성 설치 |
bun add <package> | npm install <package> | 프로젝트에 새 패키지 추가 |
bun add <package> --dev | npm install <package> --dev | 새 개발 전용 패키지 추가 |
bun remove <package> | npm uninstall <package> | 프로젝트에서 패키지 제거 |
bun update <package> | npm update <package> | 특정 패키지를 최신 버전으로 업데이트 |
bun run <script> | npm run <script> | package.json에서 지정된 스크립트를 실행 |
'JavaScript' 카테고리의 다른 글
[Javascript] Javascript 동작방식 (JS엔진, 호이스팅, 실행컨텍스트, 스코프 체인) (1) | 2024.10.29 |
---|
댓글