Mục tiêu của bài đăng này là chỉ cho bạn cách bạn có thể tạo trang web cá nhân tĩnh của riêng mình với chi phí dưới 1 đô la một tháng. Tôi biết, có lẽ bạn đang nghĩ: "Tôi vừa đọc nó phải không?". Bạn đã làm! Tất nhiên, có những lưu ý để đạt được mục tiêu đó, nhưng khi bắt đầu hành trình trang web của bạn, thực sự chỉ tốn 0,01 USD một tháng để lưu trữ trang web tĩnh của riêng bạn. Đối tượng mục tiêu của bài đăng này là bất kỳ ai có một số kinh nghiệm về JavaScript và hiểu biết chung về phát triển web. Nếu bạn không có nền tảng đó, đừng lo lắng! Tôi sẽ cố gắng hết sức để giải thích các ý tưởng và khái niệm trong bài đăng này để mọi người có thể theo dõi!
Trước khi bắt đầu, chúng ta hãy tìm hiểu một số định nghĩa để giúp chúng ta hiểu các thuật ngữ khác nhau mà chúng ta sẽ sử dụng để tạo trang web đầu tiên của mình. Vui lòng tham khảo các định nghĩa này khi chúng tôi thực hiện quá trình thêm trang web của mình vào Google Cloud:
Bài viết này giả định rằng người đọc đã có một số kiến thức nền tảng về phát triển và lập trình trang web. Tôi sẽ cho rằng mỗi người đọc có những điều sau đây:
Tôi có xu hướng suy nghĩ tốt hơn bằng cách chia mục tiêu thành nhiều phần công việc. Hãy sắp xếp các nhiệm vụ của chúng ta theo cách đó khi chúng ta tạo trang web của mình:
Nếu bạn muốn tạo trang web cá nhân của riêng mình, bạn sẽ cần một miền để bắt đầu. Mặc dù ban đầu chúng ta sẽ không sử dụng nó nhưng việc này đáng làm ngay bây giờ để chúng ta có thể sử dụng miền tùy chỉnh trong bài viết sau . Đối với tôi, miền của tôi là afro-cloud.com nhưng bạn thực sự có thể chọn bất cứ thứ gì tôi nghĩ đến miễn là nhà cung cấp dịch vụ đăng ký có sẵn miền đó. Có một số nhà cung cấp dịch vụ đăng ký miền mà bạn có thể sử dụng, cá nhân tôi đã sử dụng GoDaddy, nhưng đây là một số tùy chọn có sẵn (tôi không liên kết với bất kỳ dịch vụ nào trong số này):
Bây giờ chúng ta đã thiết lập miền của mình, hãy tạo tài khoản Google Cloud và bật Thanh toán.
Tuyệt vời! Giờ đây, khi tính năng thanh toán được bật, chúng tôi có thể bắt đầu sử dụng các dịch vụ của Google Cloud. Hiện tại chúng ta đã thiết lập xong tab này nhưng chúng ta sẽ quay lại trang này sau trong bài viết, vì vậy hãy luôn sẵn sàng sử dụng tab này.
Nếu bạn gặp sự cố khi làm theo các bước trong bài viết này, vui lòng liên hệ và tôi sẽ cố gắng hết sức để giúp gỡ lỗi. Được rồi, đã giải quyết xong vấn đề đó, hãy tiếp tục. Chúng tôi sẽ sử dụng Next.js thay vì các khung React.js khác (hoặc chỉ React) vì tính năng hỗ trợ xuất tĩnh của chúng. Có một số tùy chọn triển khai khác nhau để lưu trữ ứng dụng React.js nhưng tôi đã chọn chia sẻ phương pháp tiếp cận Google Cloud Storage và Next.js vì lợi ích SEO và tiết kiệm chi phí. Với tính năng xuất tĩnh của Next.js, khi một bản dựng sản xuất được tạo, một tệp HTML sẽ được tạo trên mỗi tuyến, cùng với các nội dung tĩnh (tệp CSS & JS) tương ứng với tệp HTML theo các phần riêng biệt. Điều này rất quan trọng vì nó có thể tránh tải các gói JavaScript không cần thiết cho trang đang được xem, đồng nghĩa với việc tải trang nhanh hơn. Tất cả các tệp được tạo khi chạy "bản dựng tiếp theo" sẽ được xuất vào thư mục "out". Nhưng nhiều hơn về điều này sau. Hãy tạo ứng dụng.
Trước hết, hãy cài đặt dự án Next.js khởi đầu trên máy của chúng ta. May mắn thay, Next.js có tiện ích "tạo ứng dụng tiếp theo" giống như Tạo ứng dụng React dành cho những người đã sử dụng tiện ích đó. Để bắt đầu quy trình làm việc, chúng ta có thể chạy lệnh sau:
npx create-next-app@latest
Lệnh sẽ hướng dẫn chúng tôi một số tùy chọn cấu hình cho dự án của chúng tôi (bạn có thể thoải mái chọn bất cứ thứ gì bạn muốn; chúng tôi chỉ cần tạo mã). Tôi đã in đậm các tùy chọn mà tôi sẽ sử dụng cho bài viết này:
Tốt lắm, bây giờ chúng ta có một số mã! Bạn sẽ nhận thấy rằng thư mục node_modules của chúng tôi đã được điền nên chúng tôi đã cài đặt tất cả các phần phụ thuộc cần thiết để chạy ứng dụng của mình. Trong cùng cửa sổ terminal mà bạn đã sử dụng để tạo dự án, hãy chạy lệnh sau: npm run dev . Thao tác này sẽ bắt đầu quy trình phát triển Next.js để chúng ta có thể xem ứng dụng của mình cục bộ. Next.js sẽ cung cấp URL để xem dự án trên máy tính của bạn. Trong hầu hết các trường hợp, đây sẽ là http://localhost:3000 , nhưng nếu bạn có một ứng dụng web khác đang chạy thì nó có thể chọn một cổng khác như 3001. Khi nhấp vào liên kết, bạn sẽ thấy một số thứ như sau:
Đẹp! Chúng tôi có một ứng dụng khởi động đang chạy! Nhưng hãy loại bỏ trang khởi đầu để làm ví dụ "Xin chào thế giới" cổ điển hơn. Cập nhật tệp src/app/page.tsx (hoặc page.jsx) để chứa nội dung sau:
import styles from "./page.module.css"; export default function Home() { return ( <main className={styles.main}> <div className={styles.description}> <p>Hello world!</p> </div> </main> ); }
Lưu tệp và quay lại tab trình duyệt đang chạy ứng dụng của bạn và tải lại trang. Bạn sẽ thấy "Xin chào thế giới" trên màn hình của mình! Bây giờ hãy quay lại để quá trình xuất tĩnh hoạt động. Chúng tôi sẽ cần định cấu hình tệp next.config để kích hoạt tính năng này. Cập nhật khai báo nextConfig thành:
const nextConfig = { output: "export", };
Điều này sẽ hướng dẫn Next.js trong quá trình xây dựng tạo các tệp HTML riêng lẻ tương ứng với từng tuyến đường trong ứng dụng của chúng tôi. Hiện tại chúng tôi chỉ có một trang nên hãy thêm một trang khác để minh họa lợi ích của việc xuất tĩnh. Trong thư mục app/, tạo một thư mục mới tên là "test". Trong thư mục mới tạo, hãy thêm tệp page.tsx (hoặc page.jsx) và thêm mã sau:
export default function Test() { return ( <main> <p>Hello test!</p> </main> ); }
Bây giờ chúng ta đã có một trang thử nghiệm, hãy thêm một liên kết đến nó từ trang chủ của chúng ta. Mở src/app/page.tsx (hoặc page.jsx) và cập nhật tệp để nó trông như sau:
import Link from "next/link"; import styles from "./page.module.css"; export default function Home() { return ( <main className={styles.main}> <div className={styles.description}> <p>Hello world!</p> <Link href="/test">Test Page!</Link> </div> </main> ); }
Lưu các tệp mới cập nhật và quay lại tab trình duyệt đang chạy ứng dụng của chúng tôi và tải lại trang. Bạn sẽ thấy một liên kết mới với "Trang thử nghiệm!" và khi nhấp vào liên kết đó, nội dung trên màn hình sẽ thay đổi thành "Xin chào bài kiểm tra!". Làm tốt lắm, bây giờ chúng tôi có hai tuyến đường trong ứng dụng của mình. Bây giờ hãy kiểm tra đầu ra của tính năng xuất tĩnh mà chúng ta đã nói đến. Quay trở lại cửa sổ terminal của bạn chạy "npm run build". Lệnh này sẽ chạy lệnh "bản dựng tiếp theo", lệnh này sẽ tạo bản dựng sẵn sàng sản xuất cho công việc của chúng ta và lưu trữ kết quả trong một thư mục được gọi ở thư mục gốc của dự án của chúng ta. Nếu chúng ta kiểm tra thư mục out, chúng ta sẽ thấy một cái gì đó như thế này:
Làm tốt lắm mọi người. Bây giờ, hãy chuyển sang tải mã của chúng tôi lên Google Cloud để chúng tôi có thể xem trực tiếp trang web.
Bây giờ chúng ta đã có mã sẵn sàng, chúng ta cần tải nó lên Google Cloud Storage để Google Cloud có thể phục vụ trang web của chúng ta trên internet. Hãy quay lại tab Google Cloud.
Mở menu hamburger ở phía bên trái màn hình và chọn "Lưu trữ đám mây". Ở đầu màn hình, bạn sẽ thấy nút "TẠO". Chúng tôi sẽ nhấp vào đó để bắt đầu quy trình tạo. Vì chúng tôi chưa sử dụng miền tùy chỉnh nên hãy đặt tên cho nhóm theo bất kỳ tên nào bạn muốn nhưng hãy lưu ý đến hạn chế về tính duy nhất. Đối với tôi, tôi sẽ sử dụng "somerandombucket123". Tiếp theo, chúng tôi sẽ sử dụng tùy chọn đa vùng ở Hoa Kỳ (đó là nơi tôi đang viết bài này) nhưng bạn có thể thoải mái điều chỉnh cho phù hợp với trường hợp sử dụng của mình. Sau đó, chúng tôi sẽ chọn tùy chọn lớp mặc định tiêu chuẩn sẽ được điền trước cho bạn. Tùy chọn tiếp theo liên quan đến việc chúng ta có muốn nhóm của mình có thể truy cập công khai qua internet hay không. Trong trường hợp này, vì chúng tôi muốn phân phối các tệp này cho người xem nên chúng tôi sẽ muốn bỏ chọn "Thực thi ngăn chặn truy cập công cộng trên nhóm này" để tất cả các tệp đều có thể truy cập được qua internet. Chúng tôi sẽ chọn kiểm soát truy cập "Đồng nhất" chứ không chọn dịch vụ "Bảo vệ dữ liệu" để giữ chi phí ở mức thấp. Sau đó chúng ta sẽ nhấn nút "Tạo".
Bây giờ chúng tôi đã tạo nhóm, chúng tôi sẽ cần thêm quyền mới để người dùng có thể xem các tệp nhóm của chúng tôi. Chọn tab "Quyền" và nhấp vào nút "Cấp quyền truy cập". Trong loại đầu vào "Quy tắc mới" trong "tất cả người dùng" và chọn vai trò trong "Lưu trữ đám mây" cho "Trình xem đối tượng lưu trữ và môi trường".
Một hộp thoại sẽ mở ra hỏi xem chúng tôi có muốn đặt nhóm của mình ở chế độ công khai hay không. Chúng tôi thực hiện việc này, vì vậy hãy chọn "Cho phép truy cập công cộng". Vì vậy hãy chọn "Cho phép truy cập công cộng". Bây giờ các tập tin của nhóm này sẽ có thể truy cập công khai. Quay lại trang tổng quan bằng cách nhấp vào mũi tên quay lại từ trang chi tiết nhóm của bạn. Bạn sẽ thấy nhóm mới tạo của mình với các tùy chọn cấu hình mà chúng tôi đã sử dụng. Tiếp theo, chúng ta sẽ cần hướng dẫn nhóm của trang web của mình và chúng ta có thể thực hiện việc này bằng cách nhấp vào ba dấu chấm của hàng của nhóm mới tạo. Chọn "Chỉnh sửa cấu hình trang web" và bạn sẽ thấy một cái gì đó như thế này:
Đối với đầu vào trang chỉ mục, hãy nhập "index.html" và đối với đầu vào trang lỗi, hãy nhập "404.html". Bạn sẽ nhận thấy rằng các tệp này khớp với kết quả xây dựng của ứng dụng Next.js của chúng tôi, đây là những gì chúng tôi muốn và sẽ sớm sử dụng. Kết thúc thay đổi bằng cách nhấp vào lưu.
Bây giờ chúng ta cần tải các tệp có trong thư mục out của mã vào nhóm này để trang web của chúng ta có thể hoạt động! Chúng tôi có thể thực hiện việc này một cách thủ công bằng cách điều hướng đến trang chi tiết nhóm cho nhóm của mình và chọn từng tệp hoặc thư mục riêng lẻ. Tuy nhiên, hãy lập trình về nó và viết một số mã để thực hiện việc này. Quay lại IDE của bạn hoặc bất cứ nơi nào bạn đang cập nhật mã của mình và hãy tạo một tệp mới có tên upload.sh ở thư mục gốc của dự án của chúng tôi. Thêm các nội dung sau:
#!/bin/bash # ADD YOUR BUCKETNAME HERE (no quotes necessary) # For example: # BUCKETNAME=somerandombucket123 BUCKETNAME=somerandombucket123 echo "Removing out folder..." sleep 1; rm -rf out echo "Creating production build..." sleep 1; npm run build echo "Uploading assets to the cloud..." sleep 1; gsutil cp out/404.html gs://$BUCKETNAME gsutil cp out/favicon.ico gs://$BUCKETNAME gsutil cp out/index.html gs://$BUCKETNAME gsutil cp out/index.txt gs://$BUCKETNAME gsutil cp out/test.html gs://$BUCKETNAME gsutil cp out/test.txt gs://$BUCKETNAME gsutil cp -r out/_next gs://$BUCKETNAME
Hãy nhớ thay thế "somerandombucket123" bằng tên nhóm của bạn. Đừng lo lắng quá nhiều về ngữ nghĩa của mã ở đây. Về cơ bản những gì chúng tôi đang làm là:
Trước khi có thể chạy tập lệnh này, chúng tôi sẽ phải tải xuống Google Cloud CLI. Bạn có thể làm theo hướng dẫn tại đây . Sau khi cài đặt, bạn sẽ cần chạy: gcloud auth login trong terminal của mình. Điều này sẽ cấp quyền truy cập cho chúng tôi để sử dụng Google Cloud CLI. Bạn có thể tìm thêm hướng dẫn và thông tin cơ bản về điều đó trong tài liệu của họ. Khi bạn đã ủy quyền thành công, hãy thêm tập lệnh chạy mới vào pack.json của chúng tôi. Thêm một mục nhập tập lệnh mới trong đối tượng "tập lệnh" để đăng ký tập lệnh tải lên của chúng tôi:
"upload": "sh upload.sh"
Tiếp theo, hãy thử nghiệm nó. Mở lại terminal của bạn và chạy: "npm run upload". Điều này sẽ thực thi tập lệnh của chúng tôi và bạn sẽ thấy một số kết quả đầu ra về quá trình tải lên xảy ra với nhóm của bạn. Nếu chúng tôi điều hướng quay lại trang Google Cloud Storage và mở nhóm của bạn, bạn sẽ thấy các tệp chúng tôi vừa tải lên. Nếu bạn điều hướng tới: https://storage.googleapis.com/YOUR_BUCKET_NAME/index.html (trong đó YOUR_BUCKET_NAME là tên nhóm của bạn), bạn sẽ thấy trang web. Nhưng bạn sẽ nhận thấy rằng kiểu dáng Next.js mặc định đã biến mất và liên kết tới trang thử nghiệm của chúng tôi bị hỏng. Có ý tưởng nào tại sao không?
Nếu bạn mở bảng điều khiển trình duyệt, bạn sẽ thấy rất nhiều lỗi không tìm thấy tài nguyên. Nói cách khác, trình duyệt không thể tìm thấy các tệp mà nó được hướng dẫn tải cho trang web của bạn. Nếu quan sát kỹ, bạn có thể thấy rằng URL của tài nguyên không hoàn toàn chính xác, nó thiếu tên nhóm của chúng tôi trong đường dẫn. Nếu chúng tôi đã sử dụng miền tùy chỉnh và định cấu hình DNS đúng cách thì chúng tôi sẽ không gặp phải vấn đề này. Nhưng với mục đích của bài đăng này, hãy thêm một số mã bổ sung để sửa lỗi định tuyến. Mở src/app/page.tsx (hoặc page.jsx) và cập nhật tệp để nó trông như sau:
import Link from "next/link"; import styles from "./page.module.css"; // Replace below with your bucketname. const BUCKET_NAME = "somerandombucket123"; const isProd = process.env.NODE_ENV === "production"; export default function Home() { return ( <main className={styles.main}> <div className={styles.description}> <p>Hello world!</p> <Link href={isProd ? '/BUCKET_NAME/test.html' : "/test"}> Test Page! </Link> </div> </main> ); }
Hãy nhớ thay thế "somerandombucket123" bằng tên nhóm của bạn. Tiếp theo cập nhật tệp next.config trông như sau:
// Replace below with your bucketname. const BUCKET_NAME = "somerandombucket123"; const isProd = process.env.NODE_ENV === "production"; /** @type {import('next').NextConfig} */ const nextConfig = { assetPrefix: isProd ? 'https://storage.googleapis.com/BUCKET_NAME/' : undefined, output: "export", }; export default nextConfig;
Một lần nữa, hãy nhớ thay thế "somerandombucket123" bằng tên nhóm của bạn. Bạn sẽ nhận thấy trong đoạn mã trên rằng chúng tôi đã thêm logic bổ sung để tính tên nhóm khi biến môi trường nút được sản xuất (do Next.js đặt). Chúng tôi đang thêm tiền tố nội dung để sửa lỗi không tìm thấy tài nguyên trong tệp cấu hình và giải quyết lỗi định tuyến trong trang chủ của chúng tôi bằng cách đặt tiền tố tuyến đường bằng tên nhóm của chúng tôi. Hãy tải lên mã của chúng tôi ngay bây giờ và xem nó có hoạt động không. Một lần nữa, hãy bắt đầu: npm run upload. Quay trở lại trang web của bạn và tải lại trang. Chúng ta đã làm như thế nào? Trang web sẽ phản ánh những gì chúng tôi có tại địa phương hiện nay. Khi bắt đầu quá trình, nếu chúng tôi tạo nhóm phù hợp với tên miền của mình thì chúng tôi sẽ gặp lỗi tài nguyên nhưng vẫn gặp sự cố định tuyến máy khách. Thật không may, một nhược điểm của phương pháp này là mã bổ sung cần thiết để thêm hậu tố .html vào các tuyến để phân phối sản phẩm.
Sau này, tôi sẽ đề cập đến việc thêm bản ghi DNS và các thay đổi cấu hình cần thiết vào nhóm của chúng tôi để phục vụ miền tùy chỉnh cũng như định cấu hình SSL cho trang web của chúng tôi. Hy vọng hôm nay bạn đã học được điều gì đó và trong tương lai tôi sẽ nói về một số ý tưởng xung quanh:
Cảm ơn đã đọc và chúc mừng!