Çerçeve Olmadan Aşamalı Bir Web Uygulaması Tasarlama ve Oluşturma (Bölüm 1)
Yayınlanan: 2022-03-10Bir web uygulaması gerçekte nasıl çalışır? Son kullanıcı açısından demek istemiyorum. Teknik anlamda söylüyorum. Bir web uygulaması gerçekte nasıl çalışır? İşleri ne başlatır? Herhangi bir ortak kod olmadan, bir uygulamayı yapılandırmanın doğru yolu nedir? Özellikle tüm mantığın son kullanıcı cihazında çalıştığı istemci tarafı bir uygulama. Veriler nasıl yönetilir ve işlenir? Arayüzün verilerdeki değişikliklere nasıl tepki vermesini sağlarsınız?
Bunlar, bir çerçeve ile tamamen görmezden gelinmesi veya görmezden gelinmesi basit olan sorulardır. Geliştiriciler React, Vue, Ember veya Angular gibi bir şeye ulaşır, kalkıp koşmak ve gitmek için belgeleri takip eder. Bu sorunlar, çerçevenin hileler kutusu tarafından ele alınır.
Bu tam olarak istediğiniz şeyler olabilir. Muhtemelen, profesyonel bir standartta bir şey inşa etmek istiyorsanız yapılacak akıllıca şey budur. Ancak, soyutlanmış sihirle, hilelerin gerçekte nasıl yapıldığını asla öğrenemezsiniz.
Numaraların nasıl yapıldığını bilmek istemiyor musun?
Yaptım. Bu yüzden, bu sorunları kendim anlamak için basit bir istemci tarafı uygulaması, çerçeve dışı bir uygulama oluşturmaya karar verdim.
Ama ben biraz kendimden geçiyorum; önce biraz arka plan.
Bu yolculuğa başlamadan önce kendimi HTML ve CSS konusunda oldukça yetkin görüyordum ama JavaScript'te değil. CSS ile ilgili en büyük sorularımı tatmin edecek şekilde çözdüğümü hissettiğimde, kendime koyduğum bir sonraki zorluk bir programlama dilini anlamaktı.
Gerçek şu ki, JavaScript ile nispeten başlangıç seviyesindeydim. Ve Wordpress'in PHP'sini hacklemenin yanı sıra, başka herhangi bir programlama dilinde de herhangi bir maruz kalma veya eğitim almadım.
Bu 'başlangıç seviyesi' iddiasını nitelendirmeme izin verin. Elbette, bir sayfada etkileşimi çalıştırabilirim. Sınıflar arasında geçiş yapın, DOM düğümleri oluşturun, ekleyin ve hareket ettirin, vb. Ama iş bunun ötesindeki herhangi bir şey için kodu düzenlemeye geldiğinde oldukça cahildim. Bir uygulamaya yaklaşan bir şey inşa etmekten emin değildim. JavaScipt'te bir dizi veriyi nasıl tanımlayacağıma dair hiçbir fikrim yoktu, onu işlevlerle işlemek bir yana.
JavaScript 'tasarım kalıpları' hakkında hiçbir fikrim yoktu - sık karşılaşılan kod problemlerini çözmek için yerleşik yaklaşımlar. Temel uygulama tasarımı kararlarına nasıl yaklaşılacağı konusunda kesinlikle bir fikrim yoktu.
Hiç 'Top Trumps' oynadın mı? Web geliştirici sürümünde kartım şöyle görünürdü (100 üzerinden puan):
- CSS: 95
- Kopyala ve yapıştır: 90
- saç çizgisi: 4
- HTML: 90
- JavaSript: 13
Teknik düzeyde kendime meydan okumak istemenin yanı sıra tasarım konusunda da eksiktim.
Geçen on yılda neredeyse yalnızca diğer insanların tasarımlarını kodlarken, görsel tasarım becerilerim, geç sonlardan beri gerçek bir zorlukla karşılaşmamıştı. Bu gerçeği ve benim cılız JavaScript becerilerimi düşünmek, giderek artan bir profesyonel yetersizlik duygusu geliştirdi. Eksiklerimi gidermenin zamanı gelmişti.
Aklımda kişisel bir zorluk oluştu: bir istemci tarafı JavaScript web uygulaması tasarlamak ve oluşturmak.
Öğrenme Üzerine
Bilgisayar dillerini öğrenmek için hiç bu kadar harika kaynak olmamıştı. Özellikle JavaScript. Ancak, her şeyi tıklayacak şekilde açıklayan kaynakları bulmam biraz zaman aldı. Benim için Kyle Simpson'ın 'You Don't Know JS' ve Marijn Haverbeke'nin 'Eloquent JavaScript'i çok yardımcı oldu.
JavaScript öğrenmeye başlıyorsanız, kesinlikle kendi gurularınızı bulmanız gerekecek; açıklama yöntemi işinize yarayan insanlar.
Öğrendiğim ilk önemli şey, bir şeyleri anladığınız şekilde açıklamayan bir öğretmenden/kaynaktan öğrenmeye çalışmanın anlamsız olduğuydu. Bazı insanlar foo
ve bar
in ile fonksiyon örneklerine bakar ve anında anlamını grok yapar. Ben o insanlardan değilim. Siz de değilseniz, programlama dillerinin size göre olmadığını varsaymayın. Sadece farklı bir kaynak deneyin ve öğrendiğiniz becerileri uygulamaya devam edin.
Ayrıca her şeyin birdenbire 'tıkladığı' herhangi bir eureka anının tadını çıkaracağınız da kesin değil; ilk görüşte aşkın kodlama eşdeğeri gibi. Kendinden emin hissetmek için çok fazla azim ve öğrendiklerinizi önemli ölçüde uygulamanız daha olasıdır.
Kendinizi birazcık bile yetkin hissettiğinizde öğrendiklerinizi uygulamaya çalışmak size daha da fazlasını öğretecektir.
İşte yol boyunca yararlı bulduğum bazı kaynaklar:
- Eğlenceli Eğlence İşlevi YouTube Kanalı
- Kyle Simpson Çoğul Görüş kursları
- Wes Bos'un JavaScript30.com'u
- Marijn Haverbeke'den anlamlı JavaScript
Doğru, bu noktaya neden geldiğim hakkında bilmen gereken hemen hemen her şey bu. Şimdi odadaki fil, neden bir çerçeve kullanmıyorsunuz?
Neden Tepki Verilmiyor, Ember, Angular, Vue Et Al
Cevap başlangıçta ima edilmiş olsa da, bir çerçevenin neden kullanılmadığı konusunun genişletilmesi gerektiğini düşünüyorum.
Çok sayıda yüksek kaliteli, iyi desteklenen JavaScript çerçevesi vardır. Her biri, istemci tarafı web uygulamalarının oluşturulması için özel olarak tasarlanmıştır. Tam olarak inşa etmek istediğim türden bir şey. Bariz olanı merak ettiğiniz için sizi bağışlıyorum: mesela, err, neden bir tane kullanmıyorsunuz?
İşte benim bu konudaki duruşum. Bir soyutlamayı kullanmayı öğrendiğinizde, öncelikle öğrendiğiniz şey budur - soyutlama. Ben o şeyin soyutluğunu değil, o şeyi öğrenmek istiyordum.
Gün içinde biraz jQuery öğrendiğimi hatırlıyorum. Güzel API, DOM manipülasyonlarını her zamankinden daha kolay hale getirmeme izin verirken, onsuz güçsüz kaldım. JQuery'ye ihtiyaç duymadan bir öğedeki sınıfları bile değiştiremedim. Bana jQuery'nin dayanamayacağı bir sayfada bazı temel etkileşimlerle görev verin ve editörümde kısa bir Samson gibi tökezledim.
Daha yakın zamanlarda, JavaScript anlayışımı geliştirmeye çalışırken, kafamı Vue ve biraz React'in etrafına sarmaya çalıştım. Ama nihayetinde, standart JavaScript'in nerede bittiği ve React veya Vue'nin nerede başladığından asla emin olamadım. Benim düşüncem, sizin için ne yaptıklarını anladığınızda bu soyutlamaların çok daha değerli olduğudur.
Bu nedenle, eğer bir şey öğreneceksem, dilin temel kısımlarını anlamak istedim. Bu şekilde, bazı aktarılabilir becerilere sahip oldum. Ay çerçevesinin mevcut tadı bir sonraki 'sıcak yeni şey' için bir kenara atıldığında bir şeyi korumak istedim.
Peki. Şimdi, bu uygulamanın neden yapıldığını ve aynı zamanda beğenin ya da beğenmeyin, nasıl yapılacağına yakalandık.
Gelelim bu şeyin ne olacağına.
Bir Uygulama Fikri
Bir uygulama fikrine ihtiyacım vardı. Çok iddialı bir şey yok; Bir iş kurmak veya Dragon's Den'de görünmek gibi bir hayalim yoktu - JavaScript ve uygulama temellerini öğrenmek birincil hedefimdi.
Uygulamanın teknik olarak başarılı olma ve yarı düzgün bir tasarım işi yapma şansım olan bir şey olması gerekiyordu.
Teğet zamanı.
İşten uzakta, fırsat buldukça salon futbolu düzenliyorum ve oynuyorum. Organizatör olarak, bana kimin oynadıklarını ve kimin oynamadığını söylemek için bir mesaj gönderdiğini zihinsel olarak not etmek acı verici. Bir oyun için tipik olarak 10 kişiye ihtiyaç vardır, bir seferde 8 kişi. Her oyunu oynayabilecek veya oynayamayacak yaklaşık 20 kişilik bir kadro var.
Yerleştiğim uygulama fikri, bir kadrodan oyuncu seçmeyi sağlayan ve bana kaç oyuncunun oynayabileceğini onayladığını gösteren bir şeydi.
Daha fazla düşündükçe, kapsamı biraz daha genişletebileceğimi hissettim, böylece herhangi bir basit takım tabanlı aktiviteyi organize etmek için kullanılabilirdi.
Kuşkusuz, Google Earth'ü pek hayal etmemiştim. Bununla birlikte, tüm temel zorluklara sahipti: tasarım, veri yönetimi, etkileşim, veri depolama, kod organizasyonu.
Tasarım açısından, bir telefon görünümünde iyi çalışabilecek ve çalışabilecek bir sürümden başka bir şeyle ilgilenmem. Tasarım zorluklarını yalnızca küçük ekranlardaki sorunları çözmekle sınırlardım.
Ana fikir kesinlikle kendisini 'yapılacaklar' tarzı uygulamalara dayandırdı; bunlardan ilham almak için bakılacak çok sayıda mevcut örnek bulunurken, aynı zamanda bazı benzersiz tasarım ve kodlama zorlukları sağlamaya yetecek kadar farklılığa sahipti.
Amaçlanan Özellikler
Tasarlamayı ve kodlamayı amaçladığım özelliklerin ilk madde işaretli listesi şuna benziyordu:
- Listeye kişi eklemek için bir giriş kutusu;
- Her kişiyi 'içeri' veya 'dışarı' olarak ayarlama yeteneği;
- İnsanları takımlara bölen, varsayılan olarak 2 takım olan bir araç;
- Listeden bir kişiyi silme yeteneği;
- 'Araçlar' için bazı arayüzler. Bölmenin yanı sıra, mevcut araçlar, girilen verileri bir dosya olarak indirme, önceden kaydedilmiş verileri yükleme ve tüm oyuncuları tek seferde silme;
- Uygulama, kaç kişinin 'İçeride' olduğuna dair geçerli bir sayı göstermelidir;
- Bir oyun için seçilen kişi yoksa, takım ayırıcıyı gizlemelidir;
- Ödeme modu. "In" kullanıcıların ödeme yapıp yapmadıklarını göstermek için ek bir geçişe sahip olmalarına olanak tanıyan ayarlarda bir geçiş.
Başlangıçta, minimum uygulanabilir bir ürün için özellikleri düşündüğüm şey buydu.

