Xây dựng website mà không cần framework và nhiều thư viện
(kodingkitty.com)- Koding Kitty áp dụng stack tập trung vào HTML tĩnh cho website công ty nhỏ, nhờ đó vẫn vận hành được các trang cần thiết và blog mà không cần CMS lớn hay framework
- Tiêu chí lựa chọn là tốc độ, thuận tiện khi phát triển, hosting rẻ, độ phức tạp thấp; WordPress, no-code, framework và Jamstack đều có gánh nặng thiết lập và học tập lớn hơn so với nhu cầu
- Nội dung được viết trực tiếp bằng HTML thay vì Markdown hay trình soạn thảo trực quan, giúp dễ xử lý các bài viết trộn giữa văn bản và widget HTML/CSS/JS
- Các cấu trúc lặp và khối dùng chung được xử lý bằng template Jinja, còn script Python 45 dòng nối việc phát hiện thay đổi, render HTML và gọi Tailwind CSS CLI
- Vì là site tĩnh nên chỉ cần hosting giá rẻ; Hetzner webhosting bắt đầu từ 2 EUR và vẫn chịu được đợt tăng vọt lưu lượng khi lên trang nhất Hacker News
Vì sao chọn một stack đơn giản
- Stack công nghệ cho website của Koding Kitty được xây dựng theo hướng cố ý đơn giản, thay vì chạy theo xu hướng phát triển web hạng nhẹ gần đây, để phù hợp với nhu cầu thực tế
- Mục tiêu là một cấu hình ít ma sát cho lập trình viên, và họ cho rằng một giải pháp đơn giản có thể tốt hơn cho khách hàng so với tổ hợp framework và thư viện phức tạp
- Thiết kế khác biệt nhưng không quá đà có thể được tạo bằng nhiều cách, nhưng cấu hình hiện tại là lựa chọn phù hợp với đúng phạm vi cần thiết
Yêu cầu và tiêu chí ban đầu
- Ngay từ đầu đã quyết định làm website tĩnh
- Chức năng cần có chỉ gồm trang chủ, showcase và blog, ngoài ra không nhiều
- Có bốn tiêu chí
- website nhanh
- phát triển nhanh
- hosting rẻ
- độ phức tạp tối thiểu
Các lựa chọn đã xem xét nhưng loại bỏ
-
WordPress và các CMS tương tự
- Họ thừa nhận WordPress đã đóng vai trò lớn trên Internet
- Nhưng với nhu cầu khiêm tốn thì nó là quá mức cần thiết
- Không cần lưu nội dung vào cơ sở dữ liệu, cũng không cần plugin hay trình soạn thảo trực quan
-
Công cụ no-code
- Một người viết web dùng công cụ no-code đem lại cảm giác gượng gạo
- Họ muốn trực tiếp sở hữu nội dung và kiểm soát website theo ý mình
- Họ cho rằng làm bằng code còn nhanh hơn trình soạn thảo WYSIWYG no-code
- Gánh nặng học ban đầu và học liên tục cũng là điều đáng ngại
-
Framework
- Họ có kinh nghiệm với framework nhưng không muốn mang cả bộ thiết lập vào
- Cơ sở dữ liệu, cấu hình, thư viện, tính năng quản trị và các thành phần khác có thể trở nên quá nhiều
- Dù có thể tùy biến hoàn toàn, cuối cùng nó vẫn có thể thành ra giống WordPress
-
Jamstack và trình tạo site tĩnh
- Trình tạo site tĩnh thoạt nhìn là lựa chọn khá hợp với yêu cầu
- Có thể chọn ngôn ngữ, viết code rồi tạo site tĩnh nhanh bằng nút bấm hoặc script
- Tuy vậy vẫn cần thiết lập ban đầu và học cả lúc đầu lẫn về sau
- Họ công nhận sự tiện lợi của việc viết blog bằng Markdown, nhưng nhìn chung vẫn chọn giải pháp đơn giản hơn
Cấu hình KittyStack
- Cấu hình của Koding Kitty được tổ chức xoay quanh bốn yêu cầu nói trên
-
Website nhanh
- Website tĩnh chạy nhanh
-
Phát triển nhanh
- Nội dung được viết bằng HTML thay vì Markdown hay trình soạn thảo cao cấp
- Các bài viết của Koding Kitty trộn văn bản với widget HTML/CSS/JS nên viết trực tiếp bằng HTML là phù hợp
-
Hosting rẻ
- Chi phí hosting cho site tĩnh thay đổi tùy nhà cung cấp và các tính năng bổ sung cần thiết
- Site tĩnh không cần cấu hình phần cứng lớn nên có thể chọn mức cấu hình tối thiểu
- Hetzner webhosting bắt đầu từ 2 EUR
- Website của Koding Kitty vẫn chịu được mức tăng lưu lượng kiểu lên trang nhất Hacker News
-
Độ phức tạp tối thiểu
- Một số trang và bài viết có các mẫu lặp lại
- Có thể copy-paste, nhưng theo thời gian sẽ khó kiểm soát
- Họ cần vòng lặp và khả năng chèn các khối code như header, footer
Jinja và luồng build
- Các cấu trúc lặp và việc chèn file dùng chung được xử lý bằng template Jinja
- Jinja cung cấp vòng lặp, chèn file như thanh điều hướng và footer, cùng các tính năng template khác
- Nhóm từng dùng framework dựa trên Jinja trước đây nên không cần học một hệ thống mới
Chuỗi công cụ đơn giản
- Các trang tĩnh cuối cùng được tạo bằng script Python 45 dòng
- Đây là số dòng tính cả chú thích và dòng trống
- Luồng build như sau
- Lập trình viên sửa
index.src.html Watchdog.pyphát hiện thay đổi file- Render template Jinja thành
index.html - Gọi Tailwind CSS CLI để tạo
styles.min.css
- Lập trình viên sửa
- Trong lúc phát triển, Live Server phục vụ file và tự reload khi có thay đổi
- Khi triển khai, file được upload thủ công qua FTP
Lợi ích của phát triển web ít phức tạp hơn
- Phát triển web có thể được giữ đơn giản mà không phải đánh đổi quá nhiều
- Giới hạn lựa chọn xuống chỉ còn vài thứ đôi khi lại đem đến cảm giác tự do hơn
- Với nhiều khách hàng, một giải pháp nhanh hơn, đơn giản hơn và rẻ hơn có thể hữu ích hơn
- Cần nhìn rộng ra toàn bộ web để đánh giá xem có thể đạt cùng kết quả với stack công nghệ ít phức tạp hơn hay không
1 bình luận
Ý kiến trên Hacker News
Tôi cũng đã ổn định với cách tiếp cận tương tự cho portfolio ảnh. Chuyển từ làm phát triển sang nhiếp ảnh, điểm hay là không phải phụ thuộc vào Squarespace như nhiều nhiếp ảnh gia khác
Sau khi thử nhiều lựa chọn chạy trên máy chủ như Ghost, Statamic, Phoenix/Vapor và nhiều trình tạo trang tĩnh phổ biến, cuối cùng tôi quay về viết HTML thuần không dùng template rồi dùng rsync để đưa lên máy chủ Hetzner
Việc không có template cho các UI dùng chung như điều hướng có hơi khó chịu, nhưng đến giờ vẫn chưa có thay đổi nào mất quá vài phút bằng regex, và lần đầu tôi từng làm mất nội dung vì regex tham lam thì git đã cứu tôi
Việc tạo các biến thể ảnh theo kích thước và định dạng hơi phiền, nhưng đổi lại nó giúp tôi thử các bố cục mới mà không phải dựa vào layout đóng khung như Ghost. Ngoài ra, khi xuất ảnh cho web, chất lượng từ trình chỉnh sửa RAW Capture One có vẻ cũng nhỉnh hơn một chút so với thư viện hay công cụ CLI mà đa số trình tạo trang tĩnh dùng
Dù chậm hơn, tôi thấy nó gần với việc làm một cuốn sách ảnh hơn. Ban đầu tốn công hơn, nhưng làm xong là xong, và trong 20 năm tới không cần phải chuyển qua lại giữa đủ loại CMS rồi làm hỏng mọi thứ
Về cơ bản nó chỉ là vài file HTML được tăng sức mạnh bằng template; ảnh được lấy qua Flickr API từ một album dành riêng cho trang này, còn Netlify thì tự động triển khai chỉ với
git pushTổng chi phí, gồm cả hosting, là 0 đô la; tôi cũng có thể quản lý ảnh từ điện thoại bằng ứng dụng Flickr. Nhờ Netlify nên tôi cũng thích ở chỗ không phải đụng vào máy chủ thực tế
Cách tôi dùng gần đây có thể cũng hữu ích(https://news.ycombinator.com/item?id=36592641). Dùng Google Sheet làm nguồn dữ liệu rất dễ, và nếu đổi sang hệ thống file ảnh chắc cũng tương tự
Cái này không hẳn là ‘đơn giản(simple)’, mà có vẻ gần với kiểu trông đơn giản nhưng thực ra sơ sài(simplistic) hơn. Nếu không làm gì nhiều và gọt bớt các góc cạnh, bạn có thể tạo ra một trang web tương đối đơn giản
Chỉ nhìn vào dark mode, gần như là tính năng không tầm thường duy nhất thấy được trên trang này, thì nó được xử lý bằng JS tải trì hoãn nên mỗi lần tải trang đều có nháy màn hình trắng không thể tránh khỏi. Muốn làm đúng thì phải dùng cách body class trong CSS; một giải pháp không hoạt động thì dù đơn giản hay phức tạp cũng vô nghĩa
Thêm nữa, chỉ để có 3 dòng JS cho localStorage và thiết lập dark mode mà lại kéo cả trình thông dịch ‘hyperscript’ tùy biến như https://hyperscript.org/ thì đi ngược hẳn tinh thần “đơn giản là đỉnh cao của sự hoàn thiện”. Tải một thư viện 96KB chưa được cache chỉ cho mục đích đó là rất kỳ, và tôi cũng tự hỏi việc HTML không vượt qua kiểm tra có phải vì thế không
Cuối cùng, một công tắc nhị phân là cách triển khai dark mode tệ vì nó bỏ qua thiết lập hệ thống/trình duyệt. Dù bật dark mode trong hệ điều hành điện thoại, người dùng vẫn sẽ thấy light mode cho đến khi tự tay bật lên, và nó cũng không tôn trọng các thiết lập hệ thống thay đổi theo thời gian hay ánh sáng xung quanh. localStorage có thể hết hạn và người dùng cũng đổi thiết bị, nên họ sẽ phải thiết lập lại nhiều lần; vì vậy rất có thể người dùng không đồng ý với cái mà lập trình viên gọi là triển khai ‘đơn giản’
Nếu tính đến thiết lập hệ thống/trình duyệt, chuyển đổi theo múi giờ, ánh sáng xung quanh v.v. thì độ phức tạp sẽ tăng lên và xung đột với triết lý web đơn giản. Tốt hơn là bỏ dark mode đi; HN cũng luôn là light mode nhưng đọc ban đêm vẫn không có vấn đề lớn
Thường thì bạn muốn vừa tôn trọng
prefers-color-schemevừa cung cấp nút chuyển, và nếu người dùng từng tự chọn trên trang thì lại muốn ưu tiên lựa chọn đó. Khi ấy vẫn cần JS và localStorageCách tôi thích là dùng style nội tuyến với
body {visibility: hidden; opacity: 0;}. Có thể giữ nguyên trang trước đó, rồi tại thời điểmDOMContentLoadedkiểm traprefers-color-schemevà localStorage, đặt đúng body class rồi mới cho trang hiển thịTrang của tôi dùng CSS để tôn trọng theme sáng/tối và không có chuyển đổi thủ công. Mục tiêu cá nhân của tôi là một website HTML/CSS thuần không có JS, và tôi cho rằng thiết lập sáng/tối nên tôn trọng lựa chọn của người dùng. Nếu cần nút chuyển thì nó nên nằm ở thanh công cụ trình duyệt chứ không phải trong trang
Nếu /u/gwern có đọc được, thì trang của tôi https://daveon.design/ chịu ảnh hưởng từ thiết kế của gwern và Tufte.css. Nó cũng pha trộn các ấn phẩm cũ, bản thảo chép tay và sở thích cá nhân, nhưng gwern là ví dụ cốt lõi đầu tiên truyền cảm hứng cho tôi về việc một website cá nhân hiện đại, gọn gàng có thể trông như thế nào và có thể chứa đựng điều gì
Nói cho đúng thì hiện tại SvelteKit + Skeleton thực sự rất ấn tượng về tốc độ tạo ra một bản prototype dùng được
Dù không hiểu sâu về Svelte, chỉ cần nắm được routing dựa trên file là phần còn lại gần như chỉ là HTML cho đến khi thực sự cần tới, Tailwind được tích hợp sẵn và theme cũng nhìn chung khá gần với vanilla
Trong vài tháng gần đây tôi đã thử Astro, Lit, Next.js, template tích hợp sẵn của Go, pug, Eleventy và nhiều thứ khác, nhưng cho đến lúc này thì đây vẫn là tổ hợp tôi thích nhất ở gần như mọi mặt
Chỉ cần nhìn ngay trang của Skeleton https://www.skeleton.dev/docs/get-started là thấy: bấm Page Down không cuộn được, rê chuột lên thanh điều hướng cũng không cuộn được, và khi in thì chỉ phần đang thấy trên màn hình bị cắt ra. Tôi đã nêu vấn đề này, nhưng dù chưa phải ưu tiên lớn thì vẫn có rất nhiều website đang dùng kiểu pattern component này
Có vẻ Skeleton cho rằng chỉ cần đảo màu theme tối là sẽ thành một theme sáng ổn, nhưng thực tế không phải vậy. DaisyUI trưởng thành hơn, hiệu năng tốt hơn, được dùng rộng rãi hơn và xử lý accessibility một cách nghiêm túc. Việc nó làm được bằng animation CSS mà không cần JS cũng rất ấn tượng, đồng thời giải quyết phần HTML/CSS khó trong khi để bạn tự viết phần Svelte vốn dễ hơn. Mức độ phụ thuộc vào Svelte cũng thấp nên HTML của DaisyUI rất dễ chuyển sang framework khác
Tailwind hoạt động ngay lập tức, và việc deploy lên những nơi như Netlify cũng cực kỳ đơn giản. Theo tiêu chuẩn hiện tại thì đây là trình dựng site tĩnh tốt nhất, và tôi thấy nó đơn giản hơn rất nhiều so với cách bài viết mô tả
Dùng
+page.tscùng cấu hình phù hợp thì cũng có thể làm website tĩnh, đồng thời có thể phát triển thành ứng dụng nhiều trang hoặc ứng dụng một trangTrời đất, làm website bằng HTML và CSS nghe đúng là điên rồ
Nói đùa vậy thôi, ngoài phần template ra thì tôi dùng cùng một stack. Nếu không phải web developer thì tôi không hiểu lắm sự cần thiết của CSS framework, và tự làm còn dễ hơn nhiều. Tôi cũng đã thử Hugo làm site generator nhưng không tiết kiệm được chút thời gian nào
Vài tháng trước, để nâng trình CSS, tôi đã thử dựng lại website của một vài công ty, và chỉ với HTML và CSS thì đều có thể tái tạo được phần giao diện. Thế nhưng website thật của các công ty đó thì khi tắt JS lại còn không hiện ra nổi
Chúng ta cứ tiếp tục chồng framework lên framework, thêm ngôn ngữ mới, thêm công cụ mới, và phần lớn chỉ làm tăng độ phức tạp cùng lượng việc bận rộn cho thế hệ sau. 5% website thật sự cần những thứ đó là ngoại lệ
Việc đây là một site bán dịch vụ thật cũng khá thú vị, và tôi cũng tò mò mức giá của nó ra sao
Tôi nghĩ cách tối giản mà vẫn hiệu quả nhất là cứ dùng PHP. Ngôn ngữ đó vốn được tạo ra cho đúng mục đích này
Với một site đơn giản thì không cần composer hay logic router gì cả, chỉ cần tách riêng file header/footer/navigation rồi include chúng trong từng trang
header.php,pagename.php,footer.php. Với site đơn giản thì tôi làm như vậy, rất dễ và rất nhanhNếu HTML có thể chèn HTML bên ngoài như CSS hay JS thì ngay cả việc này phần lớn cũng không cần thiết. Chỉ cần cho phép dùng linh hoạt là được
Chỉ cần sửa gì đó rồi git commit/push là trong chưa tới 30 giây, thay đổi sẽ được cập nhật trên toàn thế giới. Khá tuyệt, và cũng không cần hosting server riêng
Câu “hãy làm nó đơn giản nhất có thể, nhưng không đơn giản hơn” làm tôi nhớ đến. Có lẽ không phải câu của Albert Einstein
HTML + CSS thuần, kiểu nhét CSS vào từng thẻ HTML hoặc ngay trong trang thì ổn để bắt đầu. Khi trang tăng lên thành hai thì thường sẽ tách CSS ra file riêng
Nhưng khi bắt đầu làm một site có nhiều trang cùng định dạng, bạn sẽ cần một hệ thống template có include và trình tạo trang tĩnh
Nếu trang dựa trên dữ liệu, bạn sẽ cần một trình tạo site có thể lập trình để nhận dữ liệu và xuất ra trang; còn nếu dữ liệu là “thời gian thực”, bạn sẽ phải tạo trang cho từng view, nên ít nhất sẽ bước sang vùng của PHP, xa hơn nữa là vùng của các web framework hiện đại có server chạy thường trực
Gần đây tôi làm một site phi lợi nhuận theo sở thích. Đó là site quảng bá nhảy múa và sự kiện, chủ sở hữu là một giáo viên dạy nhảy không rành kỹ thuật. Tôi dùng Eleventy(https://www.11ty.dev/) để tạo site tĩnh trên gói miễn phí của Netlify, rồi gắn thêm mã build tùy chỉnh để lấy dữ liệu từ Google Sheet nhằm cho phép cô giáo định nghĩa các sự kiện sắp tới
Mất hơn chục giờ để làm, nhưng giờ nó chạy tốt mà không có chi phí vận hành/quản trị. Tôi nhận ra có một điểm ngọt rất mạnh giữa cấu hình tối giản tuyệt đối và mức Rails/Phoenix/Django
Tuy vậy, số lượng trang của một site gần như chắc chắn sẽ vượt quá 3, nên điều này có thể hơi khác với khả năng một khối mã thông thường được dùng lại hơn 3 lần
Tôi cũng muốn biết liệu cấu trúc có phải là gọi Google Sheets API ở phía client để đổ dữ liệu hay không; nếu đúng thì có lớp cache không, hay mỗi client đều nhận một bản sao mới mỗi lần
Cuộc tranh cãi về framework và độ phức tạp thật sự đã quá nhàm chán
Nếu khách hàng yêu cầu một CMS tùy biến với quy trình xuất bản nhiều tầng, quốc tế hóa, và khả năng truy cập để tuân thủ quy định, thì bạn cần công cụ mạnh để làm được trong thời gian khách hàng mong đợi. Ở mảng enterprise có rất nhiều khách hàng như vậy, nên nhu cầu với những công cụ kiểu này rất lớn. Nếu bạn chỉ làm B2C thì có thể sẽ ngạc nhiên, nhưng đó là phần chìm của tảng băng trong ngành công nghệ
Đúng là một blog tĩnh không cần cấu hình Next.js phức tạp hay toolchain Vite. Nhưng những người bàn nghiêm túc về các công cụ này không phải đang nói về việc dựng một site blog đơn giản. Ví dụ tối giản trong tutorial có thể là blog, nhưng vấn đề thực tế thì khác
Vì vậy tôi mong sự thù ghét framework bớt lại. Nếu có ý tưởng hay để làm website đơn giản hơn thì cứ công bố tutorial, và nếu đủ hấp dẫn thì mọi người ở những nơi phù hợp sẽ dùng cách đó. Chỉ là đừng dựng lên một kẻ thù mơ hồ kiểu “toolchain cay nồng và framework hợp mốt” để phản đối
Hoặc họ có thể nghĩ mình biết hết chỉ vì đã làm app nội bộ lâu năm với lượng người dùng hai chữ số và không có yêu cầu UX. Những phán đoán ít thông tin kiểu này làm lệch cả cuộc thảo luận
Chỉ là lần này người thừa hưởng đoạn mã đó sẽ không có bản cập nhật nào để nhận, và cũng khó tìm trợ giúp trên Stack Overflow hơn
Tôi không hiểu vì sao người ta lại nghĩ không thể dùng công cụ khác nhau cho từng công việc. Có lúc không cần framework thật, nhưng theo kinh nghiệm của tôi thì điều đó hiếm, trừ khi bạn đang làm thứ cực kỳ đơn giản và ít thay đổi
Trong bối cảnh có team và có khách hàng, tôi khó hình dung một site dùng “công cụ đơn giản” sẽ vận hành ra sao; đó không phải lời chê, mà thật sự là tôi không biết
Cách này thì với tôi cũng đã nghe quá phức tạp rồi
Tôi viết bài bằng Gemtext, tức Markdown cho Gemini, rồi tạo một script Python để chuyển sang HTML và tạo các trang chỉ mục
CSS chỉ có 42 dòng nên tôi nhúng thẳng vào từng trang, và tôi cũng tính rằng chi phí tăng thêm 42 dòng trên mỗi file sẽ không bao giờ lớn hơn một HTTP request thứ hai
Mọi thứ đơn giản hơn tôi nghĩ rất nhiều, không cần thư viện Python hay template. Phần khó nhất là tạo email để gửi qua mailing list. Tôi đã mất vài tháng để phân tích nhiều framework và trình tạo site tĩnh, và vài tuần để tìm CSS ổn ổn
Theo lịch sử git thì tôi mất 2 tuần hack xong, tính cả việc nhập 18 năm lịch sử từ WordPress. Vì là Python thuần nên không có gì mới phải học, và nếu có bug thì tôi có thể dễ dàng sửa hoặc thay đổi. Vì đó là code của tôi
Các nhà khoa học máy tính đã hoàn toàn quên mất rằng ta có thể đơn giản là tự code một giải pháp chắp vá theo nhu cầu thay vì cố tái sử dụng mọi thứ. Thời gian để học và tùy chỉnh còn nhiều hơn thời gian tự làm
Mã nguồn: https://git.sr.ht/~lioploum/ploum.net
Trang web: https://ploum.net
Site của tôi được phục vụ từ một bộ xử lý 6502 khắc từ gỗ balsa rồi dán bằng epoxy vào cáp Ethernet từ năm 2003. Mỗi khi muốn thay đổi thì tôi hơ nóng EPROM bằng máy sấy tóc để những bit mong muốn tự lật. Không template, không code, không phình to
Cảm giác cuộn xuống dưới và lần theo lịch sử công nghệ gợi lên sự hoài niệm
Nếu tôi không hiểu sai thì điều này trông không khác mấy so với một trình tạo trang tĩnh thông thường. Nó có vẻ giống như sự khác biệt giữa việc tạo file HTML bằng template Jinja dựa trên Python và Jekyll tạo file HTML/Markdown bằng template Liquid dựa trên Ruby
Tôi nghĩ một trang PHP để dùng
includehoặc một trình tạo trang tĩnh có sẵn sẽ hợp lý hơn nhiềuTôi không hiểu. Về cơ bản là không muốn dùng trình tạo trang tĩnh nên lại tự viết một trình tạo trang tĩnh