Oca.20

Hızlandırılmış EcmaScript 6+ Dersleri – 10: Modüller (import, export)


Yeni nesil JavaScript Framework’lerin, özellikle de React’ın temelini oluşturan modülleri kullanmanız, her alanda işinizi oldukça kolaylaştıracak ve daha profesyonel, ölçeklendirilebilir ve sürdürülebilir projeler yapmanızı sağlayacaktır.

Modüller, iki veya daha fazla dosya arasında import ve export deyimleri ile fonksiyon ve sınıfların aktarılabilmesini sağlayarak modüler programlamanın temellerini sağlar.

Temel mantığı kavrayarak bir örnek üzerinden modül kullanımını öğrenelim.

İlk Modül Kullanımı ve Sözdizim Yapısını Kavrama

Örneğimizde hesaplama yapan bir modül geliştireceğiz ve arayüzden butonlarla import edeceğimiz fonksiyonları kullanacağız.

Bir klasör içerisinde index.html, index.js ve hesapla.js adında dosyalarımız olsun.

İlk olarak index.html’i temel olarak oluşturalım…

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script type="module" src="index.js"></script>
</head>
<body>
</body>
</html>

hesapla.js

let topla = (sayilar) => {
    let toplam = 0;
    for(let sayi of sayilar){
        toplam += sayi;
    }
    return toplam;
}
export { topla };

İlk olarak topla isminde bir arrow fonksiyonu yazdık, bu örneği daha önce arrow fonksiyonları makalesinde görmüştünüz. Kendisine Array olarak verilen sayıları toplayıp return ediyordu. Ek olarak fonksiyonun dışında export { topla } şeklinde bir tanımlama yaptık. Bunun anlamış topla fonksiyonu dışarıya aktar anlamına gelmektedir. Yani dışarıdan bu fonksiyona erişebileceğiz.

Şimdi de index.js dosyamızı aşağıdaki gibi oluşturalım.

index.js

import { topla } from './hesapla.js';
let sayilar =  [2, 5, 6];
console.log( topla( sayilar ) );

İlk satırda import ile topla isimli fonksiyonu ./ dizini (yani kendi ile aynı seviyede olan dizin)’den hesapla.js isimli dosyadan çektik. İçe çekmek için istediğimiz fonksiyonları süslü parantez içerisinde yazıyoruz (Eğer birden fonksiyon çekilecekse aralarına virgül konur).

Sonuç olarak artık index.html dosyamızı tarayıcıda açıp konsola baktığımızda 13 değerini göreceğiz.

Şimdi aynı örnek üzerinden biraz daha farklı modül özelliklerini inceleyemeye devam edelim…

Çoklu Fonksiyon ve Değişkenleri İçe Aktarmak

Az önce sadece topla isimli bir fonksiyonu import ettik. Şimdi bir de aritmetik ortalama alan ve bir katsayı değerini dışa aktaran kullanım örneği görelim.

hesapla.js dosyamız üzerinden düzenleme yaparak devam edelim (Kodları kitapta tekrar yazmamak adına … ile es geçip yeni kodları göstereceğim).

hesapla.js

const topla = (sayilar) => { … }
const ortalama = (sayilar) => {
    return  topla(sayilar) / sayilar.length;
}
const PI = 3.14;
export { topla, ortalama, PI };

Dikkat edin, let ile tanımladığımız fonksiyonları bu sefer const ile tanımladık. Aslında fonksiyonları hep const ile tanımlamak lazım, çünkü değişken değildir. İkinci olarak ortalama adında bir arrow fonksiyon tanımlayıp yine sayilar parametresini aldık. Fonksiyon içinde yine iteratif olarak tek tek sayıları toplamak yerine zaten bu işi yapan topla fonksiyona sayılarımızı gönderdik ve sonucu da sayilar.length ile toplam eleman sayısını hesap ederek böldük, yani 3’e böldük. İşlem 13/3 şeklinde hesaplanacak. Son olarak export deyiminde de birden fazla fonksiyonu ve bir adet de PI adında sabitimizi süslü parantezler içerisinde dışa çıkardık.

Tekrar index.js dosyamıza dönelim ve aşağıdaki gibi düzenleyelim.

index.js

import { topla, ortalama, PI } from './hesapla.js';
let sayilar =  [2, 5, 6];
console.log( topla( sayilar ) ); // 13
console.log( ortalama( sayilar ) );  // 4.3333333
console.log( PI );  // 3.14

Bu sefer export edilen her iki fonksiyon ve sabit değerimizi içe aktarıp tekrar konsolda yazdırdık.

Çoklu İçe Aktarma İşlemi

Bir önceki örneğimizde import işleminde her bir export edilen fonksiyon ve sabitin ismini tek tek girmiştik. Ancak bazen bu isimler çok fazla olabilir. Her birini tek tek yazmak yerine export edilenlerin hepsini içe aktarmak için *operatörünü kullanabilir ve tüm import edilenleri bir Object’e aktarabiliriz.

