deno bundle được đưa trở lại dựa trên esbuild, cho phép tạo bundle một tệp cho cả server và trình duyệt, đồng thời tự động tree shaking và tối ưu hóa
- Hỗ trợ import văn bản/byte và ổn định hóa OpenTelemetry tích hợp sẵn, giúp tăng cường khả năng quan sát và trải nghiệm sử dụng tệp ngoài
- Cờ
--preload mới, cải thiện tiện ích phụ thuộc với deno update, đo coverage cho script, quản lý quyền và cả khả năng tương thích API Node.js đều được cải thiện trên diện rộng
- LSP, Jupyter, bench/coverage, tsconfig được nâng cấp hỗ trợ cùng nhiều cải tiến tiện dụng khác
Tóm tắt các thay đổi chính và tính năng mới của Deno 2.4
Sự trở lại của deno bundle
- Trong Deno 2.4, subcommand
deno bundle dùng để tạo bundle JavaScript một tệp đã được tích hợp trở lại cùng với engine esbuild
- Hỗ trợ cả server lẫn trình duyệt, đồng thời có thể bundle cả phụ thuộc npm, JSR mà không gặp vấn đề
- Hỗ trợ tự động tree shaking và tối ưu hóa mã (minify), mang lại môi trường dễ quản lý hơn
- Trong tương lai dự kiến sẽ bổ sung khả năng mở rộng và tùy biến bundle theo lập trình thông qua runtime API và plugin
Hỗ trợ import văn bản và byte
- Cung cấp cờ
--unstable-raw-imports để có thể nhúng các tệp dữ liệu ngoài như văn bản, nhị phân, hình ảnh vào đồ thị module JavaScript
- Trước đây cần đọc tệp ngoài qua I/O, nhưng giờ có thể chỉ định kiểu tệp ngay trong cú pháp import để dùng trực tiếp dữ liệu byte/văn bản
- Tính năng này cũng hoạt động khi bundle hoặc compile, giúp dễ dàng triển khai nhúng asset vào sản phẩm đầu ra
- Cùng với hỗ trợ import sẵn có như JSON, Wasm, nhiều định dạng tệp có thể được quản lý theo cách thân thiện với đặc tả hơn
- Dù đặc tả vẫn đang được thảo luận, Deno đang phản ánh hài hòa cả tiến bộ tính năng lẫn xu hướng tiêu chuẩn
Ổn định hóa OpenTelemetry tích hợp sẵn
- Hỗ trợ OpenTelemetry tích hợp sẵn được giới thiệu từ phiên bản 2.2 nay đã được ổn định hoàn toàn trong 2.4
- Chỉ cần đặt biến môi trường OTEL_DENO=1 là có thể tự động hóa thu thập log, metric, trace mà không cần thêm cờ nào khác
- Hỗ trợ đồng bộ từ tương thích không cần cấu hình với Node.js đến cả môi trường triển khai Deno Deploy
- Cũng có thể tự động liên kết/quan sát log
console.log và các HTTP request
- Do đặc tính sử dụng tài nguyên, cần kiểm soát bằng biến môi trường
Cờ --preload để thiết lập môi trường trước khi chạy
- Đã bổ sung cờ
--preload cho phép chạy trước mã dùng để thay đổi môi trường toàn cục, nạp dữ liệu, đăng ký module phụ thuộc... trước khi thực thi script chính
- Hữu ích trong nhiều tình huống xây dựng nền tảng như tùy biến platform hoặc thiết lập lại global object
- Có thể dùng trên các lệnh chính như
deno run, deno test, deno bench
Đơn giản hóa quản lý phụ thuộc: deno update
- Giới thiệu subcommand
deno update để tự động cập nhật lên phiên bản mới nhất cho phụ thuộc npm và JSR
- Hỗ trợ cập nhật hàng loạt nhiều phụ thuộc cùng lúc và cập nhật chính xác dựa trên tương thích Semver
- Cũng cung cấp như bí danh của
deno outdated --update, giúp tăng tính tiện dụng
Coverage cho script: deno run --coverage
- Không chỉ từng bài test, giờ đây còn có thể thu thập coverage cho toàn bộ quá trình chạy có bao gồm subprocess
- Có thể quản lý dữ liệu linh hoạt bằng nhiều cách như biến môi trường
DENO_COVERAGE_DIR
- Bổ sung hỗ trợ dark mode cho báo cáo coverage HTML
Biến môi trường tương thích Deno DENO_COMPAT=1
- Biến
DENO_COMPAT=1 được giới thiệu để tăng tính tiện dụng và khả năng tương thích cho hệ sinh thái npm và các dự án dựa trên package.json
- Tự động áp dụng nhiều cờ Unstable, và trong tương lai dự kiến mở rộng thêm như bỏ qua npm prefix
Cải thiện quản lý quyền và bảo mật
- Cờ
--allow-net nay hỗ trợ wildcard subdomain và dải CIDR
- Bổ sung các cờ
--allow-import để giới hạn host có thể import, và --deny-import để chặn một cách tường minh
- API
Deno.permissions chính thức hỗ trợ truy vấn kiểu "import"
- Khi dùng
Deno.execPath(), không còn cần quyền đọc nữa, giúp việc sử dụng đường dẫn file thực thi trở nên dễ hơn
exports có điều kiện trong package.json
- Hỗ trợ conditional exports trong package npm, đặc biệt tăng cường hỗ trợ cho nhiều hệ sinh thái như cấu hình server của React
- Có thể triển khai hành vi import tùy biến linh hoạt bằng cờ điều kiện do người dùng chỉ định
Hỗ trợ bare specifier trong deno run
- Có thể chạy entry point của lệnh bằng alias (bare spec) đã cấu hình trong
"imports" của deno.json
- Mang lại sự tiện lợi lớn về năng suất phát triển và tự động hóa quản lý module
Cải thiện định dạng mã cho các định dạng như XML, SVG
deno fmt nay hỗ trợ tự động format nhiều loại tệp template như .xml, .svg, .mustache
Tăng cường hỗ trợ tsconfig.json
- Cải thiện độ chính xác nhận diện nhiều tùy chọn như
references, extends, files, include, exclude
- Cung cấp khả năng tương thích tốt hơn với các framework frontend hiện đại như Vue, Svelte, Solid, Qwik
Tăng khả năng tương thích với biến toàn cục và API của Node
- Các global object của Node.js như
Buffer, global, setImmediate, clearImmediate được thay đổi để luôn tồn tại cả trong mã người dùng
- Những global trước đây chỉ dành cho package npm giờ cũng có thể dùng ngay mà không cần cờ lệnh
- Đạt trên 95% tương thích với
node:buffer, node:events, node:querystring, node:quic, node:wasm và sẽ tiếp tục mở rộng
- Phiên bản mặc định của kiểu
@types/node cũng được cập nhật lên 22.15.14
Thay đổi quản lý package npm cục bộ
- Tên tùy chọn liên kết package npm cục bộ được đổi từ
patch sang links, thống nhất với ý nghĩa của npm link
- Khi dùng tùy chọn cũ sẽ hiển thị cảnh báo deprecation, giúp quản lý package rõ ràng hơn
Cải thiện LSP và năng suất phát triển
- Cùng với các cải tiến về hiệu năng và tính năng của LSP, còn có nhiều tiện ích như hỗ trợ socket Unix/Vsock cho
fetch, callback onListen của server, quản lý kernel Jupyter, đọc comment trong plugin lint và khả năng tương thích Markdown cho bảng bench/coverage
- Việc nhận diện tín hiệu Ctrl+Close trên Windows (windows SIGHUP), cùng định dạng Markdown cho đầu ra văn bản của bench/coverage cũng được cải thiện mới
Lời cảm ơn tới cộng đồng và các nhà đóng góp
- Sự phát triển của Deno 2.4 có vai trò lớn từ sự tham gia và phản hồi của nhiều thành viên đóng góp trong cộng đồng
- Có thể tham khảo thêm nội dung và thay đổi chi tiết tại trang GitHub Releases
Kết luận
- Deno 2.4 mang lại bước tiến lớn trên nhiều phương diện như bundle, import tệp ngoài, khả năng quan sát, quyền/bảo mật, tương thích, năng suất
- Có thể trải nghiệm môi trường phát triển tích hợp dễ dùng nhưng mạnh mẽ trong quy trình phát triển cũng như các dự án frontend hiện đại và hệ sinh thái Node mới nhất
- Thông tin bổ sung, tin tức mới nhất và toàn bộ lịch sử thay đổi có thể xem trong tài liệu chính thức, blog và trang GitHub Releases
1 bình luận
Ý kiến trên Hacker News
Tôi thật sự rất thích ý tưởng của Deno, nên từng thử áp dụng tối đa Deno.json, JSR, import hiện đại, Deno Deploy... vào một dự án monorepo có Next.js, Hono và các package private. Hono chạy gọn gàng ổn thỏa, nhưng Next.js thì không như vậy, và cũng có lúc các vấn đề liên quan đến type bị lỗi vặt theo kiểu khó chịu. Tôi cũng nhớ việc chọn đích triển khai như Vercel cũng là một vấn đề. Tôi chia sẻ một sự cố nhỏ từng gặp qua liên kết issue. Ngược lại, Bun dù cảm giác sử dụng không gọn như Deno nhưng lại cần suy nghĩ ít hơn và cho cảm giác là cứ thế mà "chạy". Dù vậy, Bun cũng không hoàn hảo, chẳng hạn Vercel chưa hỗ trợ Bun runtime
Có lời khuyên rằng stack đã chọn vẫn quá xoay quanh npm, đặc biệt là trong môi trường có nhiều package npm private, nên khá gượng ép. Theo tôi, điểm ngọt của cách làm kiểu Deno nằm ở việc tự chọn một stack vốn đã thân thiện với Deno hoặc ESM. Trải nghiệm dùng Lume hoặc nhắm tới Deno Deploy là rất tốt. (Điểm JSR cũng giúp khám phá các thư viện thú vị và tương thích ESM mạnh.) Tất nhiên, bảo mọi người bắt đầu với một stack hoàn toàn mới là điều khó thực tế, và khoản đầu tư vào Next.js hiện có cũng lớn nên tôi ngại khuyến nghị Deno. Nhưng tôi nghĩ ưu điểm của Deno bộc lộ rõ nhất trong môi trường khởi đầu từ con số 0 với toàn bộ công cụ Deno-native, ESM-native. Nhân tiện, khả năng tương thích npm của Deno đang ngày càng tốt hơn, và ghi chú phát hành 2.4 cũng có các cải tiến liên quan. Trong môi trường full-stack, cách tiếp cận ưu tiên
package.jsonthay vì deno.json thực ra lại tương thích tốt hơn, nên về dài hạn dù có đẩy theo deno.json thì cấu hình dựa trên package json vẫn đáng khuyến nghịTôi đã thử dùng Deno ở chế độ tương thích npm và ấn tượng là nó hoạt động tốt hơn mong đợi. Cách dùng khá giống Bun. Nếu chạy
deno installtrong thư mục cópackage.json, nó sẽ tạo ra mộtnode_modulesgọn nhẹ, và có thể chạy các script định nghĩa trong package.json bằng lệnhdeno task something. Nhưng cách làm riêng của Deno nhiều khi khá tốn thời gian nên gây bực bội, và nếu muốn quay lại môi trường node/npm thì mọi thứ lại càng đau đầu hơn. Kết luận là dùng Deno cùng vớipackage.jsonsẽ dễ thở hơnBan đầu tôi đã all-in vào Deno, nhưng rồi quá nhiều vấn đề nhỏ nhặt khiến rất mệt mỏi. Trong khi đó Bun lại chạy tốt mà hầu như không phải bận tâm gì
Mọi người có xu hướng đánh giá thấp khả năng tương thích node của Deno. Tôi kỳ vọng việc đưa vào biến môi trường compat sẽ giúp việc phổ biến thuận lợi hơn. Sẽ còn tiện hơn nữa nếu các lệnh như denon tự động bật nó lên
Theo kinh nghiệm của tôi thì khả năng tương thích node của Deno gây thất vọng, thấp hơn kỳ vọng. Mất khoảng 1 giờ để chuyển một dự án đơn giản cỡ 100~200 dòng sang Deno, trong khi đáng ra chỉ nên mất 5~10 phút. Một số method của node không được hỗ trợ và tài liệu liên quan cũng sơ sài, còn các tính năng cơ bản thì lại phải tải trực tiếp từ những URL khó tìm. Đến lúc port test suite thì tôi bỏ cuộc. Đặc biệt, quá trình chuyển từ CommonJS (CJS) sang ESM đau đớn hơn nhiều so với tưởng tượng, hoàn toàn không hề dễ như tài liệu chính thức của Deno mô tả. Tôi đã có trải nghiệm không thể port toàn bộ thư viện
Trước đây tôi khá tích cực với Deno, nhưng giờ thì không thấy lý do gì để dùng Deno thay vì Bun nữa
Có nhận xét rằng danh sách thay đổi gần đây của Deno khá tốt. Tôi đang dùng Deno rất hài lòng cho các script ngẫu nhiên và glue code (còn machine learning các thứ thì dùng python/uv), và cũng kỳ vọng vào hỗ trợ gRPC và lệnh bundle trong tương lai
Vẫn thấy lạ là đến giờ Deno vẫn chưa chạy tử tế trên FreeBSD. Binding V8 dựa trên Rust vẫn chưa được port
Tôi tò mò không biết thực tế có bao nhiêu lập trình viên JavaScript hiện đại dùng FreeBSD
Ngày xưa tính khả chuyển giữa các hệ Unix từng là thước đo độ sạch của mã nguồn, còn bây giờ việc tương thích giữa các hệ Unix khác nhau dường như không còn được nhấn mạnh, điều này khiến tôi ngạc nhiên
Có vẻ như nó đã được đăng ký trong ports dành cho FreeBSD
Việc không đổ quá nhiều công sức vào hỗ trợ FreeBSD là điều hoàn toàn dễ hiểu
Có ý kiến cho rằng lý do Deno chưa được dùng rộng rãi hơn trong production là vì thiếu một cơ sở dữ liệu lỗ hổng tiêu chuẩn hóa. Có thể bù lại bằng khả năng tương thích npm 100%, nhưng khi đó phần lớn các package deno phổ biến sẽ bị nằm ngoài phạm vi. Về căn bản, việc không có một trình quản lý package trung tâm (đây là thiết kế có chủ ý) là một thách thức. Có ai hỏi liệu đã có tiến triển nào ở mặt này chưa
Có ý kiến phản biện rằng nếu việc thiếu cơ sở dữ liệu lỗ hổng thực sự là vấn đề lớn trong production, thì C/C++ cũng sẽ không thể dùng được theo cùng logic. Trên thực tế, C/C++ kiểm tra vấn đề bảo mật bằng cách tham chiếu các cơ sở dữ liệu bất khả tri với ngôn ngữ như CVE/GHSA. Nhân tiện, với C thì nhiều khi người ta chỉ vendoring file ngoài vào dùng mà chẳng theo dõi version gì cả. Ngoài ra còn có file
deno.lock, nên ai quan tâm có thể dựa vào đó để đối chiếu với cơ sở dữ liệu lỗ hổng cho các version đang dùngCấu trúc lấy package trực tiếp từ URL (GitHub chẳng hạn) cũng khá giống Go, nên vấn đề tương tự cũng áp dụng cho Go
Tôi thích việc subcommand bundle đã được thêm trở lại. Không còn phải dùng các cách lách phiền phức nữa nên rất hài lòng
Khá bất ngờ khi họ chọn esbuild thay vì Rolldown viết bằng Rust cho tác vụ bundle. Rolldown giờ cũng sắp lên v1 rồi mà
Tôi thật sự thích định hướng của Deno, và nghĩ rằng Node lẽ ra ngay từ đầu nên như vậy. Nhưng điều khiến tôi lo là Deno cũng có thể bị cuốn theo "hype" của các đối thủ rồi thay đổi theo mà không giữ được bản sắc
Tôi tiếp tục nghe nhiều đánh giá tốt về Deno. Nhờ vậy mà tôi cũng bắt đầu nghĩ đến việc thử dùng js
Tôi ủng hộ Deno từ góc độ bảo mật, nhưng từng thấy khó chịu khi website chính thức khuyến nghị người dùng cài theo kiểu
curl mywebsite.com/foo.sh | sh. Tất nhiên mức chấp nhận rủi ro của mỗi người khác nhau, nhưng ít nhất nếu tải file xuống rồi mới chạy thì bản thân bạn hoặc phần mềm diệt virus còn có thể kiểm tra. Hệ sinh thái Node/Deno + npm về cơ bản là một cấu trúc đòi hỏi mức độ tin cậy khá cao. Trong hướng dẫn chính thức, ngoàicurl | shcòn có tùy chọnnpm install -g deno, mà npm ít nhất vẫn có kiểm tra tính toàn vẹn tệp và quét mã độc đơn giản nên tương đối an toàn hơn. Website deno.land dù có an toàn ở mức codebase đi nữa thì ở khía cạnh vận hành cũng không thể đảm bảo 100%, nên tôi cho rằngcurl | shkhông phải thông lệ bảo mật tốtTôi không đồng tình với lập luận này. Phần lớn script cài đặt rốt cuộc cũng chỉ làm nhiệm vụ tải về và chạy một binary dài từ vài trăm đến vài triệu dòng do cùng một tác giả tạo ra. Nếu bạn hoàn toàn không tin tác giả đến mức giả định máy chủ có thể phát tán mã độc chỉ cho một số IP nhất định, thì ở cấp độ binary họ cũng hoàn toàn có thể cài mã độc, vậy ngay từ đầu bạn đã không nên dùng dự án đó. Có lẽ tranh luận
curl | shlan rộng vì đây là một lập luận dễ nói và dễ lặp lại, trong khi vấn đề bảo mật thực sự lại nằm ở việc review hàng triệu dòng mã. Còn nếu bạn lo cả tấn công MITM từ cơ quan nhà nước, thì rốt cuộc chỉ còn cách cắt hết niềm tin từ Internet bên ngoàiCó chỉ ra rằng onboarding người dùng mới cũng gặp khó khăn. Dù khuyên dùng npm thì trước hết vẫn phải cài npm, mà website chính thức của npm lại hướng dẫn cài nvm, còn nvm thì cũng dùng
curl | sh. Thành ra đường tiếp cận qua npm rốt cuộc cũng gián tiếp gặp cùng một vấn đềTrong tranh luận liệu
npm install -g denocó thực sự an toàn hơncurl | shhay không, điểm cốt lõi là: giữa máy chủ npm và máy chủ riêng, bên nào dễ bị hacker xâm nhập hơn? Nếu có thể chắc chắn không phải do máy chủ riêng bị xâm nhập thì cũng không có lý do gì để nóicurl | shkém an toàn hơnnpm install. Rốt cuộc dưới góc nhìn bảo mật thì cả hai cách đều có thể mong manh như nhau, nên nếu đẩy tới cực đoan thì bản thân việc dùng Internet mới là vấn đềCó chỉ trích rằng cách Deno triển khai sandbox mang cảm giác như công nghệ của thập niên 90, và việc sử dụng nó không hẳn là một thói quen bảo mật tốt
Tôi tò mò không biết đã từng có trường hợp tấn công thực tế nào thành công với kiểu cài đặt
curl | shhay chưa