İçeriğe geç
academia.sh

Ders 20 / 20

Paket Yayımlama

Paket bildiriminin dışa aktarım sözleşmesi, koşullu girişler, iç yolların gizlenmesi, çalıştırılabilir giriş noktası ve yayım öncesi denetim.

İçindekiler

Önceki ders ölçüm toplayıcıyı çalışır ve kapanabilir hâle getirdi. Geriye tek bir soru kalıyor: bu kodun yeniden kullanılabilir bölümü — özetleyici, kütük, hata sınıfları — başka projelere nasıl taşınır?

Yanıt, kodu bir paket sözleşmesiyle sarmalamaktır. Modüller, Araçlar ve Ekosistem kursu paketleri tüketen taraftan anlatmıştı; bu ders yayımlayan tarafa geçer.

Paket Bildirimi Bir Sözleşmedir

Bildirim dosyası, paketin adını ve sürümünü taşımanın ötesinde bir iş görür: paketin dışarıya ne söz verdiğini tanımlar. Modül Çözümleme dersinde bu haritanın tüketici tarafındaki etkisi görülmüştü; burada yazarın kararları ele alınacak.

paket/
  package.json
  kaynak/
    dizin.mjs
    dizin.cjs
    ozet.mjs
    ic-bicim.mjs
// paket/package.json
{
  "name": "olcum-cekirdek",
  "version": "1.2.0",
  "type": "module",
  "engines": { "node": ">=20" },
  "exports": {
    ".": {
      "import": "./kaynak/dizin.mjs",
      "require": "./kaynak/dizin.cjs"
    },
    "./ozet": "./kaynak/ozet.mjs"
  },
  "imports": {
    "#ic/bicim": "./kaynak/ic-bicim.mjs"
  },
  "files": ["kaynak/"]
}
// paket/kaynak/ic-bicim.mjs
export const bicimle = (n) => Number(n.toFixed(2));
// paket/kaynak/ozet.mjs
import { bicimle } from '#ic/bicim';
export const ortalama = (s) => bicimle(s.reduce((t, x) => t + x, 0) / s.length);
// paket/kaynak/dizin.mjs
export const giris = 'ES modul girisi';
// paket/kaynak/dizin.cjs
module.exports = { giris: 'CommonJS girisi' };

Alanların her biri ayrı bir söz verir.

exports, dışarıdan hangi yolların içe aktarılabileceğini sabitler. Haritada olmayan bir dosya, yerinde dursa bile erişilemez. Bu, paketin iç düzenini yeniden düzenleme özgürlüğü verir: harita korunduğu sürece dosyaların yeri değişebilir.

imports, paketin kendi içindeki takma adlarıdır. # ile başlayan bu adlar yalnızca paketin kendi dosyalarından çözülür ve dışarıdan görünmez. Uzun göreli yolları kısaltmanın, dışa açılma riski taşımayan yoludur.

type, uzantısı .js olan dosyaların hangi modül biçiminde yorumlanacağını belirler. Bu alan paketin kendi bildiriminden okunur; onu kullananın bildirimi etkilemez.

engines, paketin hangi çalışma zamanı sürümlerinde sınandığını bildirir. Çalışma zamanı bu alanı zorlamaz; paket yöneticisi kurulumda uyarır veya reddeder. Alan bir belge değil, bir sözdür: kullanılan bir arayüz belirli bir sürümden itibaren bulunuyorsa, alt sınır ona göre yazılır.

files, yayımlanan arşive hangi yolların gireceğini belirler. Testler, örnekler ve geliştirme yapılandırmaları arşiv dışında bırakılır; kullanıcı onları indirmez.

Koşullu Girişler

Kök girişin iki karşılığı var: import ile geldiğinde bir dosya, require ile geldiğinde başka bir dosya çözülür. Bu, aynı paketi iki modül biçiminden de kullanılabilir kılar.

Paketi tüketen bir dizin kuralım. Paket yöneticisi yerel bir paketi bağımlılık dizinine bağ olarak yerleştirir; aynı düzeni elle de kurabiliriz:

mkdir -p paket/tuketen/node_modules
cd paket/tuketen && ln -s ../.. node_modules/olcum-cekirdek
printf '{ "name": "tuketen", "type": "module" }\n' > package.json
// paket/tuketen/dene.mjs
import { giris } from 'olcum-cekirdek';
import { ortalama } from 'olcum-cekirdek/ozet';
import { createRequire } from 'node:module';

const require = createRequire(import.meta.url);

