JavaScript Module, yapısının amacı JavaScript kodlarını farklı sayfalara bölerek istenilen sayfadan çağırılarak kullanılmasını sağlamaktır. Böylece alakalı işlemler bir araya toplanarak bir düzen sağlanır, değişiklik gerektiğinde bakım kolaylığı sağlar ve yazılan kodlar yeniden kullanılabilir. Kısaca javascript kodlarını farklı js dosyalarına bölerek kullanılmasını sağlar. Module yapısı 2015 yılında yayımlanmıştır. Önceki yıllarda bu özellik JavaScript dilinde bulunmamaktadır ve aynı yapıyı sağlamak için asenkron modül tanımlama (AMD), CommonJS ve universal modül tanımlama (UMD) yapıları kullanılmıştır. JavaScript Modül Pattern (Anonim Closure) kullanımı da benzer işlevi sağlamak için kullanılmıştır.

JavaScript Module Pattern

JavaScript Module Patterni, benzer işlevdeki metot ve değişkenleri tek bir kapsamda toplayıp kullanmayı sağlar. Bu pattern ile gizli metot ve değişken tanımlanabilir;

JavaScript Module Pattern örneği, modül dışından erişilmek istenen fonksiyon ve değişkenler return ile döndürülmelidir. Geri döndürülmeyenler modül dışından erişilemezler ve kullanılamazlar;

Kod

// myGreetModule.js

var greetModule = (function(){
    'use strict'
    
    var _message = "Merhaba ";
    
    var greet = function(name){
        return _message + name;
    }
    
    return { greeting: greet }
    
})();

JavaScript Module Pattern kullanım örneği, dışarıya açılan (public) metot kullanılabilirdir;

Kod

// index.html

<!DOCTYPE html>
<html lang="tr">
<body>

    <script type="text/javascript" src="myGreetModule.js"></script>
    <script type="text/javascript">
    
        var result = greetModule.greeting('Kamil');
        console.log(result);        // Merhaba Kamil
    
        var result2 = greetModule.greeting('Aydan');
        console.log(result2);        // Merhaba Aydan
    
    </script>
    
</body>
</html>

JavaScript Module Pattern örneği, return komutu ile birden fazla değişken ve fonksiyon dışarıya açılabilir;

Kod

// melihsafran.ajax.helper.js

var ajaxHelper = (function () {

    // AJAX Helper

    // Vanilla AJAX GET Request Function
    var get = function (url, success, error) {
        var xHttpRequest = new XMLHttpRequest();
        xHttpRequest.open('GET', url);
        xHttpRequest.onreadystatechange = function()
        {
            if (this.readyState == 4) {
                if (this.status >= 200 && this.status < 400) {
                    success(this.responseText);
                }
                else {
                    error(this.status);
                }    
            }
        };
        xHttpRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xHttpRequest.send();
        return xHttpRequest;
    };
    
    // Vanilla AJAX POST Request Function    
    var post = function (url, data, success, error) {
        var params = typeof data == 'string' ? data : Object.keys(data).map(
                function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) }
            ).join('&');

        var xHttpRequest = new XMLHttpRequest();
        xHttpRequest.open('POST', url);
        xHttpRequest.onreadystatechange = function() {
            if (this.readyState == 4) {
                if (this.status >= 200 && this.status < 400) {
                    success(this.responseText);
                }
                else {
                    error(this.status);
                }
            }
        };
        xHttpRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
        xHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xHttpRequest.send(params);
        return xHttpRequest;
    }

    return { get, post };

})();

JavaScript Module Pattern kullanım örneği, return komutu ile birden fazla değişken ve fonksiyon dışarıya açılabilir; dışarıya açılan (public) metot kullanılabilirdir;

Kod

// index.html

<!DOCTYPE html>
<html lang="tr">
<body>

    <script type="text/javascript" src="melihsafran.ajax.helper.js"></script>
    <script type="text/javascript">
    
        ajaxHelper.get('https://jsonplaceholder.typicode.com/todos',
            function(responseData){
                var json = JSON.parse(responseData);
                console.log(json);
            },
            function(errorStatus){
                console.log('Hata oluştu: ', errorStatus);
            }
        );
        
        ajaxHelper.post('https://jsonplaceholder.typicode.com/todos', { id: 2, userId: 2, title: 'lorem ipsum dolor sit amet', completed: false },
            function(responseData){
                var json = JSON.parse(responseData);
                console.log(json);
            },
            function(errorStatus){
                console.log('Hata oluştu: ', errorStatus);
            }
        );
    
    </script>
    
</body>
</html>

Module Export

