chevron-left chevron-right

Piotr Nalepa Frontend, architecture and AI

[JS] Jak tworzyć modułowy kod JS z wykorzystaniem require.js?

This version
blog.piotrnalepa.pl/2013/07/17/js-jak-tworzyc-modulowy-kod-js-z-wykorzystaniem-require-js
Published
Author
, Staff Software Engineer
Category
JavaScript
Feedback
Write to me · Post on X

This post is 13 years old. Browsers and tools may have changed since then, so check the code against current documentation before you use it.

Tak jak obiecałem na fanpage'u bloga, w najbliższym czasie możesz się spodziewać większej ilości artykułów dotyczących języka JavaScript.
Dzisiejszy wpis będzie dotyczył tworzenia i korzystania z modułowego kodu JavaScript w aplikacjach internetowych.

Section 1Modułowość kodu JS

Na czym polega modułowość kodu JavaScript w aplikacji internetowej?
Polega ona na tym, aby tak tworzyć kod JavaScript, aby każda jego funkcjonalna część była niezależna od innych oraz aby możliwe było korzystanie z dowolnych modułów w zależności od potrzeb. Takie podejście pozwala na ograniczenie bałaganu w kodzie oraz na tworzenie wydajniejszych aplikacji webowych.

Section 2Kilka słów o AMD

AMD, w tym przypadku, to nie jest nazwa pdoducenta procesorów i kart graficznych. To jest akronim od Asynchronous Module Definition, czyli w wolnym tłumaczeniu - asynchronicznej definicji modułu. Jest to wzorzec tworzenia kodu w języku JavaScript, który pozwala na asynchroniczne, niezależne ładowanie modułów za pomocą mechanizmów ładowania kodu JavaScript (script loaders), takich jak require.js czy curl.js.

Section 3AMD

Wzorzec projektowy dla języka JavaScript, gdzie moduł i jego zależności mogą być ładowane asynchronicznie.

Section 4Tworzenie modułu zgodnego z AMD w JS

W związku z wykorzystywaniem możliwości jakie dają wzozec AMD oraz require.js bardzo często będziesz korzystał z:

  • define() - metody, która jest odpowiedzialna za utworzenie opakowania dla kodu modułu,
  • oraz require() - metody, która jest odpowiedzialna za ładowanie modułów.

Moduł we wzorcu AMD tworzymy za pomocą define(), ktory może przyjąć 3 parametry:

  • opcjonalnie, nazwę modułu,
  • opcjonalnie, tablicę zależnych modułów,
  • definicję funkcji, która inicjalizuje moduł.

Dobrą praktyką jest nazywanie modułu za pomocą ścieżki dostępu do pliku, np. app/modules/module. W ten sposób unikniemy problemów z podobnie nazwanymi modułami, co ma czasem miejsce.
Z kolei tablica zależnych modułów, jest to lista modułów, które są wymagane do tego, aby nasz zdefiniowany moduł działał poprawnie po załadowaniu na stronie.

Przykladowy kod, który przedstawia definicję modułu, może wyglądać następująco:

Example 1JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//moduł znajduje się w pliku app/modules/module.js
define('app/modules/module', ['lib/jquery', 'lib/lodash'], function ($, _)) {
  var module = function () {
    var getName = function () {
      $('body').append('<h1>AMD Module</h1>';
    };
    var makeCalculations = function (type, items) {
      if (type === 'multiply') {
        items = _.map(items, function (item) {
          return item * 2;
        });
      }
      return items;
    }
    return {
      getName     : getName,
      multiplyByTwo   : function (items) {
        return makeCalculations('multiply', items);
      }
    };
  };
});

Jak widać, w powyższym kodzie zdefiniowano moduł o nazwie module, będący zależnym od bibliotek: jQuery oraz lodash, a który definiuje obiekt module wraz z jego metodami, które są dostępne z zewnątrz.
Dla niewtajemniczonych, taka postać tworzenia obiektów jest przykładem wzorca modułu z metodami dostępnymi publicznie, jak i prywatnymi.

Za pomocą define() możemy również tworzyć moduły, które zawierają w sobie inne moduły z ich wlasnymi zależnościami oraz moduły, nie potrzebują na starcie jakichkolwiek innych bibliotek, ale mogą ich potrzebować potem.
Przyklad tego drugiego przypadku wygląda następująco:

Example 2JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//przykład ze strony: http://addyosmani.com/writing-modular-js/
define(function (require) {
  var isReady = false;
  var foobar;
 
  require(['foo', 'bar'], function (foo, bar) {
    isReady = true;
    foobar = foo() + bar();
  });
 
  return {
    isReady : isReady,
    foobar  : foobar
  };
});

Section 5Sposób użycia modułu w kodzie JS

Mając tak przygotowany moduł, możemy się do niego odwołać w następujący sposób:

Example 3JavaScript
1
2
3
4
require(['app/modules/module'], function (Module) {
  var moduleInstance = new Module();
  module.getName();
});

Prosto, łatwo i przyjemnie możemy korzystać z przygotowanych modułów. Dzięki czemu, nie musimy ładować wszystkich plików od razu na starcie aplikacji tylko w razie potrzeby.

Section 6Modułowy kod JS - podsumowanie

Tworząc modulowy kod JavaScrip możemy osiągnąć szereg korzyści, takich jak:

  • Zachowanie globalnej przestrzeni nazw czystej i wolnej od jakichkolwiek dodatkowych zmiennych,
  • Możliwość przenoszenia kodu między projektami, w końcu moduły są bytami niezależnymi (względnie),
  • Dodatkowe pliki, w których znajdują się moduły, nie muszą być ładowane od razu na starcie, lecz mogą być ładowane wedle potrzeby potem.

Share
Feedback

About the author

Staff Software Engineer

I've been writing this blog since 2009 and building for the web professionally for 14 years. Today I lead the frontend of the Cosmos platform at Bishop Fox, where I've been since day one of the project. Before that I worked at OLX, KUDO, Auto1 and eZ Systems. Here I write about what I've learned in practice: JavaScript, TypeScript, React, CSS and frontend architecture. I've also spoken at conferences across Poland and Europe. Got a question or an idea for a post? Let me know!