console.log('import kosulu :', giris);
console.log('require kosulu:', require('olcum-cekirdek').giris);
console.log('alt yol       :', ortalama([21.4, 21.9, 22.3]));
cd paket/tuketen && node dene.mjs
import kosulu : ES modul girisi
require kosulu: CommonJS girisi
alt yol       : 21.87

Aynı ad, iki farklı dosyaya çözüldü. Üçüncü satır ise alt yolun çalıştığını ve o modülün iç takma adı üzerinden başka bir dosyayı kullanabildiğini gösteriyor.

İki biçimi birlikte sunmanın bir tuzağı vardır: bir modül aynı süreçte iki kez değerlendirilebilir; Modül Çözümleme dersinde anlatıldığı gibi teklik çözülen adrese bağlıdır ve iki dosya iki ayrı adrestir. Paket durum tutuyorsa — bir sayaç, bir kayıt defteri — iki kopya iki ayrı durum demektir. Durum tutan paketler için tek biçim sunmak daha güvenlidir.

Haritada olmayan yollar erişime kapalıdır:

cd paket/tuketen && node -e "import('olcum-cekirdek/kaynak/ic-bicim.mjs').catch(e => console.log(e.code))"
ERR_PACKAGE_PATH_NOT_EXPORTED

İç takma adlar da dışarıdan çözülemez:

cd paket/tuketen && node -e "import('#ic/bicim').catch(e => console.log(e.code))"
ERR_PACKAGE_IMPORT_NOT_DEFINED

İkinci hata, takma adın tüketen paketin kendi bildiriminde tanımlı olmadığını söylüyor. # ile başlayan adlar her paket için ayrı ayrı tanımlıdır; başka bir paketin iç adları ödünç alınamaz.

Çalıştırılabilir Giriş

Komut Satırı Uygulamaları dersindeki araç bir pakete konulabilir. Bildirimdeki bin alanı, paket kurulduğunda hangi adın hangi dosyaya bağlanacağını söyler:

{
  "name": "olcum-araclari",
  "version": "1.0.0",
  "type": "module",
  "bin": { "olcum-topla": "./kaynak/topla.mjs" },
  "files": ["kaynak/"]
}

İki koşul gerekir. Dosyanın ilk satırında yorumlayıcı bildirimi bulunmalıdır — #!/usr/bin/env node satırı, çekirdeğe dosyanın hangi programla çalıştırılacağını söyler. İkincisi, dosyanın çalıştırma iznine sahip olmasıdır; paket yöneticisi bunu genellikle kurulum sırasında ayarlar, ama depoya doğru izinle işlenmesi güvenlidir.

Kütüphane ile aracı aynı pakette birleştirmek bir seçimdir. Ayrı paketler, kütüphaneyi kullananların araç bağımlılıklarını indirmesini önler; tek paket, sürüm uyumunu kendiliğinden sağlar.

Yayım Öncesi Denetim

Yayım geri alınamayan bir işlemdir: bir sürüm numarası bir kez yayımlanır ve içeriği değiştirilemez. Bu yüzden yayımdan önce dört denetim yapılır.

Arşivin içeriği. files alanı doğru yazılmadığında iki yönlü hata olur: gerekli bir dosya dışarıda kalır ve paket kurulduğunda çalışmaz, ya da gereksiz dosyalar girer ve arşiv şişer. Paket yöneticileri, arşivi üretmeden içeriğini listeleyen bir kuru çalışma kipi sunar; yayımdan önce bu liste okunur.

Giriş noktalarının çalışması. Paketi tüketen küçük bir dizin kurup — yukarıdaki gibi — her girişi içe aktarmak, haritadaki bir yazım yanlışını yayımdan önce yakalar. Yayımlanmış bir paketin girişinin kırık olması, sürüm çekilse bile kullanıcıların önbelleğinde kalır.

Sürüm numarasının anlamı. Modüller, Araçlar ve Ekosistem kursunda anlamlı sürümleme kuralları anlatılmıştı. Yayımlayan taraf için kural şu soruya indirgenir: bu sürüme geçen bir kullanıcının kodu bozulur mu? Bozuluyorsa büyük sürüm artar. Dışa aktarım haritasından bir giriş kaldırmak, bir alanın türünü değiştirmek ve desteklenen en düşük çalışma zamanı sürümünü yükseltmek kırıcı değişikliklerdir.

Gizli değer sızıntısı. Yapılandırma Yönetimi dersindeki ortam dosyası, arşive girmemelidir. Sürüm Kontrolüne Giriş kursundaki yok sayma listesi bu dosyayı depodan uzak tutar; files alanı ise arşivden. İki denetim birbirinin yerine geçmez — depoda bulunmayan bir dosya yerel çalışma dizininde durabilir ve arşive girebilir.