JavaScript modülleri ise export ve import söz dizimini kullanır. EcmaScript 2015 ile module yapısı 2015 yılında yayımlanmıştır ve 2019 yılında da Node.js üzerinde kullanılmaya başlanmıştır. Export ifadesi ile javascript dosyasındaki hangi değişken ve fonksiyonların sayfa dışından erişilebileceği belirlenir. Export edilmeyen değişken ve fonksiyonlar sayfa dışından erişilemezler. Import ifadesi ile javascript dosyasında export edilen değişken ve fonksiyonların çağırıldığı dosyada kullanımı sağlanır.

JavaScript sayfasındaki istenen değişken ve fonksiyonlar export komutu ile farklı dosyaya aktarılır. Default Export ve Named Export olmak üzere iki farklı export yöntemi bulunmaktadır;

Default Export

Default export yöntemi ile dosyadan sadece tek değer döndürülebilir;

Kod

// greet.js

var _message = "Merhaba ";
    
var greeting = function(name){
    return _message + name;
}
    
export default greeting;

Named Export

Named export yöntemi ile dosyadan birden fazla değer döndürülebilir;

Kod

// greet.js

var _message = "Merhaba ";
    
var greeting = function(name){
    return _message + name;
}

var sayHi = function(){
    return _message;
}
    
export { greeting, sayHi };

Module Import

Import ile javascript modül dosyasından istenilen değerler alınarak kullanılır; Import edilirken yazılan değişken isimleri, default export edilerek dönen değerlerin için farklı olabilir fakat named export dönenler aynı isimde import edilmek zorundadır.

Kod

// index.html

<!DOCTYPE html>
<html lang="tr">
<body>
    <script type="module">
    
        import { greeting } from './greet.js'
    
        var result = greeting('Kamil');
        
        console.log(result);        // Merhaba Kamil
        
    </script>
</body>
</html>

Modül dosyası içindeki tüm değerlerin import etmek için * as söz dizimi kullanılır;

Kod

// index.html

<!DOCTYPE html>
<html lang="tr">
<body>
    <script type="module">
    
        import * as greetings from './greet.js'
    
        var result = greetings.greeting('Kamil');
        console.log(result);        // Merhaba Kamil
        
        var result2 = greetings.sayHi();
        console.log(result2);        // Merhaba
        
    </script>
</body>
</html>

Import edilen değişken isimleri as söz dizimi ile farklı isimdeki değişkenlere alınabilir. Böylece aynı isimdeki değişkenlerin çakışmaları önlenebilir.

Kod

import { greeting as greetByName } from './greet.js'
import { greeting } from './main.js'

Uzak sunucudaki modül dosyasının import edilebilir;

Kod

import { greeting } from "https://example.com/modules/greet.js";

Dinamik Modül Yükleme

import() fonksiyonu ile modül dosyaları dinamik olarak istenildiği zaman yüklenebilir. Böylece ilgili modül dosyası sadece ihtiyaç olduğu anda yüklenip çalıştırılabilir.

Kod

//index.html

<!DOCTYPE html>
<html lang="tr">
<head>
    <script type="module" src="main.js"></script>
</head>
<body>

    <button class="greet">Selamla</button>

</body>
</html>

Dinamik modül dosyası yükleme örneği, istenen dosya butona tıklanarak dinamik şekilde yüklenebilir;

Kod

// main.js

const btnGreet = document.querySelector('.greet');

btnGreet.addEventListener('click', () => {

    import('./greet.js').then((Module) => {
    
        var result = Module.greeting('Kamil');
        console.log(result);        // Merhaba Kamil
    
    });
});

Asenkron Modül Yükleme

JavaScript modülleri, async/await yapısını destekleğiniden birden fazla dosya asenkron şekilde yüklenebilir;

Kod

// colors.json

{
    "yellow": "#F4D03F",
    "green": "#52BE80",
    "blue": "#5499C7",
    "red": "#CD6155",
    "orange": "#F39C12"
}

Kod

// getColors.js

// fetch request
const colors = fetch('../data/colors.json')
    .then((response) => response.json());

export default await colors;

Kod

// main.js

import colors from './modules/getColors.js';
import { greeting } from './greet.js';

Kaynaklar

  1. JavaScript Module Pattern Basics , coryrylan.com, 25.12.2022 tarihinde alındı.
  2. Modules , javascript.info, 25.12.2022 tarihinde alındı.
  3. JavaScript module , zetcode.com, 25.12.2022 tarihinde alındı.
  4. JavaScript Modules , w3schools.com, 25.12.2022 tarihinde alındı.
  5. JavaScript Modül Sistemi (ES Modules) Nedir? , devnot.com, 25.12.2022 tarihinde alındı.
  6. Default vs. Named Export. What Is The Difference? , vhudyma-blog.eu, 25.12.2022 tarihinde alındı.
  7. JavaScript modules , developer.mozilla.org, 25.12.2022 tarihinde alındı.


Beğen