- Bun 1.2 là một bản phát hành lớn hướng tới bộ công cụ phát triển JavaScript/TypeScript full-stack, đồng thời mở rộng khả năng tương thích Node.js cùng runtime, bundler, test và package manager
- Bun đã tăng cường việc kiểm chứng tương thích bằng cách chạy bộ kiểm thử Node.js sau mỗi thay đổi, đồng thời bổ sung hỗ trợ
node:http2,node:dgram,node:cluster,node:zlib,node:v8 - API tích hợp mới
Bun.s3vàBun.sqlđưa truy cập tới object storage tương thích S3 và Postgres vào thẳng runtime, giảm phụ thuộc vào client bên ngoài - Package manager chuyển lockfile mặc định từ file nhị phân
bun.lockbsangbun.lockdựa trên JSONC, đồng thời thêm.npmrc,bun publish,bun patch,bun outdated,bun run --filter - Thư mục làm việc của
bun run, cách xử lý lỗi củaBun.build(), giá trị trả về củaserver.stop(),bun -pvà giá trị mặc định của sourcemap đã thay đổi, nên các dự án hiện có cần kiểm tra ảnh hưởng khi migration
Tăng cường khả năng tương thích Node.js
- Bun 1.2 thay đổi quy trình cải thiện tương thích bằng cách chạy bộ kiểm thử Node.js sau mỗi lần thay đổi của Bun
- Trước đây, lỗi chủ yếu được sửa dựa trên GitHub issue hoặc báo cáo không chạy được package npm, nhưng cách này gần như là kiểu “đập chuột chũi”, khiến các đợt refactor lớn trở nên khó khăn
- Bun đã port hàng nghìn file test từ kho mã Node.js sang Bun và chạy các test này ở mỗi commit để xác nhận tính tương thích
- Trong các bài test của Node.js có những trường hợp kiểm tra chi tiết triển khai nội bộ và thông điệp lỗi chính xác, nên Bun đã thay binding nội bộ bằng stub riêng trong một số test, hoặc điều chỉnh sang xác minh dựa trên
namevàcode- Bun cố gắng khớp thông điệp lỗi của Node.js nhiều nhất có thể, nhưng trong một số trường hợp vẫn cung cấp thông điệp hữu ích hơn nếu
namevàcodegiống nhau
- Bun cố gắng khớp thông điệp lỗi của Node.js nhiều nhất có thể, nhưng trong một số trường hợp vẫn cung cấp thông điệp hữu ích hơn nếu
- Các module và tính năng Node.js mới được hỗ trợ
node:http2: hỗ trợ tạo máy chủ HTTP/2, cũng cần cho máy chủ gRPCnode:dgram: hỗ trợ bind/connect cho socket UDPnode:cluster: có thể chạy nhiều instance Bun để phân phối công việc trên nhiều lõi CPUnode:zlib: phần triển khai JavaScript đã được viết lại bằng mã native và nhanh gấp 2 lần so với Bun 1.1node:v8: có thể kiểm tra heap của Bun trong Chrome DevTools bằnggetHeapSnapshot,writeHeapSnapshot
- Máy chủ
node:http2trong Bun 1.2 nhanh gấp 2 lần Node.js expressxử lý request HTTP nhanh hơn tối đa 3 lần so với Node.js nhờ cải thiện tương thíchnode:httpvà tối ưu hóa máy chủ HTTP của Bun- Cũng đã bổ sung hỗ trợ cho C++ addon sử dụng V8 C++ API
- Node.js dùng V8, còn Bun dùng JavaScriptCore, nên độ khó triển khai rất cao
- Bun triển khai public C++ API của V8 trên nền JavaScriptCore để các package như
cpu-featurescó thể hoạt động - Hỗ trợ V8 C++ API rất phức tạp nên nhiều package có thể vẫn còn thiếu tính năng; Bun đang tiếp tục cải thiện hỗ trợ cho các package như
node-canvas@v2vànode-sqlite3
API S3 tích hợp Bun.s3
- Bun 1.2 bổ sung API tích hợp
Bun.s3để làm việc với object storage tương thích S3- Có thể dùng với các dịch vụ triển khai S3 API như Amazon S3, Google Cloud Storage, Cloudflare R2
- Việc đọc, ghi, xóa file được xử lý bằng API tương thích với
Blobtheo tiêu chuẩn Web
s3.file()trả về một tham chiếu trì hoãn tới file S3, có thể dùng theo cùng cách với BunFileAPI nhưtext(),json(),arrayBuffer(),stream()- Client S3 của Bun được viết bằng mã native chứ không phải JavaScript
- So với cách dùng
@aws-sdk/client-s3trên Node.js, việc tải file từ bucket S3 nhanh hơn 5 lần
- So với cách dùng
- Tính năng ghi cung cấp
write()vàwriter()write()có thể upload chuỗi,Uint8Array,Blob,Response...writer()thực hiện multipart upload cho file lớn
presign()tạo presigned URL cho phép upload một file cụ thể- Có thể để người dùng upload trực tiếp lên S3 mà không lộ credential hoặc cấp quyền truy cập bucket không cần thiết
- Khi dùng cùng
Bun.serve(),new Response(s3.file(...))sẽ chuyển hướng bằng presigned URL thay vì để máy chủ tải file S3 rồi gửi lại- Giảm bộ nhớ, thời gian và chi phí băng thông khi máy chủ phải tải file
- URL
s3://cũng có thể dùng trongBun.file()vàfetch()- Có thể upload, download, xóa bằng
fetch("s3://...") S3Clientmặc định được cấu hình bằng các biến môi trường nhưAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY
- Có thể upload, download, xóa bằng
Client Postgres tích hợp Bun.sql
- Bun 1.2 bổ sung client SQL tích hợp
Bun.sqlhỗ trợ Postgres- Trước đó Bun đã cung cấp client SQLite tích hợp, và ở bản phát hành này phạm vi hỗ trợ cơ sở dữ liệu SQL được mở rộng
- Cũng đã có pull request bổ sung hỗ trợ MySQL
Bun.sqlthực thi SQL bằng tagged-template literal- Có thể truyền giá trị JavaScript làm tham số SQL
- Tự động dùng escape chuỗi và prepared statement để ngăn SQL injection
- Kết quả được trả về dưới dạng mảng object với tên cột làm key
- Sử dụng triển khai native và nhiều tối ưu hóa
- prepared statement tự động
- query pipelining
- binary wire protocol
- connection pooling
- cache cấu trúc
- Tốc độ đọc hàng nhanh hơn tối đa 50% so với cách dùng các client Postgres phổ biến trên Node.js
- API được lấy cảm hứng từ
postgres.js, nhằm giúp việc chuyển từ mã hiện có sang client SQL tích hợp của Bun trở nên dễ dàng
Thay đổi ở trình quản lý gói
- Bun 1.2 chuyển lockfile mặc định từ
bun.lockbdạng nhị phân sangbun.lockdạng văn bảnbun.lockbtừng giúpbun installnhanh hơn gần 30 lần so vớinpm, nhưng khó xem nội dung trên GitHub, khó review pull request và khó xử lý merge conflict- Các công cụ như Dependabot cũng gặp khó khi đọc lockfile
bun.locklà tệp JSONC- Hỗ trợ comment và trailing comma
- Giúp dễ xem diff trong pull request hơn, và trailing comma làm giảm khả năng xảy ra merge conflict
- Dự án mới sẽ tạo
bun.lock- Các dự án hiện có dùng
bun.lockbvẫn tiếp tục được hỗ trợ lockfile nhị phân mà không tự động migrate bun.lockbsẽ được hỗ trợ lâu dài, vàbun add,bun updatecũng sẽ tiếp tục cập nhật nó- Có thể migrate sang lockfile văn bản mới bằng
bun install --save-text-lockfile
- Các dự án hiện có dùng
bun installvẫn nhanh hơn 30% so với Bun 1.1 ngay cả sau khi chuyển sang lockfile văn bản- Có thể dùng comment và trailing comma trong
package.jsonrequire()vàimport()cũng có thể đọcpackage.jsonkiểu này- Tuy nhiên đây không phải tính năng được hỗ trợ rộng rãi trong toàn bộ hệ sinh thái JavaScript, nên được khuyến nghị dùng theo kiểu “at your own risk”
- Đã bổ sung hỗ trợ
.npmrc- Đọc
.npmrcở thư mục gốc dự án và thư mục home - Có thể dùng để cấu hình registry, scoped package và xác thực private registry
- Đọc
- Lệnh và tùy chọn mới cho trình quản lý gói
bun run --filter: chạy đồng thời cùng một script trên nhiều workspacebun outdated: kiểm tra dependency đã cũbun publish: thay thếnpm publish, hỗ trợ xác thực.npmrc, đóng gói tarball, OTP và xử lý các edge case của package.jsonbun patch: lưu thay đổi sửa dependency thành tệp.patchtrongpatches/và tự động áp dụng khibun install--omit=dev|optional|peer: loại trừ dependency dev, optional, peer khỏi quá trình cài đặt- Có thể cấu hình chứng chỉ CA trong
bunfig.toml, cờ CLI và.npmrc - Cũng hỗ trợ
bundleDependenciesvà giữ nguyên thụt lề củapackage.jsonkhi dùngbun add
Cải tiến test runner
bun testhỗ trợ JUnit XML reporter- Với
bun test --reporter=junit --reporter-outfile=junit.xml, có thể gửi kết quả test tới các công cụ CI/CD như Jenkins, CircleCI và GitLab CI - Cũng có thể cấu hình báo cáo JUnit trong
bunfig.toml
- Với
- Đã thêm reporter LCOV cho code coverage
bun test --coverage --coverage-reporter=lcovsẽ tạocoverage/lcov.info- Có thể đổi thư mục output bằng
--coverage-dir
- Hỗ trợ inline snapshot với
expect().toMatchInlineSnapshot()- Dùng
bun test -uhoặc--update-snapshotsđể cập nhật snapshot ngay trong tệp test - Cũng có thể dùng
toThrowErrorMatchingSnapshot()vàtoThrowErrorMatchingInlineSnapshot()
- Dùng
test.only()giờ hoạt động cả khi không có cờ--only- API
expect()được bổ sung các matcher như trong Jest, Vitest vàjest-extendedtoContainValue(),toContainKey(), các hàm nhómtoHaveReturned()- Có thể truyền thông báo lỗi tùy chỉnh ở đối số thứ hai
- Có thể thay đổi timeout test mặc định của scope hoặc module hiện tại bằng
jest.setTimeout()vàsetDefaultTimeout()
Bundler và tính năng build
- Bun 1.2 hỗ trợ HTML import
- Khi truyền tệp HTML vào tùy chọn
staticcủaBun.serve, Bun sẽ tự động bundle các thẻ<script>và<link>trong HTML rồi public chúng thành static route
- Khi truyền tệp HTML vào tùy chọn
bun build --compilehỗ trợ cross-compilation- Có thể tạo binary Windows hoặc macOS từ Linux, và cũng hỗ trợ chiều ngược lại
- Bản build cho Windows có thể đặt icon và dùng tùy chọn ẩn cửa sổ console
bun build --bytecodetạo bytecode cache- Có thể giúp thời gian khởi động của các ứng dụng như
eslintnhanh gấp 2 lần - Tệp
.jscchứa bytecode cache của tệp.jstương ứng, và cần cả hai tệp để chạy - Bytecode cache có thể lớn gấp 8 lần mã nguồn, nên đổi lại việc cải thiện thời gian khởi động là dùng nhiều dung lượng đĩa hơn
- Có thể giúp thời gian khởi động của các ứng dụng như
- Có thể chỉ định định dạng output CommonJS bằng
bun build --format=cjs- Trước đây chỉ hỗ trợ ESM
- Giúp dễ tạo thư viện hoặc ứng dụng nhắm tới các phiên bản Node.js cũ hơn
- Cải thiện khả năng phát hiện CommonJS
- Khi tệp mơ hồ, chỉ thị
"use strict"ở đầu tệp sẽ được dùng như heuristic cuối cùng để xác định CommonJS require.main === moduleđược viết lại thànhimport.meta.mainđể có thể dùng cùng câu lệnh import
- Khi tệp mơ hồ, chỉ thị
- Plugin API được bổ sung hook
onBeforeParse()- Phải được triển khai bằng N-API addon, không phải JavaScript
- Có thể xử lý mã nguồn ngay trước khi parse với gần như không có overhead trong các ngôn ngữ biên dịch như Rust, C/C++ và Zig
- Đây là API nâng cao dành cho tác giả plugin và framework
- Các tùy chọn build cũng được mở rộng
- Tiêm biến môi trường vào bundle bằng
--env="PUBLIC_*" - Loại bỏ function call theo kiểu
--drop=console - Thêm banner/footer
- Kiểm tra danh sách tệp được nhúng trong standalone executable bằng
Bun.embeddedFiles() - Bỏ qua annotation dead-code elimination sai bằng
--ignore-dce-annotations - Cấu hình để không đưa dependency gói vào bundle bằng
--packages=external
- Tiêm biến môi trường vào bundle bằng
Bundling CSS
- Bun 1.2 triển khai CSS parser và bundler mới
- Được phát triển từ công trình của LightningCSS, rồi được viết lại từ Rust sang Zig và tích hợp với parser, bundler và runtime JavaScript/TypeScript của Bun
- Với
bun build ./index.css, có thể gộp nhiều tệp CSS cùng các tham chiếu@import,url,@font-facethành một tệp CSS duy nhất - Có thể import tệp
.csstừ mã JavaScript và TypeScript- CSS được import trong JavaScript module graph cùng các quy tắc
@importsẽ được làm phẳng thành một tệp CSS theo từng entrypoint
- CSS được import trong JavaScript module graph cùng các quy tắc
- API
Bun.build()cũng có thể bundle CSS và JavaScript bằng cùng một API
Thêm API runtime Bun
Bun.serve()hỗ trợ static route thông qua thuộc tínhstatic- Truyền đường dẫn làm key và đối tượng
Responselàm value - Static route nhanh hơn tối đa 40% so với xử lý trực tiếp trong handler
fetch() - Phần body, header và status code của response được cache trong bộ nhớ nên không có JavaScript allocation hay garbage collection
- Có thể tải lại static route bằng
server.reload()
- Truyền đường dẫn làm key và đối tượng
Bun.udpSocket()cung cấp UDP socket theo kiểu API của Bun- Cũng hỗ trợ
node:dgram, nhưngBun.udpSocket()là API hiện đại tương tựBun.listen()hiện có - Có thể gửi nhiều UDP datagram bằng một syscall và xử lý OS backpressure
- Cũng hỗ trợ
Bun.file()hỗ trợdelete(),unlink(),stat()stat()trả về metadata có cùng dạng với đối tượngStatscủa Node.jsfs.stat()- Có thể dùng cùng API này cho cả file trên S3
Bun.color()cung cấp khả năng phân tích, chuẩn hóa và chuyển đổi màu sắc- Hỗ trợ CSS, ANSI color code, RGB, HSL v.v.
dns.prefetch()có thể lấy trước DNS record để làm nóng DNS cache khi khởi động- Có thể kiểm tra trạng thái DNS cache bằng
dns.getCacheStats()
- Có thể kiểm tra trạng thái DNS cache bằng
- Các tiện ích khác
Bun.inspect.table(): trả về chuỗi dạng bảng nhưconsole.tableBun.randomUUIDv7(): tạo monotonic UUID v7 phù hợp cho sắp xếp và cơ sở dữ liệu
Cải tiến client SQLite
- Client SQLite tích hợp sẵn của Bun có thể ánh xạ kết quả truy vấn thành instance của class bằng
query.as(Class)- Có thể gắn getter, setter và method
- Vì lý do hiệu năng nên không hỗ trợ class constructor, default initializer và private field
- Không quản lý quan hệ hay sinh SQL nên không phải ORM
query.iterate()xử lý bằng iterator thay vì nạp toàn bộ các hàng vào bộ nhớ cùng lúc- Bản thân đối tượng truy vấn cũng có thể duyệt bằng vòng lặp
for
- Bản thân đối tượng truy vấn cũng có thể duyệt bằng vòng lặp
- Khi bật tùy chọn
strict, có thể bỏ qua tiền tố$,@,:trong tham số truy vấn- Nếu thiếu tham số sẽ ném lỗi
- Có thể kiểm tra số hàng đã thay đổi và row ID được chèn cuối cùng từ kết quả
db.run()changeslastInsertRowid
- Tùy chọn
safeIntegerssẽ trả về số nguyên 64 bit dưới dạngBigIntthay vìnumberbị cắt bớt- Có thể thiết lập ở cấp cơ sở dữ liệu hoặc cấp truy vấn
- Có thể dùng cú pháp JavaScript
usingđể tự động đóng statement và database khi scope kết thúc
Biên dịch và chạy C từ JavaScript
- Bun 1.2 bổ sung hỗ trợ thử nghiệm để biên dịch và chạy C từ JavaScript
- Sử dụng API
cc()củabun:ffi - Đây là cách dùng system library của C từ JavaScript mà không cần build step riêng
- Sử dụng API
- Bun tích hợp sẵn
tinycc- Không giống
gcchayclang, nó có thể biên dịch mã C đơn giản trong vài mili giây - Có thể biên dịch và chạy mã C khi cần
- Không giống
- Cũng cung cấp mã C dùng N-API
- Hoạt động chỉ với Bun mà không cần bước build
node-gyp
- Hoạt động chỉ với Bun mà không cần bước build
Hỗ trợ musl và Alpine Linux
- Bun 1.2 bổ sung bản build Bun cho các bản phân phối Linux dùng musl libc thay vì glibc
- Có thể dùng trong các môi trường như Alpine Linux
- Hỗ trợ Linux x64 và aarch64
- Trong Docker có thể dùng image
oven/bun:alpine - musl cho phép tạo image container nhỏ hơn, nhưng có xu hướng chậm hơn đôi chút so với bản glibc của Bun
- Nếu không có lý do cụ thể thì nên dùng glibc
Tính năng ngôn ngữ JavaScript
- Đã thêm hỗ trợ import attributes
- Có thể import và chỉ rõ JSON, text, TOML v.v. như
import json from "./package.json" with { type: "json" } - Cũng có thể dùng trong
import()động
- Có thể import và chỉ rõ JSON, text, TOML v.v. như
- Hỗ trợ
usingvàawait using- Khi ra khỏi scope,
[Symbol.dispose]hoặc[Symbol.asyncDispose]sẽ được gọi để tự động dọn dẹp tài nguyên - Được hỗ trợ trong nhiều API của Bun như
Bun.spawn(),Bun.serve(),Bun.connect(),Bun.listen(),bun:sqlitev.v.
- Khi ra khỏi scope,
- API mới liên quan đến Promise
Promise.withResolvers(): tạopromise,resolve,rejectcùng lúcPromise.try(): bọc hàm đồng bộ hoặc bất đồng bộ thành promise
- API về lỗi và mảng byte
Error.isError(): kiểm tra chính xác hơn một giá trị có phải Error hay không, kể cả khi prototype chain bị thao tác hoặc trong tình huống cross-realm củanode:vmUint8Array.toBase64()/Uint8Array.fromBase64()Uint8Array.toHex()/Uint8Array.fromHex()
- Đã thêm iterator helper
map,flatMap,filter,take,drop,reduce,toArray,forEach,find
- Hỗ trợ
Float16Array- Mảng số thực dấu chấm động 16 bit có độ chính xác thấp hơn 32 bit nhưng hiệu quả bộ nhớ cao hơn
Thêm Web API
- Hỗ trợ
TextDecoderStreamvàTextEncoderStream- Đây là phiên bản streaming của
TextDecodervàTextEncoder - Trong Bun,
TextEncoderStreamnhanh hơn Node.js tối đa 30 lần
- Đây là phiên bản streaming của
- Hỗ trợ tùy chọn
streamcủaTextDecoder- Có thể xử lý chunk như một phần của luồng lớn hơn ngay cả khi đó chưa phải UTF-8 code point hoàn chỉnh
- Đã thêm phương thức
bytes()- Trong
Response,Blob,Bun.file()v.v., dữ liệu stream được trả về dưới dạngUint8Array - Giảm bớt quy trình gọi
arrayBuffer()rồi tạoUint8Arraynhư trước
- Trong
- Hỗ trợ upload
fetch()dạng streaming- Hữu ích khi tải lên file lớn hoặc luồng dữ liệu chưa biết trước content length
- Đã triển khai
console.group()vàconsole.groupEnd() - Hỗ trợ
URL.createObjectURL()- Có thể tạo URL từ
Blobvà dùng chofetch(),Worker,import() - Worker script cũng đi qua Bun transpiler nên có thể dùng cú pháp TypeScript
- Có thể tạo URL từ
AbortSignal.any()kết hợp nhiềuAbortSignal, để khi một signal bị abort thì signal cha cũng bị abort
Thay đổi hành vi và lưu ý khi di chuyển
- Thư mục làm việc của
bun runđã thay đổi- Trước đây sử dụng thư mục làm việc hiện tại của shell
- Trong Bun 1.2, thư mục cha của
package.jsonđược dùng làm thư mục làm việc của script - Đây là thay đổi nhằm đồng bộ với cách hoạt động của
npmvàyarn
bun testgiờ sẽ coi uncaught error hoặc rejection giữa các bài kiểm thử là lỗi thất bại- Trước đây những lỗi như vậy có thể không được xử lý là kiểm thử thất bại
server.stop()giờ trả vềPromise<void>- Có thể chờ cho đến khi các kết nối HTTP đang xử lý được đóng lại
Bun.build()giờ sẽ reject khi thất bại, thay vì đưa lỗi vàologscủa kết quả đã resolve- Nếu cần hành vi cũ, có thể đặt
throw: false
- Nếu cần hành vi cũ, có thể đặt
bun -pnay trở thành alias củabun --printđể tương thích với Node.js- Trước đây đây là alias của
bun --port
- Trước đây đây là alias của
- Giá trị mặc định của
bun build --sourcemapđã đổi từ inline source map sang linked source map- Nếu cần hành vi cũ, hãy dùng
--sourcemap=inline
- Nếu cần hành vi cũ, hãy dùng
Cải thiện hiệu năng
- Bun 1.2 bao gồm cải thiện hiệu năng trên nhiều đường chạy khác nhau
node:http2: nhanh gấp 2 lần- Tải lên S3 qua
node:http: nhanh gấp 5 lần path.resolve(): nhanh gấp 30 lần- Phân giải DNS của
fetch(): nhanh gấp 2 lần bun --hot: giảm một nửa mức sử dụng bộ nhớ- macOS
fs.readdirSync(): đọc thư mục nhỏ nhanh hơn 5% String.at(): nhanh hơn 44%atob()với đầu vào chuỗi lớn: nhanh hơn tối đa 8 lần- Giải nén dữ liệu gzip của
fetch(): nhanh hơn 30% Buffer.from(string, "base64")với đầu vào lớn: nhanh hơn từ 6 đến 30 lầnJSON.parse()với đầu vào chuỗi lớn: nhanh hơn từ 2 đến 4 lần, với đầu vào object: nhanh hơn 6%- Thông lượng của một số ứng dụng
Bun.serve(): tăng tối đa 2 lần Error.captureStackTrace(): nhanh gấp 9 lầnfs.readFile()với tệp nhỏ: nhanh hơn tối đa 10%console.log()với đối số chuỗi: nhanh hơn 50%
- Trên Windows, JIT của JavaScriptCore được kích hoạt
- Trước đây JIT chỉ khả dụng trên macOS và Linux
- JavaScript trên Windows nhìn chung chạy nhanh hơn
- Ví dụ,
Object.entries()nhanh hơn 20%,Array.map()nhanh hơn 50%
Cài đặt và nâng cấp
- Lệnh cài đặt mới
curl -fsSL https://bun.sh/install | bashpowershell -c "irm bun.sh/install.ps1 | iex"npm install -g bunbrew tap oven-sh/bunrồibrew install bundocker pull oven/bun
- Với Bun đã được cài đặt, hãy nâng cấp bằng
bun upgrade
1 bình luận
Các ý kiến trên Hacker News
Không hiểu vì sao lại đưa cơ sở dữ liệu bên thứ ba và thư viện S3 bên ngoài vào core/thư viện chuẩn
Những thứ như vậy có lẽ hợp làm thư viện tùy chọn hơn; các runtime kiểu này cần chọn rất thận trọng những gì đưa vào thư viện chuẩn
Ngay từ bây giờ đã có cảm giác đây là một dự án nhồi nhét mọi thứ như “bồn rửa nhà bếp”
Cách tiếp cận kèm sẵn pin phổ biến ở nhiều nơi và là con đường được lựa chọn
Cấu hình TypeScript cũng khó, Webpack, S3, Postgres, Jest, v.v. cũng vậy, nên cách tiếp cận file/stream được đơn giản hóa cũng khá thú vị
Có lẽ chỉ cần chờ xem các nhà cung cấp triển khai phân tán sẽ xuất hiện thế nào
Tất nhiên có thể tôi sai, nhưng việc đưa các phụ thuộc như vậy vào core/thư viện chuẩn thật sự không hợp lý lắm
Có vẻ anh ấy cho rằng nếu đưa vào core thì có thể tối ưu tốt hơn so với thư viện bên thứ ba
Cá nhân tôi nghĩ đó là cách tiếp cận sai và cảm giác Jared đang quá tham vọng, nhưng rốt cuộc đây vẫn là dự án đam mê của anh ấy
Theo cách Bun diễn đạt thì “Bun hướng tới một runtime JavaScript ưu tiên cloud. Nghĩa là nó hỗ trợ tất cả công cụ và dịch vụ cần thiết để chạy ứng dụng production trên cloud”, nhưng câu này không tạo nhiều niềm tin cho tôi
Lựa chọn thiết kế cụ thể này trông còn tệ hơn cả Node
Vấn đề của phần mềm được VC hậu thuẫn luôn là các tính năng tích hợp kiểu này cố gắng cung cấp một thứ gì đó độc quyền, nói cách khác là tạo ra sự phụ thuộc
Trải nghiệm dùng Bun của tôi đến giờ rất tốt
Mỗi khi cấu hình TypeScript/Jest/React/Webpack cho dự án mới, tôi luôn ngại vì các breaking change chỗ này chỗ kia; còn với Bun thì nó tự xử lý và với nhu cầu của tôi thì cứ chạy được một cách không đau đớn
Khó nói gì về việc tích hợp các thư viện bên thứ ba như S3, SQL, nhưng ít nhất có vẻ họ đang tập trung vào những thứ phổ biến nhất và được yêu cầu nhiều nhất
Tôi thích vì nó mang lại sự hợp lý mà hệ sinh thái công cụ Node.js từng cần
Có vẻ bạn đang đánh giá thấp việc các công cụ khác cũng đã tiến bộ rất nhiều trong thời gian qua
Với tôi nó giống như mã gian lận năng suất
Vì ChatGPT chưa hiểu Bun tốt nên có hơi mất năng suất một chút, nhưng tôi vẫn thích Bun
Có nhiều điểm hay, nhưng tôi lo rằng một số hành vi mặc định có đang đi quá xa theo hướng hành vi ẩn như phép thuật hay không
Khi dùng
new Response(s3.file(...)), thay vì tải file S3 xuống server rồi gửi cho người dùng, Bun chuyển hướng người dùng tới URL được ký sẵn của file S3Với thiết lập mặc định thì đây là lựa chọn khá bất ngờ, và hoàn toàn không rõ phải tắt thế nào khi không muốn trực tiếp phơi bày bucket S3
Ban đầu tôi rất kỳ vọng vào dự án này, nhưng nhìn vào các quyết định thiết kế rời rạc được công khai trên mạng xã hội, mà cá nhân tôi thấy nhiều cái không tốt, thì tôi không còn tin vào định hướng dài hạn
Nếu vẫn giữ ở v0.x thì ổn, nhưng một khi đã phát hành 1.0, tiêu chuẩn để mở rộng bề mặt API lẽ ra phải cao hơn nhiều
Response(file.stream())Cá nhân tôi thấy nó giống một hành vi có tác dụng phụ mạnh, và khi đọc thì trông như nó trả về nội dung file chứ không phải URL
Dù vậy tôi cũng tò mò việc lộ bucket thì có gì khó chịu
Vì là URL được ký sẵn nên nó đâu cấp quyền truy cập rộng rãi
Một API tường minh hơn như
Response((file(...).getPresignedURL()))sẽ tốt hơn, hoặc có tùy chọn bật hành vi này bằng biến môi trường hay cấu hình Bun thì có lẽ ổn hơnKèm sẵn pin tạo ra khác biệt lớn
Đó cũng là lý do tôi thích việc các Web API như Fetch API, Service Workers, Web Components, ES6+, WebRTC giờ đã trở thành native trên cả hai runtime V8 và WebKit
Tuy nhiên cũng phải có giới hạn
S3 có thể là đi hơi xa, nhưng SQL driver thì hợp lý
Dù vậy, vấn đề là nên đưa vào đến đâu
Có rất nhiều cơ sở dữ liệu, vậy có phải đưa driver của một nửa trong số đó vào không?
Chỉ đến mức đó thôi cũng đã thêm nhiều mã, có thể làm file thực thi chậm đi
Ngoài ra, đưa những API nhạy cảm như vậy vào Bun cũng có thể khiến bảo mật bị bỏ sót
Hãy tưởng tượng một script nào đó hoặc một vấn đề về đường dẫn khiến
evalđược chạy, rồi Bun upload toàn bộ file nguồn lên S3 cá nhân; đến lúc đó là coi như xongTôi từng nghĩ tùy vào cách mã được load lúc runtime, mức này có thể gần như bỏ qua được
Nếu chỉ khi thấy câu lệnh
importthì việc load mã mới được kích hoạt, thì thực tế chẳng có overhead tốc độ nào phải không?Ngay cả khi được link tĩnh, tôi cũng không rõ vì sao chỉ vì mã tồn tại mà file thực thi lại chậm đi đến mức đáng quan tâm
Chắc có chuyện file thực thi cần load vào bộ nhớ lớn hơn theo đúng nghĩa đen, nhưng có lẽ không phải kiểu chậm đi có thể cảm nhận được
Cốt lõi là ai chịu trách nhiệm bảo trì thư viện, và khi SQLite thay đổi thì thư viện đó sẽ được thay đổi như thế nào
Nếu SQLite có lỗi thì trong Bun sẽ sửa ra sao?
Những phiên bản nào cần được đưa bản sửa vào?
Bản vá của runtime có thể thay đổi hành vi của mã chạy bên trên nó; vậy xử lý thế nào nếu người dùng đã workaround theo hành vi cũ?
Ở một mức độ nào đó đây là các vấn đề có thể giải quyết, nhưng cũng đi kèm nhược điểm
Đến một lúc nào đó, nó không còn là runtime nữa mà trở thành nền tảng, kéo theo những trách nhiệm và vấn đề khác
Nó không phải chuẩn web thực sự, nhưng cũng là thứ nhiều người trên thực tế coi như chuẩn để tương thích theo
Gần đây một khách hàng của tôi dùng Bun trong production
Tôi nghe nói trải nghiệm phát triển với Bun tốt đến mức khó tin nhờ tốc độ và sự đơn giản
Trải nghiệm nhà phát triển về lâu dài đóng vai trò rất lớn
Nếu codebase hoặc quy trình lộn xộn, bạn sẽ mất người giỏi trừ khi trả mức đãi ngộ cỡ FAANG
Tôi vẫn chưa dùng thử Bun, nhưng danh sách tính năng dài đến mức khiến tôi hoài nghi liệu tất cả có vững chắc và không lỗi hay không
Tôi hy vọng mình sai, và dự định sẽ thử chạy trong một dự án sau này
Từ góc nhìn quản lý dự án, tôi hơi bối rối vì sao lại dành thời gian cho hỗ trợ S3 khi nó còn chưa tương thích 100% với Node.js
Next.js là một hệ sinh thái rất lớn, nên nếu kéo được khách hàng Next.js sang thì có thể tăng trưởng lớn hơn nhiều so với hỗ trợ S3
Hằng ngày bạn thực sự dùng bao nhiêu trong toàn bộ bề mặt API của Node.js?
Bạn thực sự phụ thuộc bao nhiêu vào các edge case kỳ quặc trong đó?
Những người làm việc trên đó cũng không phải robot
Có việc cần thời gian để nắm bắt, và trong lúc đó họ cũng có thể làm việc khác
Cũng không phải một người làm tất cả mọi thứ
Nói “kéo khách hàng Next.js sang thì sẽ tăng trưởng hơn”, nhưng tăng trưởng hướng tới điều gì?
Điều đó không kiếm ra tiền
Đây là một dự án được VC hậu thuẫn, và mục tiêu không phải là cung cấp Bun miễn phí để có được mọi người dùng trên thế giới
Zig có mức an toàn bộ nhớ rất thấp
Nếu tham chiếu một biến không còn sống, thay vì lỗi segmentation, nó truy cập vào một vùng bộ nhớ tùy ý không liên quan
Nghe nói ngay cả trong chế độ debug và safe cũng vậy[0]
Việc đặt lên trên một hệ thống lifetime bộ nhớ đánh dấu tên biến là đã chết và chặn truy cập nếu nó đã chết khó đến vậy sao?
Cuối cùng lại thành “đừng dùng hành vi không xác định”[1]
Vì vậy tôi không muốn đặt bất cứ thứ gì làm bằng Zig ở những nơi như web server phơi ra Internet
[0] : https://news.ycombinator.com/item?id=41720995
[1] : https://github.com/ziglang/zig/issues/16467#issuecomment-164...
Năm ngoái tôi đã thử dùng và nó liên tục crash
bun addkhông giữ nguyên khoảng trắng và thụt lề trongpackage.json, và giờ giữ nguyên được cả kiểu thụt lề kỳ quặc đến đâu, khá buồn cườiKhông biết ai yêu cầu chuyện này, và vì sao họ nghĩ đáng để viết mã cho nó
Import HTML thật ấn tượng và hay ho
Trong Bun 1.2, họ hỗ trợ import HTML, và nói rằng có thể thay thế toàn bộ toolchain frontend bằng một câu lệnh
importduy nhấtBạn có thể bắt đầu bằng cách truyền import HTML vào tùy chọn
staticcủaBun.serveCó thể load các plugin theo từng framework như hot module replacement, tiền xử lý CSS, trình biên dịch Vue SFC không?
Việc phục vụ file tĩnh thì không hẳn là mới, nên có vẻ tôi đang bỏ sót điều gì đó
Tôi từng nghĩ không có dự án nào được định sẵn sẽ thất bại nhiều như một lựa chọn cạnh tranh thay thế cho Node.js, nhưng dùng thử một lần hóa ra lại là quyết định đúng
Tôi phải viết nhiều script độc lập để xử lý việc cập nhật file văn bản và SQLite DB, và có thể dùng ngay TypeScript,
bun:sqlite[1],bun $ Shell[2] mà không cần file cấu hình hay quản lý dependency npm cục bộSau đó tôi cũng thử dùng cho các dự án JS/TypeScript mới, và cả bundler tích hợp sẵn [3] lẫn hỗ trợ test [4] đều hữu ích, cài dependency cũng xong ngay tức thì
Mọi thứ chạy nhanh và dùng được ngay thực sự là một cải thiện chất lượng cuộc sống, và giờ Bun đã trở thành lựa chọn đầu tiên của tôi cho dự án JS mới
[1] https://bun.sh/docs/runtime/shell
[2] https://bun.sh/docs/api/sqlite
[3] https://bun.sh/docs/bundler
[4] https://bun.sh/docs/cli/test
Trước đây tôi nghiêng về kiểu “mấy thứ này sang năm npm cũng sẽ có hết, vậy thì có ý nghĩa gì”
Cuối cùng tôi đã thử Bun và thật sự bất ngờ
Khi những yếu tố nhỏ trong trải nghiệm lập trình viên tích lại, khác biệt trở nên rất lớn
Trong dự án của tôi, Bun thật sự mang cảm giác như thế hệ tiếp theo
Cách đây không lâu tôi lần đầu dùng thử Bun và trải nghiệm rất tuyệt
Tất cả dự án của tôi đều cấu hình Webpack hoặc Vite để dùng TypeScript; một khi đã cấu hình thì gần như chạy hoàn hảo, nhưng bản thân việc cấu hình khá phiền và không đáng cho các script nhỏ
Trái lại, Bun chạy được ngay
Tôi đã loay hoay 10–30 phút với một công cụ nào đó tên là
node-tshay gì đó để cố chạy TS “trực tiếp” từ CLI, rồi phải đối mặt với những thông báo kinh khủng như “không phải là module”, “không thể dùng import/require”, “ESM/CJS”, và đã thử hết các cách sửa phổ biến như đổi loại module trongpackage.json, đổitsconfig, đổi cách dùngimport/requireKhi đang cố chạy một script khoảng 200 dòng, đến nước cuối cùng tôi chuyển sang Bun thì nó chạy rất tuyệt
node --experimental-strip-types index.tsNếu không dùng Node mới nhất thì gói
tsxhoạt động tốt với tôiTốt hơn
ts-nodeTuy nhiên cả hai lựa chọn đều chỉ bỏ qua thông tin kiểu, và Bun cũng vậy
Tôi thích hướng đi này
Đặc biệt, việc đưa vào hỗ trợ native cho S3 và Postgres là rất hợp lý, vì nó có thể tồn tại như một phương án thay thế cho tình trạng hiện nay là “tự lắp ghép framework”
Trong mọi web framework như Rails và Laravel, đây là tiêu chuẩn, và hệ sinh thái JS cũng có thể hưởng lợi lớn từ điều này
Tôi nghĩ bước tiếp theo là trải nghiệm test mặc định tốt hơn, có thể làm tốt migration và quản lý schema, cũng như thiết lập factory