Yayım işleminin kendisi paket yöneticisinin komutudur ve bir kaydın hesabına erişim gerektirir. Erişimin ikinci bir etmenle korunması, yayım hakkının en dar kümeyle sınırlanması ve yayımın el ile değil, sürüm etiketiyle tetiklenen bir otomasyon adımından yapılması yaygın uygulamalardır.

Özet

  • Paket bildirimi, paketin dışarıya verdiği sözü tanımlar; dışa aktarım haritası genel arayüzü sabitler ve iç düzeni yeniden düzenleme özgürlüğü verir.
  • Koşullu girişler aynı paketi iki modül biçiminden kullanılabilir kılar; durum tutan paketlerde iki kopya iki ayrı durum anlamına gelir.
  • # ile başlayan iç takma adlar yalnızca kendi paketinden çözülür; başka paketten erişilemez.
  • Çalıştırılabilir giriş, ad ile dosya eşlemesi, yorumlayıcı bildirimi ve çalıştırma izni olmak üzere üç koşula bağlıdır.
  • Yayım geri alınamaz; arşiv içeriği, giriş noktaları, sürüm numarasının anlamı ve gizli değer sızıntısı yayımdan önce denetlenir.

Kurs Kapanışı

Kurs, tek bir soruyla başladı: aynı dil, tarayıcı yerine bir sunucu sürecinde çalıştığında ne değişir? Yanıt üç katmanda kuruldu.

Çalışma zamanı modeli. Barındıran ortam kavramı, dil çekirdeğini dış dünyaya erişimden ayırdı. Olay döngüsünün aşamaları ölçüldü; zamanlayıcı gecikmesinin bir alt sınır olduğu ve engelleyen işin bu sınırı kendi süresi kadar büyüttüğü gösterildi. Süreç nesnesi, argümanları, ortamı, akışları ve çıkış kodunu programın eline verdi. Modül çözümleme, bir adın hangi dosyaya karşılık geldiğini kesinleştirdi.

Yerleşik modüller. Dosya sistemi üç arayüzüyle ele alındı ve seçim ölçütü olay döngüsüne bağlandı. Yollar veri olarak işlendi; kök dizin dışına çıkışı engelleyen denetim yazıldı. Akışlar, parça sınırının kayıt sınırından farklı olduğu gözlemiyle kuruldu ve geri basınç ölçüldü: dönüş değerini yok sayan üretici tamponu elli kayda çıkarırken, dinleyen üretici dördü aşmadı. Arabellekler ham baytı, olay yayıcı gözlemci kalıbını, HTTP sunucusu istek ve yanıtın akış doğasını getirdi. Alt süreçler ve çok çekirdek kullanımı, işi sürecin dışına çıkarmanın iki yolunu ayırdı.

Uygulama yazımı. Komut satırı arayüzü, yapılandırma, hata sınıflandırması, yapılandırılmış kütük, test, profilleme, zarif kapanma ve paketleme — hepsi tek bir somut iş üzerinde geliştirildi. Ölçüm toplayıcı, on iki satırlık bir dosyayı okuyan bir betikten başlayıp; akışla okuyan, HTTP üzerinden sunan, sınanan, izlenen ve sinyal aldığında süren isteklerini tamamlayarak kapanan bir hizmete dönüştü.

Bu kurs, JavaScript ve TypeScript müfredatının son kursudur. Buradan iki yön açılır.

Frontend Geliştirme müfredatı, aynı dilin öbür barındıran ortamına döner: belge yapısı, oluşturma stratejileri, bileşen mimarisi, erişilebilirlik ve başarım. Bu kursta öğrenilen modül çözümleme, paketleme ve olay modeli oradaki yapı araçlarının dayanağıdır.

Backend Geliştirme müfredatı ise bu kursun bıraktığı yerden sürer: burada elle kurulan istek dağıtımı, yapılandırma, günlükleme ve hata katmanı orada bir uygulama mimarisi olarak ele alınır; üstüne API sözleşmesi, veri erişimi, kimlik doğrulama, eşzamansız işleme ve gözlemlenebilirlik katmanları eklenir. Ölçüm toplayıcının /ozet ucu, orada tasarımı gerekçelendirilen bir kaynak modelinin ilk örneğidir.

İki yönde de bu kursta kurulan model geçerli kalır: olay güdümlü, tek iş parçacıklı, akışlarla çalışan bir çalışma zamanı. Çerçeveler ve kütüphaneler bu modeli gizler, değiştirmez — ve gizlenmiş bir modelin arızası, ancak modeli bilen tarafından çözülür.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat