Bối cảnh hiện tại của công cụ web ngày càng phức tạp hơn bao giờ hết. Chúng ta có các thư viện như Solid, Vue, Svelte, Angular, React và các thư viện khác xử lý các bản cập nhật UI (Giao diện người dùng) theo cách tiện dụng. Chủ đề ngày càng quan trọng đối với các nhà phát triển là sự cân bằng và đánh đổi giữa các biện pháp thực hành tốt nhất về hiệu suất và khả năng sử dụng.
Các nhà phát triển cũng đang làm mờ ranh giới giữa mã front-end và back-end. Cách chúng ta đặt logic và dữ liệu cùng nhau trở nên thú vị hơn khi chúng ta tích hợp và kết hợp cách chúng hoạt động cùng nhau để mang lại trải nghiệm ứng dụng thống nhất.
Với những thay đổi về ý thức hệ này, các siêu khuôn khổ đã phát triển xung quanh các thư viện cốt lõi theo những cách độc đáo. Để đóng gói các mô hình mà UI được hiển thị và tạo khả năng tương tác liền mạch giữa mã máy chủ và mã trình duyệt của chúng tôi, các phương pháp mới đang nổi lên.
Mặc dù ý tưởng ban đầu về việc có một khuôn khổ "siêu" là ghép các bộ công cụ khác nhau lại với nhau để xây dựng trải nghiệm mượt mà, nhưng rất khó để tạo ra các tích hợp mà không đưa ra một số quyết định có ý kiến ở mức độ nào đó. Vì vậy, các khuôn khổ như QwikCity, SvelteKit, Redwood và Next.js đã đi sâu vào lãnh thổ có ý kiến riêng của chúng và cung cấp một đường ray cứng để đảm bảo một tập hợp các quy ước được xác định.
Trong khi đó, những khuôn khổ khác như Nuxt, Remix và Analog vẫn giữ nguyên mức độ trừu tượng nông hơn của các tích hợp của chúng, cho phép kết hợp các công cụ của chúng và dễ dàng sử dụng các tài nguyên từ cộng đồng hơn (Vite là một ví dụ điển hình về một công cụ được tất cả chúng sử dụng một cách nông).
Điều này không chỉ tạo ra sự ràng buộc thấp hơn với nhà cung cấp đối với các nhà phát triển mà còn cho phép cấu hình được sử dụng lại trong một số trường hợp vì các quyết định như vậy bị loại bỏ khỏi các ý kiến để ủng hộ các mức độ trừu tượng mạnh hơn. SolidStart tiến một bước dài vượt ra ngoài đó vào lãnh thổ không thiên vị. Lõi của riêng nó là khoảng 1500 dòng mã và các phần chức năng lớn nhất được cung cấp với sự kết hợp của các công cụ tích hợp tốt.
Kiến trúc tách rời hỗ trợ các khung mới hơn cũng trao quyền cho nhà phát triển để có trải nghiệm gỡ lỗi tốt hơn trong và ngoài cộng đồng của mình. Nếu gặp sự cố trên máy chủ, bạn không bị giới hạn bởi kiến thức về một khuôn khổ cụ thể.
Ví dụ, vì cả hai đều dựa trên Nitro, nên cộng đồng Analog và SolidStart hiện có thể chia sẻ kiến thức với nhau. Ngoài ra, vì tất cả đều dựa trên Nitro và Vite, Nuxt, Analog và SolidStart có thể triển khai trên cùng một nền tảng và chia sẻ thông tin chi tiết về triển khai để mỗi hệ sinh thái cùng phát triển. Cộng đồng sẽ chiến thắng với cách tiếp cận này và các nhà phát triển thư viện/khung cũng chiến thắng. Đây là một mô hình và cách tiếp cận hoàn toàn mới để cùng nhau chia sẻ gánh nặng bảo trì meta-framework (một trong những trách nhiệm đáng sợ nhất của người bảo trì).

Nó sử dụng JSX và có cú pháp rất giống với React, nhưng bên trong, nó hoạt động theo một cách hoàn toàn khác. Đưa nhà phát triển đến gần DOM hơn trong khi vẫn cung cấp công thái học cần thiết để làm việc hiệu quả trong môi trường nhà phát triển. Với kích thước gói chỉ 3Kb, nó thường là lựa chọn ngay cả đối với hầu hết các trang web tĩnh. Ví dụ: nhiều người sử dụng Solid để mang lại tính tương tác cho các trang web Astro dựa trên nội dung của họ khi cần.
Solid cũng mang đến các nguyên mẫu hạng nhất, các thành phần Control Flow tích hợp, quản lý trạng thái chất lượng cao và hỗ trợ TypeScript đầy đủ. Solid đóng gói một cú đấm trong một gói nhỏ hiệu quả.
Ngoài sự phổ biến của nó, nó đặc biệt được yêu thích vì thời gian khởi động máy chủ nhanh, hỗ trợ HMR, bản dựng được tối ưu hóa, dễ cấu hình, hệ sinh thái plug-in phong phú, công cụ hiện đại và trải nghiệm tổng thể chất lượng cao của nhà phát triển.
Hãy coi Nitro như một tiện ích mở rộng bổ sung giúp Vite dễ xây dựng hơn và linh hoạt hơn. Nó giải quyết phần lớn các mối quan tâm về cấp độ thời gian chạy cần được giải quyết trong Vite.
Ví dụ:
Vì các tuyến tài nguyên hoạt động như một thùng, nên bằng cách định nghĩa
Vinxi sẽ tận dụng đúng bộ API từ Nitro và Vite để tài nguyên của bạn không bị tiếp xúc với thời gian chạy sai và để việc triển khai diễn ra suôn sẻ cho các nhà cung cấp nền tảng được xác định.
Tất cả các API này đều được hỗ trợ bởi một thư viện độc lập khác có tên là Seroval. Để gửi dữ liệu giữa máy chủ và máy khách theo cách an toàn, tất cả dữ liệu cần được tuần tự hóa. Seroval tự định nghĩa theo cách quá đơn giản: “Stringify JS Values”. Tuy nhiên, định nghĩa này không đề cập đến thực tế là nó thực hiện theo cách cực kỳ mạnh mẽ và nhanh chóng.
Nhờ Seroval, SolidStart có thể vượt qua ranh giới tuần tự hóa một cách an toàn và hiệu quả. Tuần tự hóa tài nguyên có thể được coi là tính năng quan trọng nhất của một khuôn khổ full-stack — nếu không có nó, cầu nối back-end và front-end sẽ không hoạt động trơn tru.
Bên cạnh tuần tự hóa tài nguyên, SolidStart cũng có thể sử dụng hành động máy chủ. Ngay từ tài liệu, đây là cách các hành động máy chủ trông như thế nào đối với chúng tôi (lưu ý chỉ thị

Hy vọng rằng bài tập nhỏ này về việc tách rời khuôn khổ và lắp lại các bộ phận với nhau sẽ thú vị và sâu sắc. Hãy cho tôi biết trong phần bình luận bên dưới hoặc trên X nếu điều này giúp bạn hiểu rõ hơn hoặc thậm chí chọn được các công cụ cho dự án tiếp theo của mình.
Các nhà phát triển cũng đang làm mờ ranh giới giữa mã front-end và back-end. Cách chúng ta đặt logic và dữ liệu cùng nhau trở nên thú vị hơn khi chúng ta tích hợp và kết hợp cách chúng hoạt động cùng nhau để mang lại trải nghiệm ứng dụng thống nhất.
Với những thay đổi về ý thức hệ này, các siêu khuôn khổ đã phát triển xung quanh các thư viện cốt lõi theo những cách độc đáo. Để đóng gói các mô hình mà UI được hiển thị và tạo khả năng tương tác liền mạch giữa mã máy chủ và mã trình duyệt của chúng tôi, các phương pháp mới đang nổi lên.
Mặc dù ý tưởng ban đầu về việc có một khuôn khổ "siêu" là ghép các bộ công cụ khác nhau lại với nhau để xây dựng trải nghiệm mượt mà, nhưng rất khó để tạo ra các tích hợp mà không đưa ra một số quyết định có ý kiến ở mức độ nào đó. Vì vậy, các khuôn khổ như QwikCity, SvelteKit, Redwood và Next.js đã đi sâu vào lãnh thổ có ý kiến riêng của chúng và cung cấp một đường ray cứng để đảm bảo một tập hợp các quy ước được xác định.
Trong khi đó, những khuôn khổ khác như Nuxt, Remix và Analog vẫn giữ nguyên mức độ trừu tượng nông hơn của các tích hợp của chúng, cho phép kết hợp các công cụ của chúng và dễ dàng sử dụng các tài nguyên từ cộng đồng hơn (Vite là một ví dụ điển hình về một công cụ được tất cả chúng sử dụng một cách nông).
Điều này không chỉ tạo ra sự ràng buộc thấp hơn với nhà cung cấp đối với các nhà phát triển mà còn cho phép cấu hình được sử dụng lại trong một số trường hợp vì các quyết định như vậy bị loại bỏ khỏi các ý kiến để ủng hộ các mức độ trừu tượng mạnh hơn. SolidStart tiến một bước dài vượt ra ngoài đó vào lãnh thổ không thiên vị. Lõi của riêng nó là khoảng 1500 dòng mã và các phần chức năng lớn nhất được cung cấp với sự kết hợp của các công cụ tích hợp tốt.
Mô-đun trên khối đơn
Động lực đằng sau việc tách rời hoàn toàn kiến trúc là trao quyền cho nhà phát triển sử dụng để chọn khung và xây dựng theo mong muốn của họ. Một nhà phát triển có thể muốn sử dụng Solid và SSR, nhưng hãy tưởng tượng mã cũ có sự phụ thuộc chặt chẽ vào TanStack Router, trong khi SolidStart và hầu hết các dự án Solid đều có Solid-Router thay thế. Với kiến trúc tách rời, có thể tạo lớp áp dụng gia tăng hoặc lớp tích hợp để mọi thứ sẽ hoạt động theo lợi ích tốt nhất của nhóm.Kiến trúc tách rời hỗ trợ các khung mới hơn cũng trao quyền cho nhà phát triển để có trải nghiệm gỡ lỗi tốt hơn trong và ngoài cộng đồng của mình. Nếu gặp sự cố trên máy chủ, bạn không bị giới hạn bởi kiến thức về một khuôn khổ cụ thể.
Ví dụ, vì cả hai đều dựa trên Nitro, nên cộng đồng Analog và SolidStart hiện có thể chia sẻ kiến thức với nhau. Ngoài ra, vì tất cả đều dựa trên Nitro và Vite, Nuxt, Analog và SolidStart có thể triển khai trên cùng một nền tảng và chia sẻ thông tin chi tiết về triển khai để mỗi hệ sinh thái cùng phát triển. Cộng đồng sẽ chiến thắng với cách tiếp cận này và các nhà phát triển thư viện/khung cũng chiến thắng. Đây là một mô hình và cách tiếp cận hoàn toàn mới để cùng nhau chia sẻ gánh nặng bảo trì meta-framework (một trong những trách nhiệm đáng sợ nhất của người bảo trì).
SolidStart chính xác là gì?
SolidStart được xây dựng từ năm trụ cột cơ bản:- Solid: thư viện chế độ xem cung cấp các trừu tượng kết xuất.
- Vite (trong Vinxi): trình đóng gói để tối ưu hóa mã để thực thi trong các thời gian chạy khác nhau.
- Nitro (trong Vinxi): máy chủ web độc lập do nhóm Nuxt tạo ra và dựa trên h3 với Rollup.
- Vinxi: trình điều phối, xác định thời gian chạy và mã ở đâu mỗi cái đều có.
- Seroval: trình tuần tự hóa dữ liệu sẽ kết nối dữ liệu từ máy chủ đến trình duyệt và ngược lại.

1. Solid
Solid là một thư viện dựng hình ngày càng trở nên phổ biến vì hiệu suất dựng hình đáng kinh ngạc và lớp trừu tượng mỏng. Nó được xây dựng trên Signals, một triển khai hiện đại và đổi mới của Observer Pattern cổ điển, đồng thời cung cấp một loạt các trình trợ giúp để trao quyền cho nhà phát triển tạo ra mã cực kỳ hiệu suất cao và dễ đọc.Nó sử dụng JSX và có cú pháp rất giống với React, nhưng bên trong, nó hoạt động theo một cách hoàn toàn khác. Đưa nhà phát triển đến gần DOM hơn trong khi vẫn cung cấp công thái học cần thiết để làm việc hiệu quả trong môi trường nhà phát triển. Với kích thước gói chỉ 3Kb, nó thường là lựa chọn ngay cả đối với hầu hết các trang web tĩnh. Ví dụ: nhiều người sử dụng Solid để mang lại tính tương tác cho các trang web Astro dựa trên nội dung của họ khi cần.
Solid cũng mang đến các nguyên mẫu hạng nhất, các thành phần Control Flow tích hợp, quản lý trạng thái chất lượng cao và hỗ trợ TypeScript đầy đủ. Solid đóng gói một cú đấm trong một gói nhỏ hiệu quả.
2. Vite
Có thể nói là bundler tốt nhất trong hệ sinh thái JavaScript, Vite có sự cân bằng phù hợp giữa cấu hình khai báo và cấu hình tùy chỉnh. Nó hoàn toàn dựa trên TypeScript, giúp dễ dàng mở rộng bằng thư viện hoặc khuôn khổ sử dụng và có lượng người dùng đủ lớn đảm bảo tính linh hoạt của nó. Vite hoạt động với và đã trở thành công cụ thực tế cho nhiều khuôn khổ, chẳng hạn như Astro, Vue, Preact, Elm, Lit, Svelte, Nuxt, Analog, Remix và nhiều khuôn khổ khác.Ngoài sự phổ biến của nó, nó đặc biệt được yêu thích vì thời gian khởi động máy chủ nhanh, hỗ trợ HMR, bản dựng được tối ưu hóa, dễ cấu hình, hệ sinh thái plug-in phong phú, công cụ hiện đại và trải nghiệm tổng thể chất lượng cao của nhà phát triển.
3. Nitro
Bản thân là một khuôn khổ, Nitro được viết bằng TypeScript và hoàn toàn độc lập và mở cho mọi siêu khuôn khổ sử dụng làm nền tảng. Nó cung cấp một bộ công cụ và API mạnh mẽ để quản lý bộ nhớ đệm, tuyến đường và rung cây. Đây là cơ sở nhanh chóng để bất kỳ dự án nào dựa trên JavaScript xây dựng máy chủ của họ. Nitro có khả năng mở rộng cao, tích hợp dễ dàng vào các đường ống DevOps và CI/CD, tập trung vào bảo mật, mạnh mẽ và tự hào có một bộ bộ điều hợp phong phú, khiến nó có thể triển khai trên hầu hết, nếu không muốn nói là tất cả, các nền tảng của nhà cung cấp chính.Hãy coi Nitro như một tiện ích mở rộng bổ sung giúp Vite dễ xây dựng hơn và linh hoạt hơn. Nó giải quyết phần lớn các mối quan tâm về cấp độ thời gian chạy cần được giải quyết trong Vite.
4. Vinxi
Vinxi là một SDK (Bộ phát triển phần mềm) mang đến một bộ công cụ mạnh mẽ dựa trên cấu hình để tạo các ứng dụng đầy đủ. Nó tạo Nitro dưới mui xe để thiết lập một máy chủ web và tận dụng Vite cho các thành phần đóng gói. Nó được lấy cảm hứng từ Bun App API và hoạt động thông qua một giao diện rất khai báo để khởi tạo một ứng dụng bằng cách thiết lập bộ định tuyến cho mỗi thời gian chạy.Ví dụ:
Mã:
import { createApp } from "vinxi";import solid from "vite-plugin-solid";const resources = { name: "public", mode: "static", dir: "./public",};const spa = { name: "client", mode: "build", handler: "./app/client.tsx", target: "browser", plugins: () => [solid({ ssr: true })], base: "/_build"}const server = { name: "ssr", mode: "handler", handler: "./app/server.tsx", target: "server", plugins: () => [solid({ ssr: true })],}export default createApp({ routers: [resources, spa, server],});
mode: "static"
, không cần phải định nghĩa trình xử lý. Bộ định tuyến của bạn cũng có thể được xây dựng tĩnh (mode: “build”
) và hướng đến thời gian chạy của trình duyệt hoặc có thể nằm trên máy chủ và xử lý từng yêu cầu thông qua handler điểm vào của nó: "./app/server.tsx"
.Vinxi sẽ tận dụng đúng bộ API từ Nitro và Vite để tài nguyên của bạn không bị tiếp xúc với thời gian chạy sai và để việc triển khai diễn ra suôn sẻ cho các nhà cung cấp nền tảng được xác định.
5. Seroval
Sau khi bộ định tuyến được thiết lập và ứng dụng có thể xử lý điều hướng (điều hướng cứng thông qua trình xử lý "ssr" và điều hướng mềm thông qua trình xử lý "client"), đã đến lúc ghép chúng lại với nhau. Đây là phần mà lõi của SolidStart phát huy tác dụng. Nó cung cấp các API cung cấp tính công thái học để lấy và thay đổi các yêu cầu.Tất cả các API này đều được hỗ trợ bởi một thư viện độc lập khác có tên là Seroval. Để gửi dữ liệu giữa máy chủ và máy khách theo cách an toàn, tất cả dữ liệu cần được tuần tự hóa. Seroval tự định nghĩa theo cách quá đơn giản: “Stringify JS Values”. Tuy nhiên, định nghĩa này không đề cập đến thực tế là nó thực hiện theo cách cực kỳ mạnh mẽ và nhanh chóng.
Nhờ Seroval, SolidStart có thể vượt qua ranh giới tuần tự hóa một cách an toàn và hiệu quả. Tuần tự hóa tài nguyên có thể được coi là tính năng quan trọng nhất của một khuôn khổ full-stack — nếu không có nó, cầu nối back-end và front-end sẽ không hoạt động trơn tru.
Bên cạnh tuần tự hóa tài nguyên, SolidStart cũng có thể sử dụng hành động máy chủ. Ngay từ tài liệu, đây là cách các hành động máy chủ trông như thế nào đối với chúng tôi (lưu ý chỉ thị
"use server"
cho phép Vinxi đặt mã vào đúng vị trí.
Mã:
import { action, redirect } from "@solidjs/router";const isAdmin = action(async (formData: FormData) => { "use server"; await new Promise((resolve, reject) ==> setTimeout(resolve, 1000)); const username = formData.get("username"); if (username === "admin") throw redirect("/admin"); return new Error("Invalid username");});export function MyComponent() { return ( Username: );}
Mọi thứ đều kết hợp lại với nhau
Sau sự cố này, mọi thứ vẫn có thể còn chưa chắc chắn. Vậy, chúng ta hãy khép lại vòng lặp bằng cách lắp ráp các bộ phận:
Hy vọng rằng bài tập nhỏ này về việc tách rời khuôn khổ và lắp lại các bộ phận với nhau sẽ thú vị và sâu sắc. Hãy cho tôi biết trong phần bình luận bên dưới hoặc trên X nếu điều này giúp bạn hiểu rõ hơn hoặc thậm chí chọn được các công cụ cho dự án tiếp theo của mình.