Bu yazının amacı, ayda 1 doların altında bir ücret karşılığında kendi statik kişisel web sitenizi nasıl oluşturabileceğinizi göstermektir. Biliyorum, muhtemelen şunu düşünüyorsunuz: "Bunu doğru mu okudum?". Yaptın! Elbette bu hedefe ulaşmak için uyarılar var, ancak web sitenizin yolculuğunun başlangıcında, kendi statik web sitenizi barındırmanın maliyeti gerçekte yalnızca 0,01 ABD dolarıdır. Bu yazının hedef kitlesi, biraz JavaScript deneyimi olan ve web geliştirme konusunda genel bir anlayışa sahip olan herkestir. Eğer bu altyapıya sahip değilseniz, endişelenmeyin! Herkesin takip edebilmesi için bu yazıdaki fikir ve kavramları açıklamak için elimden geleni yapacağım!
Başlamadan önce, ilk sitemizi oluşturmak için kullanacağımız farklı terimleri anlamamıza yardımcı olacak bazı tanımlara bakalım. Sitemizi Google Cloud'a ekleme sürecinde ilerlerken bu tanımlara başvurmaktan çekinmeyin:
Bu makale, okuyucunun web sitesi geliştirme ve programlama konusunda bazı temel bilgilere sahip olduğunu varsaymaktadır. Her okuyucunun aşağıdaki özelliklere sahip olduğunu varsayacağım:
Bir hedefi artan iş parçalarına bölerek daha iyi düşünme eğilimindeyim. Web sitemizi oluştururken görevlerimizi bu şekilde çerçeveleyelim:
Kendi kişisel web sitenizi oluşturmak istiyorsanız, başlamak için bir alan adına ihtiyacınız olacak. Her ne kadar başlangıçta kullanmayacak olsak da, özel alan adını daha sonraki bir makalede kullanabilmemiz için bunu şimdi yapmaya değer. Benim için alanım afro-cloud.com'du , ancak bir kayıt sağlayıcının alan adı mevcut olduğu sürece gerçekten aklınıza ne gelirse onu seçebilirsiniz. Kullanabileceğiniz çok sayıda alan adı kayıt sağlayıcısı var, ben şahsen GoDaddy'yi kullandım, ancak burada mevcut seçeneklerin bir alt kümesi var (bu hizmetlerin hiçbirine bağlı değilim):
Artık alanımızı kurduğumuza göre bir Google Cloud hesabı oluşturalım ve Faturalandırmayı etkinleştirelim.
Harika! Artık faturalandırma etkinleştirildiğinde Google Cloud hizmetlerini kullanmaya başlayabiliriz. Şimdilik bu sekmeyle hazırız, ancak bu sayfaya makalenin ilerleyen bölümlerinde geri döneceğiz, o yüzden onu el altında bulundurun.
Bu makalede yer alacak adımları takip etmekte sorun yaşıyorsanız lütfen bizimle iletişime geçin; sorunun hatalarını ayıklamak için elimden geleni yapacağım. Tamam, bunu düzelttikten sonra devam edelim. Statik dışa aktarma desteği nedeniyle Next.js'yi diğer React.js çerçevelerinin (veya yalnızca React'ın) aksine kullanacağız. Bir React.js uygulamasını barındırmak için çok sayıda farklı dağıtım seçeneği mevcut ancak SEO avantajları ve maliyet tasarrufları nedeniyle Google Cloud Storage ve Next.js yaklaşımını paylaşmayı seçtim. Next.js statik dışa aktarmalarıyla, bir üretim yapısı oluşturulduğunda, rota başına bir HTML dosyası ve farklı parçalar halinde HTML dosyasına karşılık gelen statik varlıklar (CSS ve JS dosyaları) oluşturulur. Bu önemlidir çünkü görüntülenen sayfa için gereksiz JavaScript paketlerinin yüklenmesini önleyebilir, bu da sayfanın daha hızlı yüklenmesi anlamına gelir. "Sonraki derleme" çalıştırıldığında oluşturulan tüm dosyalar "çıkış" klasörüne aktarılacaktır. Ancak bunun hakkında daha sonra daha fazla bilgi vereceğiz. Uygulamayı oluşturalım.
Öncelikle makinemize bir başlangıç Next.js projesi yükleyelim. Neyse ki Next.js, bunu kullananlar için tıpkı Create React App gibi bir "sonraki uygulama oluştur" yardımcı programına sahiptir. İş akışını başlatmak için aşağıdaki komutu çalıştırabiliriz:
npx create-next-app@latest
Komut, projemiz için bazı yapılandırma seçeneklerinde bize yol gösterecektir (istediğinizi seçmekten çekinmeyin; yalnızca kod oluşturmaya ihtiyacımız var). Bu makale için kullanacağım seçenekleri kalın harflerle yazdım:
Güzel, artık bir kodumuz var! Node_modules klasörümüzün doldurulduğunu fark edeceksiniz, böylece uygulamamızı çalıştırmak için ihtiyaç duyduğumuz tüm bağımlılıklar kurulu olacaktır. Projeyi oluşturmak için kullandığınız terminal penceresinde şu komutu çalıştıralım: npm run dev . Bu, uygulamamızı yerel olarak görüntüleyebilmemiz için Next.js geliştirme iş akışını başlatacaktır. Next.js, projeyi bilgisayarınızda görüntülemek için bir URL sağlayacaktır. Çoğu durumda bu http://localhost:3000 olacaktır, ancak çalışan başka bir web uygulamanız varsa 3001 gibi başka bir bağlantı noktası seçebilir. Bağlantıya tıkladığınızda aşağıdakine benzer bir şey görmelisiniz:
Güzel! Bir başlangıç uygulamamız var ve çalışıyor! Ama daha klasik olan "Merhaba Dünya" örneğini yapmak için başlangıç sayfasından kurtulalım. Src/app/page.tsx (veya page.jsx) dosyasını aşağıdakileri içerecek şekilde güncelleyin:
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> ); }
Dosyayı kaydedin ve uygulamamızı çalıştıran tarayıcı sekmesine geri dönün ve sayfayı yeniden yükleyin. Ekranınızda "Merhaba dünya" görmelisiniz! Şimdi statik dışa aktarmanın işe yaraması konusuna geri dönelim. Özelliği etkinleştirmek için next.config dosyamızı yapılandırmamız gerekecek. NextConfig bildirimini şu şekilde güncelleyin:
const nextConfig = { output: "export", };
Bu, oluşturma işlemi sırasında Next.js'ye, uygulamamızdaki her rotaya karşılık gelen ayrı HTML dosyaları oluşturma talimatını verecektir. Şimdilik yalnızca bir sayfamız var, bu nedenle statik dışa aktarmanın faydalarını göstermek için başka bir sayfa ekleyelim. App/ dizini içinde "test" adında yeni bir dizin oluşturun. Yeni oluşturulan dizine bir page.tsx (veya page.jsx) dosyası ekleyin ve aşağıdaki kodu ekleyin:
export default function Test() { return ( <main> <p>Hello test!</p> </main> ); }
Artık bir test sayfamız olduğuna göre, ana sayfamızdan ona bir bağlantı ekleyelim. Src/app/page.tsx'i (veya page.jsx) açın ve dosyayı şu şekilde görünecek şekilde güncelleyin:
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> ); }
Yeni güncellenen dosyaları kaydedin ve uygulamamızı çalıştıran tarayıcı sekmesine geri dönün ve sayfayı yeniden yükleyin. "Test Sayfası!" içeren yeni bir bağlantı görmelisiniz. ve bu bağlantıya tıklandığında ekrandaki içerik "Merhaba test!" gösterecek şekilde değişmelidir. İyi iş çıkardınız, artık uygulamamızda iki rotamız var. Şimdi bahsettiğimiz statik dışa aktarma özelliğinin çıktısına göz atalım. Terminal pencerenize geri döndüğünüzde "npm run build" komutunu çalıştırın. Bu komut, çalışmamız için üretime hazır bir yapı oluşturacak ve sonucu projemizin kökünde çağrılan bir dizinde saklayacak "sonraki yapı" komutunu çalıştıracaktır. Out dizinini incelersek şöyle bir şey görmeliyiz:
Harika iş çıkardınız millet. Şimdi siteyi canlı olarak görebilmek için kodumuzu Google Cloud'a yüklemek üzere vites değiştirelim.
Artık kodumuz hazır olduğuna göre Google Cloud'un sitemize internet üzerinden hizmet verebilmesi için onu Google Cloud Storage'a yüklememiz gerekiyor. Google Cloud sekmesine geri dönelim.
Ekranın sol tarafındaki hamburger menüsünü açın ve "Bulut Depolama"yı seçin. Ekranın üst kısmında "OLUŞTUR" düğmesini görmelisiniz. Oluşturma iş akışını başlatacak olana tıklayacağız. Henüz özel bir alan kullanmayacağımız için, gruba istediğiniz adı verin ancak benzersizlik kısıtlamasının farkında olun. Benim için "somerandombucket123" kullanacağım. Daha sonra ABD içindeki çoklu bölge seçeneğini kullanacağız (bu yazıyı burada yazıyorum) ancak kullanım durumunuza göre ayarlama yapmaktan çekinmeyin. Daha sonra sizin için önceden doldurulması gereken standart varsayılan sınıf seçeneğini seçeceğiz. Bir sonraki seçenek, paketimizin internet üzerinden herkesin erişimine açık olmasını isteyip istemediğimizle ilgilidir. Bu durumda, bu dosyaları izleyicilerimize sunmak istediğimizden, tüm dosyalara internet üzerinden erişilebilmesi için "Bu pakette genel erişimi engellemeyi uygula" seçeneğinin işaretini kaldırmak isteyeceğiz. Maliyetleri düşük tutmak için "Tek tip" erişim kontrolünü seçeceğiz ve "Veri koruma" tekliflerini seçmeyeceğiz. Daha sonra "Oluştur" butonuna basacağız.
Artık paketi oluşturduğumuza göre kullanıcıların paket dosyalarımızı görüntüleyebilmesi için yeni bir izin eklememiz gerekecek. "İzinler" sekmesini seçin ve "Erişim Ver" düğmesine tıklayın. "Yeni sorumlular" alanına "allUsers" yazın ve "Ortam ve Depolama Nesne Görüntüleyicisi" için "Bulut Depolama" altındaki rolü seçin.
Paketimizi herkese açık hale getirmek isteyip istemediğimizi soran bir iletişim kutusu açılacaktır, biz de bunu yapıyoruz, bu nedenle "Genel Erişime İzin Ver"i seçin. Dolayısıyla "Genel Erişime İzin Ver"i seçin. Artık bu paketin dosyaları herkesin erişimine açık olacak. Paket ayrıntıları sayfanızdaki geri okunu tıklayarak genel bakış sayfasına geri dönün. Kullandığımız yapılandırma seçenekleriyle yeni oluşturduğunuz paketinizi görmelisiniz. Daha sonra web sitemizin kovasına talimat vermemiz gerekecek ve bunu yeni oluşturulan kova satırındaki üç noktaya tıklayarak yapabiliriz. "Web sitesi yapılandırmasını düzenle"yi seçtiğinizde şunun gibi bir şey görmelisiniz:
Dizin sayfası girişi için "index.html" yazın ve hata sayfası girişi için "404.html" yazın. Bu dosyaların, istediğimiz ve kısa süre içinde kullanacağımız Next.js uygulamamızın derleme çıktısıyla eşleştiğini fark edeceksiniz. Kaydet'i tıklatarak değişikliği tamamlayın.
Şimdi web sitemizin yayına girebilmesi için kodumuzun out dizininde bulunan dosyalarımızı bu kovaya yüklememiz gerekiyor! Bunu, paketimizin paket ayrıntıları sayfasına gidip her dosya veya klasörü ayrı ayrı seçerek manuel olarak yapabiliriz. Ancak bu konuda programlı olalım ve bunu yapmak için bazı kodlar yazalım. IDE'nize veya kodunuzda güncelleme yaptığınız yere geri dönün ve projemizin kökünde upload.sh adında yeni bir dosya oluşturalım. Aşağıdaki içerikleri ekleyin:
#!/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
"somerandombucket123" ifadesini paket adınızla değiştirdiğinizden emin olun. Burada kodun anlambilimi hakkında çok fazla endişelenmeyin. Esas olarak yaptığımız şey:
Bu betiği çalıştırmadan önce Google Cloud CLI'yi indirmemiz gerekecek. Buradaki talimatları takip edebilirsiniz. Kurulumdan sonra terminalinizde şunu çalıştırmanız gerekir: gcloud auth login . Bu, Google Cloud CLI'yi kullanmamız için erişim yetkisi verecektir. Bununla ilgili daha fazla talimat ve arka planı belgelerinde bulabilirsiniz. Başarıyla yetkilendirdikten sonra package.json dosyamıza yeni bir çalıştırma betiği ekleyelim. Yükleme komut dosyamızı kaydetmek için "scripts" nesnesine yeni bir komut dosyası girişi ekleyin:
"upload": "sh upload.sh"
Şimdi test edelim. Terminalinizi tekrar açın ve şunu çalıştırın: "npm run upload". Bu, betiğimizi çalıştıracak ve paketinize yapılan yüklemelerle ilgili bazı çıktılar görmelisiniz. Google Cloud Storage sayfasına geri dönüp paketinizi açarsak, az önce yüklediğimiz dosyaları görmelisiniz. Şu adrese giderseniz: https://storage.googleapis.com/YOUR_BUCKET_NAME/index.html (burada YOUR_BUCKET_NAME paketinizin adıdır) siteyi görmelisiniz. Ancak varsayılan Next.js stilinin kaybolduğunu ve test sayfamıza olan bağlantının koptuğunu fark edeceksiniz. Neden olduğu hakkında bir fikrin var mı?
Tarayıcı konsolunuzu açarsanız çok sayıda kaynak bulunamadı hatası görüyor olmalısınız. Başka bir deyişle tarayıcı, siteniz için yüklemesi talimatı verilen dosyaları bulamıyor. Yakından bakarsanız kaynağın URL'sinin tam olarak doğru olmadığını, yolda paket adımızın eksik olduğunu görebilirsiniz. Özel bir etki alanı kullanmış olsaydık ve DNS'yi doğru şekilde yapılandırmış olsaydık bu sorunla karşılaşmazdık. Ancak bu yazının amaçları doğrultusunda, yönlendirmeyi düzeltmek için bazı ek kodlar ekleyelim. Src/app/page.tsx'i (veya page.jsx) açın ve dosyayı şu şekilde görünecek şekilde güncelleyin:
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> ); }
"somerandombucket123" ifadesini paket adınızla değiştirdiğinizden emin olun. Daha sonra next.config dosyasını aşağıdaki gibi görünecek şekilde güncelleyin:
// 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;
Yine "somerandombucket123" ifadesini paket adınızla değiştirdiğinizden emin olun. Yukarıdaki kod parçacığında, düğüm ortam değişkeni üretim (Next.js tarafından ayarlanır) olduğunda paket adımızı hesaba katacak ek mantık eklediğimizi fark edeceksiniz. Yapılandırma dosyasındaki kaynak bulunamadı hatalarını düzeltmek için bir varlık öneki ekliyoruz ve rotanın başına paket adımızı ekleyerek ana sayfamızdaki yönlendirme hatasını hesaba katıyoruz. Şimdi kodumuzu yükleyelim ve çalışıp çalışmadığını görelim. Bir kez daha başlayın: npm yüklemeyi çalıştırın. Web sitenize geri dönün ve sayfayı yeniden yükleyin. Nasıl yaptık? Site şu anda yerel olarak sahip olduğumuz şeyleri yansıtmalıdır. Sürecin başında, etki alanı adımızla eşleşecek bir paket oluştursaydık kaynak hataları yaşardık ancak yine de istemci yönlendirme sorununu yaşardık. Ne yazık ki, bu yaklaşımın bir dezavantajı, üretim sunumu için rotalara .html sonekini eklemek için gereken ek koddur.
Daha sonraki bir tarihte, özel bir alan adı sunmak için paketimize gereken DNS kayıtlarını ve yapılandırma değişikliklerini eklemenin yanı sıra web sitemiz için SSL yapılandırmayı da ele alacağım. Umarım bugün bir şeyler öğrenmişsinizdir ve gelecekte bazı fikirler üzerinde konuşacağım:
Okuduğunuz için teşekkürler ve şerefe!