index.js dosyamızı aşağıdaki gibi düzenleyelim.

index.js

import * as hesapla from './hesapla.js';
let sayilar =  [2, 5, 6];
console.log( hesapla.topla( sayilar ) );
console.log( hesapla.ortalama( sayilar ) );
console.log( hesapla.PI );

İçe aktarırken * as hesapla yapısı ile bütün export edilenleri as (gibi anlamındadır) deyimi ile hesapla adlı Object’e aktardık. Burada obje adı ve dosya ismi aynı görülüyor, ama zorunlu bir kullanım değildir. Fakat neyi neye aktardım diye sonraları düşünmemek için pratik bir kullanım şeklidir. Fonksiyon ve sabit değerleri objeye aktarıldığı için doğrudan çağırdığımızda hata alırız. Bu nedenle artık hesapla adlı obje içinden hesapla.topla() gibi erişebiliriz.

İçe Aktarılanları Tekrar İsimlendirme

Bir önceki örneğimizde modülü içe aktarıp hesapla isimli bir Object’e aktarmıştık. Şimdi de yine normal olarak import edeceğiz, ancak modül içinde yer alan hesapla, ortalama ve PI’yi farklı isimlerle yeniden adlandıralım. Bu kullanım şekli pek tavsiye edilmiyor, ancak bazı farklı kaynaklardan gelen modülleri kullanmak zorunda kaldığınızda modül içindeki isimlendirmeler size anlamsız geliyor veya sık sık unutuyorsanız, bu metotla daha akılda kalıcı isimler verebilirsiniz.

Değişikliğimizi yine index.js üzerinde yapacağız.

index.js

import { 
    topla as sayilariTopla, 
    ortalama as sayilarinOrtalamasiniAl, 
    PI as piSayisi } from './hesapla.js';
let sayilar =  [2, 5, 6];
console.log( sayilariTopla( sayilar ) );
console.log( sayilarinOrtalamasiniAl( sayilar ) );
console.log( piSayisi )

Süslü parantezler içinde içe aktarılan her bir isim as deyimi ile yeniden adlandırılabilir. Mesela topla fonksiyonu artık sayilariTopla şeklinde çağırabiliriz.

Dikkat edilmesi gereken diğer bir durum ise, import işlemi sırasında as kullanımı ile yeniden adlandırmalar yapıldığında, her bir içe aktarılanı ve yeni ismi yeni bir satırda yazma şeklidir. Bu sayede uzun uzun eklemiş ve tanımlamış olduğunuz isimleri daha rahat görebilirsiniz ve kodunuz daha temiz olur.

Varsayılan Modülü Belirlemek

Son olarak varsayılan bir modül belirleyelim. Her bir modülden sadece bir tane default, yani varsayılan fonksiyon dışa aktarılabilir.

Son hali ile hesapla.js dosyamıza bakalım…

hesapla.js

const varsayilanFonksiyon = () => console.log("Varsayılan fonksiyon çalıştı");
const topla = (sayilar) => {
    let toplam = 0;
    for(let sayi of sayilar){
        toplam += sayi;
    }
    return toplam;
}
const ortalama = (sayilar) => topla(sayilar) / sayilar.length;
const PI = 3.14;
export { topla, ortalama, PI };
export default varsayilanFonksiyon;

Öncelikle fonksiyonlarımızı tek satırda yazarak düzenlediğimize dikkat edin. Zorunlu değil, ancak eğer fonksiyon bloğu tek satır koddan oluşuyorsa süslü parantezlerle blok açmaya gerek yoktur. Böylece okunurluk daha kolay olur.

İlk satırda varsayilanFonksiyon adında bir fonksiyon tanımladık. Genelde default olan fonksiyonların adları main şeklinde olur, ama biz anlaşılır olsun diye daha kolay bir isim girdik. Export ederken de export default şeklinde tanımlama yaptık ve fonksiyon adını süslü parantezler olmadan girdik. Varsayılan olan fonksiyonlarda süslü parantez kullanılmaz.

Şimdi de index.js’in son haline bakalım…

import 
    varsayilanFonksiyon, { 
    topla as sayilariTopa, 
    ortalama as sayilarinOrtalamasiniAl, 
    PI as piSayisi } from './hesapla.js';
let sayilar =  [2, 5, 6];
varsayilanFonksiyon();
console.log( sayilariTopa( sayilar ) );
console.log( sayilarinOrtalamasiniAl( sayilar ) );
console.log( piSayisi );

Bir modülden varsayılan fonksiyonu import ederken yine export işleminde olduğu gibi süslü parantezlerin dışına yazıyoruz.

Makale serimizin diğer konuları şunlar olacaktır:


Web Tasarımı ve Web Programlama 2020

Yorum bırak

Yorum