Tasarım
Tasarımlar kağıt parçalarıyla başladı. Kafamda inanılmaz olan kaç tane fikrin bir karakalemle yapılan yetersiz incelemeye tabi tutulduğunda bile gülünç olduğunu bulmak aydınlatıcıydı (okuyun: ezici).
Bu nedenle birçok fikir çabucak reddedildi, ancak diğer taraftan, bazı fikirlerin taslağını çizerek, her zaman, aksi takdirde asla düşünmeyeceğim başka fikirlere yol açtı.
Şimdi, bunu okuyan tasarımcılar muhtemelen “Hah, tabii ki” gibi olacaklar ama bu benim için gerçek bir keşifti. Geliştiriciler, daha sonraki aşama tasarımlarını görmeye alışkındır, bu noktadan önce yol boyunca terk edilen tüm adımları nadiren görürler.
Karakalem olarak bir şeyden memnun kaldığımda, onu tasarım paketi Sketch'te yeniden yaratmaya çalışırdım. Fikirlerin kağıt ve kalem aşamasında uçup gitmesi gibi, aynı sayıda kişi Sketch'in bir sonraki aslına uygunluk aşamasından geçemedi. Sketch'te çalışma yüzeyi olarak görünenler daha sonra kodlanacak adaylar olarak seçildi.
Buna karşılık, bu adaylar yerleşik kod olduğunda, çeşitli nedenlerle bir yüzdenin de çalışmadığını görecektim. Her aslına uygunluk adımı, tasarımın başarılı veya başarısız olması için yeni zorluklar ortaya çıkardı. Ve bir başarısızlık beni kelimenin tam anlamıyla ve mecazi olarak çizim tahtasına geri götürür.
Sonuç olarak, sonuçta elde ettiğim tasarım, Sketch'te orijinal olarak sahip olduğumdan biraz farklı. İşte ilk Sketch maketleri:


O zaman bile, hiçbir yanılgı içinde değildim; temel bir tasarımdı. Bununla birlikte, bu noktada, işe yarayabileceğinden nispeten emin olduğum bir şeye sahiptim ve onu denemek ve inşa etmek için biraz uğraşıyordum.
Teknik gereksinimler
Bazı ilk özellik gereksinimleri ve temel bir görsel yön ile, kodla ne elde edilmesi gerektiğini düşünmenin zamanı gelmişti.
Alınan bilgelik, iOS veya Android cihazlar için uygulama yapmanın yolunun yerel kodla olduğunu belirtse de, niyetimin uygulamayı JavaScript ile oluşturmak olduğunu zaten belirledik.
Ayrıca, uygulamanın Aşamalı Web Uygulaması veya daha yaygın olarak bilinen adıyla PWA olarak nitelendirilmesi için gerekli tüm kutuları işaretlediğinden emin olmak istiyordum.
Progresif Web Uygulamasının ne olduğunu bilmiyorsanız, işte size 'asansör perdesi'. Kavramsal olarak, standart bir web uygulaması hayal edin, ancak bazı belirli kriterleri karşılayan bir uygulama. Bu özel gereksinimler grubuna bağlılık, destekleyici bir cihazın (düşünme cep telefonu) web uygulamasına özel ayrıcalıklar vererek, web uygulamasını parçalarının toplamından daha büyük hale getirmesi anlamına gelir.
Özellikle Android'de, yalnızca HTML, CSS ve JavaScript ile oluşturulmuş bir PWA'yı yerel kodla oluşturulmuş bir uygulamadan ayırt etmek neredeyse imkansız olabilir.
Bir uygulamanın Aşamalı Web Uygulaması olarak kabul edilmesi için gereken Google gereksinimleri listesi aşağıda verilmiştir:
- Site HTTPS üzerinden sunulur;
- Sayfalar tabletlerde ve mobil cihazlarda duyarlıdır;
- Tüm uygulama URL'leri çevrimdışıyken yüklenir;
- Ana Ekrana Ekle için sağlanan meta veriler;
- İlk yükleme, 3G'de bile hızlı;
- Site tarayıcılar arası çalışır;
- Sayfa geçişleri ağda engelleniyormuş gibi gelmiyor;
- Her sayfanın bir URL'si vardır.
Ayrıca, gerçekten öğretmenin evcil hayvanı olmak ve başvurunuzun 'Örnek Aşamalı Web Uygulaması' olarak değerlendirilmesini istiyorsanız, aşağıdaki gereksinimleri de karşılaması gerekir:
- Site içeriği Google tarafından indekslenir;
- Uygun olduğunda Schema.org meta verileri sağlanır;
- Uygun olduğunda sosyal meta veriler sağlanır;
- Kanonik URL'ler gerektiğinde sağlanır;
- Sayfalar Geçmiş API'sini kullanır;
- Sayfa yüklenirken içerik atlamaz;
- Bir ayrıntı sayfasından geri basmak, önceki liste sayfasındaki kaydırma konumunu korur;
- Dokunulduğunda, girişler ekran klavyesi tarafından gizlenmez;
- İçerik, bağımsız veya tam ekran modundan kolayca paylaşılabilir;
- Site, telefon, tablet ve masaüstü ekran boyutları genelinde duyarlıdır;
- Herhangi bir uygulama yükleme istemleri aşırı kullanılmaz;
- Ana Ekrana Ekle istemi engellendi;
- İlk yükleme 3G'de bile çok hızlı;
- Site önbellek öncelikli ağ kullanır;
- Site, çevrimdışı olduklarında kullanıcıyı uygun şekilde bilgilendirir;
- Bildirimlerin nasıl kullanılacağı hakkında kullanıcıya bağlam sağlayın;
- Kullanıcıları Anında Bildirimleri açmaya teşvik eden kullanıcı arayüzü aşırı agresif olmamalıdır;
- Site, izin isteği gösterildiğinde ekranı karartır;
- Anında iletme bildirimleri zamanında, kesin ve alakalı olmalıdır;
- Bildirimleri etkinleştirmek ve devre dışı bırakmak için kontroller sağlar;
- Kullanıcı, Credential Management API aracılığıyla cihazlar arasında oturum açar;
- Kullanıcı, Ödeme İsteği API'sinden yerel UI aracılığıyla kolayca ödeme yapabilir.
Krikey! Seni bilmiyorum ama bu ikinci grup şey, temel bir uygulama için çok fazla iş gibi görünüyor! Olduğu gibi, orada zaten planladığım şeyle alakalı olmayan birçok öğe var. Buna rağmen, sadece ilk testleri geçmek için görüşümü indirdiğimi söylemekten utanmıyorum.
Tüm uygulama türleri bölümü için, bir PWA'nın yerel bir uygulamadan daha uygulanabilir bir çözüm olduğuna inanıyorum. Bir uygulama mağazasında oyunların ve SaaS'ın tartışmasız daha anlamlı olduğu durumlarda, daha küçük yardımcı programlar Web'de Aşamalı Web Uygulamaları olarak oldukça mutlu ve daha başarılı bir şekilde yaşayabilir.
Çok çalışmaktan kaçınmam söz konusuyken, erken yapılan bir başka seçim de uygulama için tüm verileri denemek ve kullanıcının kendi cihazında depolamaktı. Bu şekilde, veri hizmetleri ve sunucuları ile bağlantı kurmak ve oturum açma ve kimlik doğrulama işlemleri ile uğraşmak gerekli olmayacaktır. Becerilerimin bulunduğu yere göre, kimlik doğrulamayı bulmak ve kullanıcı verilerini depolamak, neredeyse kesinlikle çiğneyebileceğimden ve uygulamanın havalesi için aşırıya kaçabileceğimden daha fazlasını ısıracak gibi görünüyordu!
Teknoloji Seçenekleri
Hedefin ne olduğu konusunda oldukça net bir fikirle, onu inşa etmek için kullanılabilecek araçlara dikkat çekildi.
Web sitesinde "... düz JavaScript'i derleyen JavaScript'in yazılı bir üst kümesi" olarak tanımlanan TypeScript'i kullanmaya erkenden karar verdim. Sevdiğim dilin gördükleri ve okudukları, özellikle de kendini statik analize çok iyi öğrendiği gerçeği.
Statik analiz, bir programın, çalıştırmadan önce (örneğin, statik olduğunda) kodunuza bakabileceği ve sorunları vurgulayabileceği anlamına gelir. Mutlaka mantıksal sorunlara işaret edemez, ancak bir dizi kurala karşı uygun olmayan koda işaret edebilir.
Devam ederken (kesinlikle birçok) hatalarıma işaret edebilecek herhangi bir şey iyi bir şey olmalıydı, değil mi?
TypeScript'e aşina değilseniz, Vanilla JavaScript'te aşağıdaki kodu göz önünde bulundurun:
console.log(`${count} players`); let count = 0;
Bu kodu çalıştırın ve şöyle bir hata alacaksınız:
ReferenceError: Cannot access uninitialized variable.
Biraz JavaScript becerisine sahip olanlar için, bu temel örnek için, onlara işlerin iyi bitmeyeceğini söylemek için bir araca ihtiyaçları yoktur.
Ancak, aynı kodu TypeScript'te yazarsanız, düzenleyicide bu gerçekleşir:

Kodu çalıştırmadan önce aptallığım hakkında bazı geri bildirimler alıyorum! Statik analizin güzelliği budur. Bu geri bildirim genellikle, daha deneyimli bir geliştiricinin yanımda oturup hataları yakalaması gibi bir şeydi.
TypeScript öncelikle adından da anlaşılacağı gibi koddaki her şey için beklenen 'type'ı belirtelim. Bu, yanlışlıkla bir türü diğerine 'zorlamanızı' önler. Veya uygulanabilir olmayan bir veri parçası üzerinde bir yöntem çalıştırmaya çalışmak - örneğin bir nesne üzerinde bir dizi yöntemi. Bu, kod çalıştığında mutlaka bir hatayla sonuçlanacak türden bir şey değildir, ancak kesinlikle izlenmesi zor hatalara neden olabilir. TypeScript sayesinde, kodu çalıştırmayı denemeden önce düzenleyicide geri bildirim alırsınız.
TypeScript, bu keşif yolculuğunda kesinlikle gerekli değildi ve açık bir yararı olmadıkça, hiç kimseyi bu tür araçlara atlamaya teşvik etmem. İlk etapta araçları ayarlamak ve araçları yapılandırmak bir zaman kaybı olabilir, bu nedenle dalmadan önce uygulanabilirliklerini kesinlikle göz önünde bulundurun.
TypeScript'in sağladığı başka faydalar da var, bu serinin bir sonraki makalesinde geleceğiz, ancak statik analiz yetenekleri tek başına TypeScript'i benimsemek istemem için yeterliydi.
Yaptığım seçimlerle ilgili önemli düşünceler vardı. Uygulamayı Aşamalı Web Uygulaması olarak oluşturmayı seçmek, Hizmet Çalışanlarını bir dereceye kadar anlamam gerektiği anlamına geliyordu. TypeScript kullanmak, bir tür derleme araçlarını tanıtmak anlamına gelir. Bu araçları nasıl yönetirdim? Tarihsel olarak, NPM'yi paket yöneticisi olarak kullanırdım, peki ya Yarn? Bunun yerine Yarn kullanmaya değer miydi? Performans odaklı olmak, bazı küçültme veya paketleme araçlarını göz önünde bulundurmak anlamına gelir; webpack gibi araçlar giderek daha popüler hale geliyordu ve değerlendirilmesi gerekiyordu.
Özet
Bu göreve başlamanın gerekliliğini fark etmiştim. JavaScript güçlerim zayıftı ve hiçbir şey teoriyi pratiğe dökmeye çalışmak kadar belimi bükemez. Vanilya JavaScript ile bir web uygulaması oluşturmaya karar vermek benim ateş vaftizim olacaktı.
Uygulamayı yapmak için seçenekleri araştırmak ve değerlendirmek için biraz zaman harcadım ve uygulamayı Aşamalı Web Uygulaması yapmanın beceri setim ve fikrin göreceli basitliği için en mantıklısı olduğuna karar verdim.
Derleme araçlarına, bir paket yöneticisine ve ardından çok fazla sabra ihtiyacım var.
Nihayetinde, bu noktada temel soru kaldı: Bu gerçekten başarabileceğim bir şey miydi? Yoksa kendi beceriksizliğim yüzünden alçalır mıydım?
Derleme araçları, JavaScript tasarım kalıpları ve daha "uygulama benzeri" bir şeyin nasıl yapılacağı hakkında okuyabileceğiniz ikinci bölümde bana katılacağınızı umuyorum.