SlideShare a Scribd company logo
JavaScript, Moduły
Organizacja kodu pod serwer i przeglądarkę




                         meetjs · Listopad 2011 · Warszawa
Mariusz Nowak
mariusz@medikoo.com



   @medikoo


   github.com/medikoo


Programista JavaScript w Roche Sp. z o.o.
Przeglądarka
Na samym początku była przeglądarka.
Organizacja kodu, jak to (przeważnie) wyglądało (?)
Przeglądarka
Na samym początku była przeglądarka.
Organizacja kodu, jak to (przeważnie) wyglądało (?)

• Łączenie plików
Przeglądarka
Napisanych mniej więcej tak:
MAIN.module = (function() {
    var privateVar = '..';

   var privateMethod = function (args) {
       // ...
   };

   return {
       publicProperty: '..',
       publicMethod: function () {
           // ...
       }
   };

}());
Przeglądarka
Na samym początku była przeglądarka,
Organizacja kodu, jak to (przeważnie) wyglądało (?)

• Łączenie plików
Przeglądarka
Na samym początku była przeglądarka,
Organizacja kodu, jak to (przeważnie) wyglądało (?)

• Łączenie plików
• Wzorzec modułu (Module pattern)
Serwer
Początek roku 2009
• Wiele dostępnych implementacji: Rhino, Spidermonkey, V8, JSCore
• Brak jasno określonych standardów
• Programiści chcą pisać moduły, które mogą być uruchomione w
dowolnej implementacji
Serwer
Początek roku 2009
• Wiele dostępnych implementacji: Rhino, Spidermonkey, V8, JSCore
• Brak jasno określonych standardów
• Programiści chcą pisać moduły, które mogą być uruchamiane w
dowolnej implementacji
• Pojawia się potrzeba stworzenia podłoża pod ekosystem podobny do
tego jaki ma Python, Ruby czy Java
Serwer
Początek roku 2009
• Wiele dostępnych implementacji: Rhino, Spidermonkey, V8, JSCore
• Brak jasno określonych standardów
• Programiści chcą pisać moduły, które mogą być uruchamiane w
dowolnej implementacji
• Pojawia się potrzeba stworzenia podłoża pod ekosystem podobny do
tego jaki ma Python, Ruby czy Java
• Powstaje grupa ServerJS, przemianowana później na CommonJS
-> http://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/
Serwer
Grupa CommonJS przygotowuje między innymi specyfikację
modułów. -> http://www.commonjs.org/specs/modules/1.0/
Serwer
Grupa CommonJS przygotowuje między innymi specyfikację
modułów. -> http://www.commonjs.org/specs/modules/1.0/

add.js
exports.add = function() {
     var sum = 0, i = 0, args = arguments, l = args.length;
     while (i < l) sum += args[i++];
     return sum;
};

increment.js
var add = require('add').add;
exports.increment = function(val) {
     return add(val, 1);
};

program.js
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
Serwer
Mniej więcej w tym samym czasie powstaje Node.js, który
implementuje Moduły z CommonJS

add.js
exports.add = function() {
     var sum = 0, i = 0, args = arguments, l = args.length;
     while (i < l) sum += args[i++];
     return sum;
};

increment.js
var add = require('add').add;
exports.increment = function(val) {
     return add(val, 1);
};

program.js
var inc = require('increment').increment;
var a = 1;
inc(a); // 2
Serwer
Mniej więcej w tym samym czasie powstaje Node.js, który
implementuje Moduły z CommonJS
... z pewnymi udogodnieniami
add.js
module.exports = function() {
     var sum = 0, i = 0, args = arguments, l = args.length;
     while (i < l) sum += args[i++];
     return sum;
};

increment.js
var add = require('./add');
module.exports = function(val) {
     return add(val, 1);
};

program.js
var inc = require('./increment');
var a = 1;
inc(a); // 2
Serwer
Jak to działa:



   // increment.js
   var add = require('./add');
   module.exports = function (val) {
       return add(val, 1);
   };
Serwer
Jak to działa:
var exports, module;
function (exports, require, module) {

   // increment.js
   var add = require('./add');
   module.exports = function (val) {
       return add(val, 1);
   };

}.call(exports = {}, exports, function (path) {
 // import zewnętrznego modułu
}, module = { exports: exports });

MODULE = module.exports;
Serwer
Wróćmy do wzorca Modułu.
Serwer
Wróćmy do wzorca Modułu.
module.js
MAIN.module = (function() {
    var privateVar = '..';
    var privateMethod = function (args) {
        // ...
    };
    return {
        publicProperty: '..',
        publicMethod: function () {
            // ...
        }
    };
}());
Serwer
Wzorzec modułu jako moduł CommonJS:
module.js

var privateVar = '..';
var privateMethod = function (args) {
    // ...
};

exports.publicProperty: '..',
exports.publicMethod: function () {
    // ...
};

program.js
var foobar = require(‘./module’);
Serwer
Wzorzec modułu jako moduł CommonJS:
module.js

var privateVar = '..';
var privateMethod = function (args) {
    // ...
};

exports.publicProperty: '..',
exports.publicMethod: function () {
    // ...
};

program.js
var foobar = require(‘./module’);
    ↑ sami decydujemy jaką nazwą chcemy odwoływać się do zaciągniętego
modułu.
Serwer
Moduły CommonJS to bardzo udana specyfikacja.
Co zyskujemy ?
Serwer
Moduły CommonJS to bardzo udana specyfikacja.
Co zyskujemy ?

Przede wszystkim przejrzystość kodu i enkapsulacja na
najlepszym możliwym (w JavaScript) poziomie
Serwer
Moduły CommonJS to bardzo udana specyfikacja.
Co zyskujemy ?

Przede wszystkim przejrzystość kodu i enkapsulacja na
najlepszym możliwym (w JavaScript) poziomie

• Nie ma potrzeby tworzenia zbędnych “wrapper’ów” by pracować w
“swoim” zakresie zmiennych
Serwer
Moduły CommonJS to bardzo udana specyfikacja.
Co zyskujemy ?

Przede wszystkim przejrzystość kodu i enkapsulacja na
najlepszym możliwym (w JavaScript) poziomie

• Nie ma potrzeby tworzenia zbędnych “wrapper’ów” by pracować w
“swoim” zakresie zmiennych
• Nie toniemy w długich przestrzeniach nazw - każdy potrzebny
zewnętrzny moduł przypisujemy do lokalnej zmiennej
Serwer
Moduły CommonJS to bardzo udana specyfikacja.
Co zyskujemy ?

Przede wszystkim przejrzystość kodu i enkapsulacja na
najlepszym możliwym (w JavaScript) poziomie

• Nie ma potrzeby tworzenia zbędnych “wrapper’ów” by pracować w
“swoim” zakresie zmiennych
• Nie toniemy w długich przestrzeniach nazw - każdy potrzebny
zewnętrzny moduł przypisujemy do lokalnej zmiennej
• Możemy zbudować dużą, złożoną aplikację, nie dotykając globalnej
przestrzeni nazw
Serwer i Przeglądarka
Jak uruchomić tak napisany kod pod przeglądarką ?
Serwer i Przeglądarka
Jak uruchomić tak napisany kod pod przeglądarką ?

Kiedy zainteresowałem się CommonJS oraz Node.js
(początek 2011), byłem przekonany, że już istnieje solidne
rozwiązanie.
Serwer i Przeglądarka
Jak uruchomić tak napisany kod pod przeglądarką ?

Kiedy zainteresowałem się CommonJS oraz Node.js
(początek 2011), byłem przekonany, że już istnieje solidne
rozwiązanie.

Znalazłem ok. 8-10 rozwiązań próbujących robić coś
podobnego, jednak żadne nie było satysfakcjonujące
Serwer i Przeglądarka
Główny problem polegał na tym, że każde rozwiązanie
próbowało być czymś więcej niż parserem zależności
modułów CommonJS.
Serwer i Przeglądarka
Główny problem polegał na tym, że każde rozwiązanie
próbowało być czymś więcej niż parserem zależności
modułów CommonJS.

Sama implementacja parsera w każdym rozwiązaniu, też
niestety pozostawiała wiele do życzenia.
Serwer i Przeglądarka
Najciekawsze rozwiązania
Serwer i Przeglądarka
Najciekawsze rozwiązania

Browserify -> https://github.com/substack/node-browserify
Serwer i Przeglądarka
Najciekawsze rozwiązania

Browserify -> https://github.com/substack/node-browserify

Bardzo ciekawe narzędzie jeśli chcemy wykorzystać moduły dostarczane
z Node.js. Browserify stara się umożliwić działanie takiego kodu po
stronie przeglądarki - taki też był główny zamysł projektu
Serwer i Przeglądarka
Najciekawsze rozwiązania

Browserify -> https://github.com/substack/node-browserify

Bardzo ciekawe narzędzie jeśli chcemy wykorzystać moduły dostarczane
z Node.js. Browserify stara się umożliwić działanie takiego kodu po
stronie przeglądarki - taki też był główny zamysł projektu

Dość duża ilość kodu, obsługującego moduły po stronie przeglądarki (ok.
320 linii).
Serwer i Przeglądarka
Najciekawsze rozwiązania

Browserify -> https://github.com/substack/node-browserify

Bardzo ciekawe narzędzie jeśli chcemy wykorzystać moduły dostarczane
z Node.js. Browserify stara się umożliwić działanie takiego kodu po
stronie przeglądarki - taki też był główny zamysł projektu

Dość duża ilość kodu, obsługującego moduły po stronie przeglądarki (ok.
320 linii).

Niestety nie radzi sobie z niektórymi ścieżkami (nie sczytuje modułów z
zewnętrznych pakietów ?)
Serwer i Przeglądarka
AMD czyli Asynchronous Module Definition
Serwer i Przeglądarka
AMD czyli Asynchronous Module Definition

Ostatnio pojawiło się wiele materiałów na ten temat:

http://addyosmani.com/writing-modular-js/

http://blog.millermedeiros.com/2011/09/amd-is-better-for-the-web-than-commonjs-
modules/

http://unscriptable.com/index.php/2011/09/30/amd-versus-cjs-whats-the-best-
format/
Serwer i Przeglądarka
AMD ?
Serwer i Przeglądarka
AMD ?
Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży
modułów AMD
Serwer i Przeglądarka
AMD ?
Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży
modułów AMD
Serwer i Przeglądarka
AMD ?
Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży
modułów AMD

AMD ma nie wiele wspólnego z Modułami CommonJS, wymaga innej
dyscypliny pisania kodu
Serwer i Przeglądarka
AMD ?
Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży
modułów AMD

AMD ma nie wiele wspólnego z Modułami CommonJS, wymaga innej
dyscypliny pisania kodu

• Wszystkie zależności deklarujemy na początku modułu
Serwer i Przeglądarka
AMD ?
Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży
modułów AMD

AMD ma nie wiele wspólnego z Modułami CommonJS, wymaga innej
dyscypliny pisania kodu

• Wszystkie zależności deklarujemy na początku modułu
W modułach CommonJS możemy sięgać po zewnętrzne moduły w dowolnym miejscu
- podobnie będzie w Harmony
Serwer i Przeglądarka
AMD ?
Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży
modułów AMD

AMD ma nie wiele wspólnego z Modułami CommonJS, wymaga innej
dyscypliny pisania kodu

• Wszystkie zależności deklarujemy na początku modułu
W modułach CommonJS możemy sięgać po zewnętrzne moduły w dowolnym miejscu
- podobnie będzie w Harmony

• Ponownie każdy moduł musimy owijać funkcją deklarującą moduł
Serwer i Przeglądarka
Dlaczego tak jest ?
Serwer i Przeglądarka
Dlaczego tak jest ?

AMD próbuje rozwiązywać dwa problemy:

• Modularyzacja/Organizacja kodu
• Dynamiczne dociąganie zależności (na żądanie)
Serwer i Przeglądarka
Dlaczego tak jest ?

AMD próbuje rozwiązywać dwa problemy:

• Modularyzacja/Organizacja kodu
• Dynamiczne dociąganie zależności (na żądanie)
Brzmi obiecująco, ale czy warto ?
Serwer i Przeglądarka
Jak wygląda AMD ?
Serwer i Przeglądarka
Jak wygląda AMD ?
add.js
define(function () {
     return function() {
          var sum = 0, i = 0, args = arguments, l = args.length;
          while (i < l) sum += args[i++];
          return sum;
     };
});

increment.js
define(['add'], function (add) {
     return function(val) {
          return add(val, 1);
     };
});

program.js
define(['increment'], function (inc) {
     var a = 1;
     inc(a); // 2
});
Serwer i Przeglądarka
Najpopularniejsza implementacja -> http://requirejs.org/
wymaga od nas wciągnięcia do przeglądarki ok 2000 linii
kodu
Serwer i Przeglądarka
Najpopularniejsza implementacja -> http://requirejs.org/
wymaga od nas wciągnięcia do przeglądarki ok 2000 linii
kodu

... tylko po to byśmy mogli uruchomić właściwy kod
Serwer i Przeglądarka
Najpopularniejsza implementacja -> http://requirejs.org/
wymaga od nas wciągnięcia do przeglądarki ok 2000 linii
kodu

... tylko po to byśmy mogli uruchomić właściwy kod

... którego i tak bez kompilacji dodatkowym narzędziem
nie będziemy mogli wykorzystać po stronie serwera (w
Node.js).
Serwer i Przeglądarka
Ok, ale co z dynamicznym doładowywaniem zależności ?
Taki jest przecież główny cel i przyczyna złożoności AMD.
Serwer i Przeglądarka
Ok, ale co z dynamicznym doładowywaniem zależności ?
Taki jest przecież główny cel i przyczyna złożoności AMD.


Dynamiczne doładowywanie powinno się rozgrywać na
poziomie funkcjonalności nie na poziomie modułów.
Serwer i Przeglądarka
Ok, ale co z dynamicznym doładowywaniem zależności ?
Taki jest przecież główny cel i przyczyna złożoności AMD.


Dynamiczne doładowywanie powinno się rozgrywać na
poziomie funkcjonalności nie na poziomie modułów.

              (takie jest przynajmniej moje zdanie ;)
Serwer i Przeglądarka
Podsumowanie:
Serwer i Przeglądarka
Podsumowanie:

Brakuje lekkiej i czystej implementacji modułów CommonJS
(precyzyjniej modułów Node.js),
Serwer i Przeglądarka
Podsumowanie:

Brakuje lekkiej i czystej implementacji modułów CommonJS
(precyzyjniej modułów Node.js),

Implementacji, która nie próbuje dodatkowym kosztem
rozwiązywać innych problemów.
Serwer i Przeglądarka
Podsumowanie:

Brakuje lekkiej i czystej implementacji modułów CommonJS
(precyzyjniej modułów Node.js),

Implementacji, która nie próbuje dodatkowym kosztem
rozwiązywać innych problemów.

Kod wiążący moduły powinien być minimalny, niezauważalny w
porównaniu do kodu aplikacji.
Serwer i Przeglądarka
Ostatecznie narodził się nowy projekt:
Serwer i Przeglądarka
Ostatecznie narodził się nowy projekt:

modules-webmake ->
https://github.com/medikoo/modules-webmake

npm install -g webmake
Modules Webmake
modules-webmake buduje drzewo zależności między modułami i
wypluwa je jako jeden plik wykonywalny po stronie przeglądarki.
Modules Webmake
modules-webmake buduje drzewo zależności między modułami i
wypluwa je jako jeden plik wykonywalny po stronie przeglądarki.

Obecna implementacja jest bardzo podstawowa, można powiedzieć
jesteśmy na starcie.
Modules Webmake
modules-webmake buduje drzewo zależności między modułami i
wypluwa je jako jeden plik wykonywalny po stronie przeglądarki.

Obecna implementacja jest bardzo podstawowa, można powiedzieć
jesteśmy na starcie.

Nie przeszkadza to jednak w budowaniu dużych aplikacji, złożonych
z kilkuset modułów, pochodzących z kilkunastu pakietów
(package’y)
Modules Webmake
modules-webmake buduje drzewo zależności między modułami i
wypluwa je jako jeden plik wykonywalny po stronie przeglądarki.

Obecna implementacja jest bardzo podstawowa, można powiedzieć
jesteśmy na starcie.

Nie przeszkadza to jednak w budowaniu dużych aplikacji, złożonych
z kilkuset modułów, pochodzących z kilkunastu pakietów
(package’y)

Z modules-webmake już teraz możecie budować duże, złożone
aplikacje
Modules Webmake
Jak wygląda wygenerowany plik ?
Modules Webmake
Jak wygląda wygenerowany plik ?
(function (modules) {

    // 53 linie kodu obsługującego zależności
})
({
     "root": {
          "add.js": function (exports, module, require) {
               module.exports = function () {
                    var sum = 0, i = 0, args = arguments, l = args.length;
                    while (i < l) sum += args[i++];
                    return sum;
               };
          },
          "increment.js": function (exports, module, require) {
               var add = require('./add');
               module.exports = function (val) {
                    return add(val, 1);
               };
          },
          "program.js": function (exports, module, require) {
               var inc = require('./increment');
               var a = 1;
               inc(a); // 2
          }
     }
})
("root/program");
Modules Webmake
Jak wygląda wygenerowany plik ?
(function (modules) {

    // 53 linie kodu obsługującego zależności
})
({
     "root": {
          "add.js": function (exports, module, require) {
               module.exports = function () {
                    var sum = 0, i = 0, args = arguments, l = args.length;
                    while (i < l) sum += args[i++];
                    return sum;
               };
          },
          "increment.js": function (exports, module, require) {
               var add = require('./add');
               module.exports = function (val) {
                    return add(val, 1);
               };
          },
          "program.js": function (exports, module, require) {
               var inc = require('./increment');
               var a = 1;
               inc(a); // 2
          }
     }
})
("root/program"); <- Wykonanie modułu inicjującego aplikację
Modules Webmake
• modules-webmake może być wykorzystywany zarówno z poziomu konsoli jak i
programistycznie - możemy podczepić narzędzie bezpośrednio pod serwer http w
Node.js i tym samym skonfigurować automatyczne generowanie plików
Modules Webmake
• modules-webmake może być wykorzystywany zarówno z poziomu konsoli jak i
programistycznie - możemy podczepić narzędzie bezpośrednio pod serwer http w
Node.js i tym samym skonfigurować automatyczne generowanie plików

• Zależności są parsowane statycznie, stwarza to pewne ograniczenia. Dla
specyficznych przypadków możemy wymusić dociągnięcie wybranych zależności
opcją ‘include’
Modules Webmake
• modules-webmake może być wykorzystywany zarówno z poziomu konsoli jak i
programistycznie - możemy podczepić narzędzie bezpośrednio pod serwer http w
Node.js i tym samym skonfigurować automatyczne generowanie plików

• Zależności są parsowane statycznie, stwarza to pewne ograniczenia. Dla
specyficznych przypadków możemy wymusić dociągnięcie wybranych zależności
opcją ‘include’

• modules-webmake sczytuje zależności z lokalnego pakietu jak i z zewnętrznych
pakietów, jedynym ograniczeniem (obecnie) jest to, że nie rozróżnia dwóch różnych
wersji tego samego pakietu.
Modules Webmake
• modules-webmake może być wykorzystywany zarówno z poziomu konsoli jak i
programistycznie - możemy podczepić narzędzie bezpośrednio pod serwer http w
Node.js i tym samym skonfigurować automatyczne generowanie plików

• Zależności są parsowane statycznie, stwarza to pewne ograniczenia. Dla
specyficznych przypadków możemy wymusić dociągnięcie wybranych zależności
opcją ‘include’

• modules-webmake sczytuje zależności z lokalnego pakietu jak i z zewnętrznych
pakietów, jedynym ograniczeniem (obecnie) jest to, że nie rozróżnia dwóch różnych
wersji tego samego pakietu.

• Pełniejsza dokumentacja zawsze dostępna pod adresem:
https://github.com/medikoo/modules-webmake
Modules Webmake
Na początku tego miesiąca skończyłem pracę nad aplikacją budowaną z pomocą
modules-webmake.


• Aplikacja HTML5, adresowana tylko pod nowoczesne przeglądarki (Najnowsze
wersje FF, Chrome i Safari (OSX oraz iOS))

• Tryb offline, wymusza to przeniesienie całej logiki aplikacji, wraz z szablonami i
prostym silnikiem bazy danych na stronę klienta.

• Strona serwera obsługiwana przez Node.js zajmuje się synchronizacją klientów
oraz zapisywaniem zmian do fizycznej bazy danych (mongodb)

• Minimalistyczna komunikacja klient-serwer oparta na socket’ach (obecnie
Socket.IO)
Modules Webmake
Plik wynikowy po stronie klienta obecnie, wykorzystuje 273 moduły z 19 pakietów.

176 powyższych modułów pracuje również po stronie serwera.
Daje to w przybliżeniu ok 60% kodu wykorzystywanego po obu stronach.

Połączony plik składa się z ok 11 tysięcy linii kodu
Zajmuje, ok 370kB przed minifikacją i spakowaniem.

Jest to dość obiecujące, jeśli weźmiemy pod uwagę, że zawarte są w nim szablony
dla całej aplikacji oraz wszystkie moduły składające się na aplikację wraz z silnikiem
bazy danych.

Po zaciągnięciu aplikacji komunikacja z serwerem jest ograniczona do minium,
wszystkie strony są generowane przez klienta.
Modules Webmake
Zmiany zaplanowane na najbliższą przyszłość:
Modules Webmake
Zmiany zaplanowane na najbliższą przyszłość:

• Nie tylko parser zależności ale również pełnoprawny silnik modułów.
W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie
skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska
przeglądarkowego.
Modules Webmake
Zmiany zaplanowane na najbliższą przyszłość:

• Nie tylko parser zależności ale również pełnoprawny silnik modułów.
W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie
skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska
przeglądarkowego.
• Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych
zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików
trzymanych w pamięci podręcznej.
Modules Webmake
Zmiany zaplanowane na najbliższą przyszłość:

• Nie tylko parser zależności ale również pełnoprawny silnik modułów.
W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie
skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska
przeglądarkowego.
• Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych
zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików
trzymanych w pamięci podręcznej.
• Opcjonalna minifikacja, kompilacja
Modules Webmake
Zmiany zaplanowane na najbliższą przyszłość:

• Nie tylko parser zależności ale również pełnoprawny silnik modułów.
W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie
skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska
przeglądarkowego.
• Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych
zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików
trzymanych w pamięci podręcznej.
• Opcjonalna minifikacja, kompilacja
• Wykrywanie niewykorzystanych zależności
Modules Webmake
Zmiany zaplanowane na najbliższą przyszłość:

• Nie tylko parser zależności ale również pełnoprawny silnik modułów.
W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie
skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska
przeglądarkowego.
• Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych
zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików
trzymanych w pamięci podręcznej.
• Opcjonalna minifikacja, kompilacja
• Wykrywanie niewykorzystanych zależności
• Rozbijanie plików, w celu szybszego podawania kodu przeglądarce
Modules Webmake
Zmiany zaplanowane na najbliższą przyszłość:

• Nie tylko parser zależności ale również pełnoprawny silnik modułów.
W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie
skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska
przeglądarkowego.
• Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych
zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików
trzymanych w pamięci podręcznej.
• Opcjonalna minifikacja, kompilacja
• Wykrywanie niewykorzystanych zależności
• Rozbijanie plików, w celu szybszego podawania kodu przeglądarce
• Inteligentna generacja wielu plików (moduły nie powinny się powtarzać w różnych
plikach)
Modules Webmake
Zmiany zaplanowane na najbliższą przyszłość:

• Nie tylko parser zależności ale również pełnoprawny silnik modułów.
W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie
skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska
przeglądarkowego.
• Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych
zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików
trzymanych w pamięci podręcznej.
• Opcjonalna minifikacja, kompilacja
• Wykrywanie niewykorzystanych zależności
• Rozbijanie plików, w celu szybszego podawania kodu przeglądarce
• Inteligentna generacja wielu plików (moduły nie powinny się powtarzać w różnych
plikach)
• Poprawianie kodu pod silniki z niepełnym wsparciem ES5 np. owijanie apostrofami
nazw właściwości, które odpowiadają nazwom zastrzeżonym (drobne udogodnienia)
Przyszłość: Harmony
Będziemy mieli natywny silnik modułów w JavaScript.

http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples
Przyszłość: Harmony
Będziemy mieli natywny silnik modułów w JavaScript.

http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples


Podstawa modułów w Harmony jest koncepcyjnie taka
sama jak modułów w CommonJS.
Przyszłość: Harmony
Będziemy mieli natywny silnik modułów w JavaScript.

http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples


Podstawa modułów w Harmony jest koncepcyjnie taka
sama jak modułów w CommonJS.

Różnice leżą w dedykowanej składni jak i w
dodatkowych możliwościach - dynamiczne ładowanie,
możliwość importowania modułów przez url itp.
Harmony Modules
Harmony Modules
Tak obecnie jest w Node.js:
add.js
module.exports = function() {
     var sum = 0, i = 0, args = arguments, l = args.length;
     while (i < l) sum += args[i++];
     return sum;
};

increment.js
var add = require('./add');
module.exports = function(val) {
     return add(val, 1);
};

program.js
var inc = require('./increment');
var a = 1;
inc(a); // 2
Harmony Modules
Tak będzie w Harmony:
add.js
export function add () {
     var sum = 0, i = 0, args = arguments, l = args.length;
     while (i < l) sum += args[i++];
     return sum;
};

increment.js
import add from './add';
export function increment (val) {
     return add(val, 1);
};

program.js
import { increment: inc } from './increment';
var a = 1;
inc(a); // 2
Harmony Modules
Modules Webmake dla ES3/5:
(function (modules) {

    // 53 linie kodu obsługującego zależności
})
({
     "root": {
          "add.js": function (exports, module, require) {
               module.exports = function () {
                    var sum = 0, i = 0, args = arguments, l = args.length;
                    while (i < l) sum += args[i++];
                    return sum;
               };
          },
          "increment.js": function (exports, module, require) {
               var add = require('./add');
               module.exports = function (val) {
                    return add(val, 1);
               };
          },
          "program.js": function (exports, module, require) {
               var inc = require('./increment');
               var a = 1;
               inc(a); // 2
          }
     }
})
("root/program");
Harmony Modules
Modules Webmake dla Harmony:



         module add {
              export function add () {
                   var sum = 0, i = 0, args = arguments, l = args.length;
                   while (i < l) sum += args[i++];
                   return sum;
              };
         };
         module increment {
              import add from add;
              export function increment (val) {
                   return add(val, 1);
              };
         };
         module program {
              import { increment: inc } from increment;
              var a = 1;
              inc(a); // 2
         };


import * from program;
Serwer i Przeglądarka

Jeśli dziś korzystasz z Modułów CommonJS, przejście za
parę lat na Moduły w Harmony będzie bezproblemowe
Serwer i Przeglądarka

Jeśli dziś korzystasz z Modułów CommonJS, przejście za
parę lat na Moduły w Harmony będzie bezproblemowe


Dziś:
CommonJS Modules & modules-webmake
Serwer i Przeglądarka

Jeśli dziś korzystasz z Modułów CommonJS, przejście za
parę lat na Moduły w Harmony będzie bezproblemowe


Dziś:
CommonJS Modules & modules-webmake


Jutro:
Harmony Modules
Serwer i Przeglądarka

Jeśli dziś korzystasz z Modułów CommonJS, przejście za
parę lat na Moduły w Harmony będzie bezproblemowe


Dziś:
CommonJS Modules & modules-webmake


Jutro:
Harmony Modules (& modules-webmake ?)
Pytania ?
Dziękuję !

Mariusz Nowak
mariusz@medikoo.com



   @medikoo


   github.com/medikoo

More Related Content

PDF
OSGi, deklaratywnie
PPTX
PDF
Podstawy programowania w Drupalu - Drupal idzie na studia - Jarosław Sobiecki
ODP
Drupal Rules - Drupal Idzie Na Studia - Jarosław Sobiecki
PDF
Bazy danych w Drupalu 7. Przygotowanie tabeli przechowującej wpisy chatu
PDF
Podstawy SEO w Drupalu 7 - Jarosław Sobiecki
PPTX
Optymalizacja aplikacji ASP.NET
PPTX
Co nowego w VS 2013 dla programistów ASP.NET?
OSGi, deklaratywnie
Podstawy programowania w Drupalu - Drupal idzie na studia - Jarosław Sobiecki
Drupal Rules - Drupal Idzie Na Studia - Jarosław Sobiecki
Bazy danych w Drupalu 7. Przygotowanie tabeli przechowującej wpisy chatu
Podstawy SEO w Drupalu 7 - Jarosław Sobiecki
Optymalizacja aplikacji ASP.NET
Co nowego w VS 2013 dla programistów ASP.NET?

What's hot (20)

PDF
Angular 4 pragmatycznie
ODP
DrupalDay Podstawy Drupal 8
PPTX
AADays 2015 - Jak to zrobic w JavaScript
PDF
Webpack - Czym jest webpack i dlaczego chcesz go używać? - wersja krótka
PDF
Struktura i własności systemu zarządzania treścią Drupal
PDF
PPTX
Wzorce projektowe (w ASP.NET i nie tylko)
PDF
Encje w drupalu - DrupalCamp Wroclaw 2015
PDF
WordUp Trójmiasto - Sage 9 w praktyce
ODP
DrupalDay podstawy systemu Drupal (Wersja skrócona)
PDF
Daj się wyręczyć - Joomla Day Polska 2014
PDF
Hugo - make webdev fun again
PDF
Motywy dla WordPressa - historia prawdziwa - WordUp Katowice
PDF
Metaprogramowanie w JS
PDF
Uwierzytelnianie dwuetapowe (2FA) w Drupalu [PL]
PDF
Dlaczego Twoja kolejna aplikacja powinna bazować na platformie Drupal?
PDF
Automatyzacja utrzymania jakości w środowisku PHP
PDF
Laravelowe paczki do uwierzytelniania
PDF
Drupal jako modularny i rozszerzalny CMS [PL]
PDF
Cykl życia zapytania HTTP (pod maską)
Angular 4 pragmatycznie
DrupalDay Podstawy Drupal 8
AADays 2015 - Jak to zrobic w JavaScript
Webpack - Czym jest webpack i dlaczego chcesz go używać? - wersja krótka
Struktura i własności systemu zarządzania treścią Drupal
Wzorce projektowe (w ASP.NET i nie tylko)
Encje w drupalu - DrupalCamp Wroclaw 2015
WordUp Trójmiasto - Sage 9 w praktyce
DrupalDay podstawy systemu Drupal (Wersja skrócona)
Daj się wyręczyć - Joomla Day Polska 2014
Hugo - make webdev fun again
Motywy dla WordPressa - historia prawdziwa - WordUp Katowice
Metaprogramowanie w JS
Uwierzytelnianie dwuetapowe (2FA) w Drupalu [PL]
Dlaczego Twoja kolejna aplikacja powinna bazować na platformie Drupal?
Automatyzacja utrzymania jakości w środowisku PHP
Laravelowe paczki do uwierzytelniania
Drupal jako modularny i rozszerzalny CMS [PL]
Cykl życia zapytania HTTP (pod maską)
Ad

Similar to JavaScript, Moduły (20)

PPSX
Webinar - Podstawy Node.js
PDF
Modularny JavaScript - meet.js
PDF
(node.js) Web Development - prościej
PDF
Kickoff to Node.js
PDF
(node.js) Web development - prościej (pl)
PDF
Paleta możliwości web developera
ODP
#3 Frontend Meetup - RequireJS
PDF
Jaki framework wybrać
PDF
JavaScript. Zaawansowane programowanie
PDF
JavaScript. Projekty
PDF
JavaScript dla webmasterów. Zaawansowane programowanie
PDF
Jak nadążyć za światem front-endu - WordPress Training Day
PDF
Master Thesis - Comparative analysis of programming Environments based on Rub...
PDF
Podstawy JavaScript | DreamLab Academy #7
PDF
ES2015 / ES6 Podstawy nowoczesnego JavaScriptu
PDF
JavaScript. Biblia
PPTX
Jak zostać mobile deweloperem w 1 dzień
PPTX
Full Stack JavaScript case study na podstawie Maracuya Jukebox audio player
PDF
Łukasz Spandel – Atena – JavaScript rośnie w siłę – najnowsze trendy w tworze...
Webinar - Podstawy Node.js
Modularny JavaScript - meet.js
(node.js) Web Development - prościej
Kickoff to Node.js
(node.js) Web development - prościej (pl)
Paleta możliwości web developera
#3 Frontend Meetup - RequireJS
Jaki framework wybrać
JavaScript. Zaawansowane programowanie
JavaScript. Projekty
JavaScript dla webmasterów. Zaawansowane programowanie
Jak nadążyć za światem front-endu - WordPress Training Day
Master Thesis - Comparative analysis of programming Environments based on Rub...
Podstawy JavaScript | DreamLab Academy #7
ES2015 / ES6 Podstawy nowoczesnego JavaScriptu
JavaScript. Biblia
Jak zostać mobile deweloperem w 1 dzień
Full Stack JavaScript case study na podstawie Maracuya Jukebox audio player
Łukasz Spandel – Atena – JavaScript rośnie w siłę – najnowsze trendy w tworze...
Ad

JavaScript, Moduły

  • 1. JavaScript, Moduły Organizacja kodu pod serwer i przeglądarkę meetjs · Listopad 2011 · Warszawa
  • 2. Mariusz Nowak mariusz@medikoo.com @medikoo github.com/medikoo Programista JavaScript w Roche Sp. z o.o.
  • 3. Przeglądarka Na samym początku była przeglądarka. Organizacja kodu, jak to (przeważnie) wyglądało (?)
  • 4. Przeglądarka Na samym początku była przeglądarka. Organizacja kodu, jak to (przeważnie) wyglądało (?) • Łączenie plików
  • 5. Przeglądarka Napisanych mniej więcej tak: MAIN.module = (function() { var privateVar = '..'; var privateMethod = function (args) { // ... }; return { publicProperty: '..', publicMethod: function () { // ... } }; }());
  • 6. Przeglądarka Na samym początku była przeglądarka, Organizacja kodu, jak to (przeważnie) wyglądało (?) • Łączenie plików
  • 7. Przeglądarka Na samym początku była przeglądarka, Organizacja kodu, jak to (przeważnie) wyglądało (?) • Łączenie plików • Wzorzec modułu (Module pattern)
  • 8. Serwer Początek roku 2009 • Wiele dostępnych implementacji: Rhino, Spidermonkey, V8, JSCore • Brak jasno określonych standardów • Programiści chcą pisać moduły, które mogą być uruchomione w dowolnej implementacji
  • 9. Serwer Początek roku 2009 • Wiele dostępnych implementacji: Rhino, Spidermonkey, V8, JSCore • Brak jasno określonych standardów • Programiści chcą pisać moduły, które mogą być uruchamiane w dowolnej implementacji • Pojawia się potrzeba stworzenia podłoża pod ekosystem podobny do tego jaki ma Python, Ruby czy Java
  • 10. Serwer Początek roku 2009 • Wiele dostępnych implementacji: Rhino, Spidermonkey, V8, JSCore • Brak jasno określonych standardów • Programiści chcą pisać moduły, które mogą być uruchamiane w dowolnej implementacji • Pojawia się potrzeba stworzenia podłoża pod ekosystem podobny do tego jaki ma Python, Ruby czy Java • Powstaje grupa ServerJS, przemianowana później na CommonJS -> http://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/
  • 11. Serwer Grupa CommonJS przygotowuje między innymi specyfikację modułów. -> http://www.commonjs.org/specs/modules/1.0/
  • 12. Serwer Grupa CommonJS przygotowuje między innymi specyfikację modułów. -> http://www.commonjs.org/specs/modules/1.0/ add.js exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; increment.js var add = require('add').add; exports.increment = function(val) { return add(val, 1); }; program.js var inc = require('increment').increment; var a = 1; inc(a); // 2
  • 13. Serwer Mniej więcej w tym samym czasie powstaje Node.js, który implementuje Moduły z CommonJS add.js exports.add = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; increment.js var add = require('add').add; exports.increment = function(val) { return add(val, 1); }; program.js var inc = require('increment').increment; var a = 1; inc(a); // 2
  • 14. Serwer Mniej więcej w tym samym czasie powstaje Node.js, który implementuje Moduły z CommonJS ... z pewnymi udogodnieniami add.js module.exports = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; increment.js var add = require('./add'); module.exports = function(val) { return add(val, 1); }; program.js var inc = require('./increment'); var a = 1; inc(a); // 2
  • 15. Serwer Jak to działa: // increment.js var add = require('./add'); module.exports = function (val) { return add(val, 1); };
  • 16. Serwer Jak to działa: var exports, module; function (exports, require, module) { // increment.js var add = require('./add'); module.exports = function (val) { return add(val, 1); }; }.call(exports = {}, exports, function (path) { // import zewnętrznego modułu }, module = { exports: exports }); MODULE = module.exports;
  • 18. Serwer Wróćmy do wzorca Modułu. module.js MAIN.module = (function() { var privateVar = '..'; var privateMethod = function (args) { // ... }; return { publicProperty: '..', publicMethod: function () { // ... } }; }());
  • 19. Serwer Wzorzec modułu jako moduł CommonJS: module.js var privateVar = '..'; var privateMethod = function (args) { // ... }; exports.publicProperty: '..', exports.publicMethod: function () { // ... }; program.js var foobar = require(‘./module’);
  • 20. Serwer Wzorzec modułu jako moduł CommonJS: module.js var privateVar = '..'; var privateMethod = function (args) { // ... }; exports.publicProperty: '..', exports.publicMethod: function () { // ... }; program.js var foobar = require(‘./module’); ↑ sami decydujemy jaką nazwą chcemy odwoływać się do zaciągniętego modułu.
  • 21. Serwer Moduły CommonJS to bardzo udana specyfikacja. Co zyskujemy ?
  • 22. Serwer Moduły CommonJS to bardzo udana specyfikacja. Co zyskujemy ? Przede wszystkim przejrzystość kodu i enkapsulacja na najlepszym możliwym (w JavaScript) poziomie
  • 23. Serwer Moduły CommonJS to bardzo udana specyfikacja. Co zyskujemy ? Przede wszystkim przejrzystość kodu i enkapsulacja na najlepszym możliwym (w JavaScript) poziomie • Nie ma potrzeby tworzenia zbędnych “wrapper’ów” by pracować w “swoim” zakresie zmiennych
  • 24. Serwer Moduły CommonJS to bardzo udana specyfikacja. Co zyskujemy ? Przede wszystkim przejrzystość kodu i enkapsulacja na najlepszym możliwym (w JavaScript) poziomie • Nie ma potrzeby tworzenia zbędnych “wrapper’ów” by pracować w “swoim” zakresie zmiennych • Nie toniemy w długich przestrzeniach nazw - każdy potrzebny zewnętrzny moduł przypisujemy do lokalnej zmiennej
  • 25. Serwer Moduły CommonJS to bardzo udana specyfikacja. Co zyskujemy ? Przede wszystkim przejrzystość kodu i enkapsulacja na najlepszym możliwym (w JavaScript) poziomie • Nie ma potrzeby tworzenia zbędnych “wrapper’ów” by pracować w “swoim” zakresie zmiennych • Nie toniemy w długich przestrzeniach nazw - każdy potrzebny zewnętrzny moduł przypisujemy do lokalnej zmiennej • Możemy zbudować dużą, złożoną aplikację, nie dotykając globalnej przestrzeni nazw
  • 26. Serwer i Przeglądarka Jak uruchomić tak napisany kod pod przeglądarką ?
  • 27. Serwer i Przeglądarka Jak uruchomić tak napisany kod pod przeglądarką ? Kiedy zainteresowałem się CommonJS oraz Node.js (początek 2011), byłem przekonany, że już istnieje solidne rozwiązanie.
  • 28. Serwer i Przeglądarka Jak uruchomić tak napisany kod pod przeglądarką ? Kiedy zainteresowałem się CommonJS oraz Node.js (początek 2011), byłem przekonany, że już istnieje solidne rozwiązanie. Znalazłem ok. 8-10 rozwiązań próbujących robić coś podobnego, jednak żadne nie było satysfakcjonujące
  • 29. Serwer i Przeglądarka Główny problem polegał na tym, że każde rozwiązanie próbowało być czymś więcej niż parserem zależności modułów CommonJS.
  • 30. Serwer i Przeglądarka Główny problem polegał na tym, że każde rozwiązanie próbowało być czymś więcej niż parserem zależności modułów CommonJS. Sama implementacja parsera w każdym rozwiązaniu, też niestety pozostawiała wiele do życzenia.
  • 32. Serwer i Przeglądarka Najciekawsze rozwiązania Browserify -> https://github.com/substack/node-browserify
  • 33. Serwer i Przeglądarka Najciekawsze rozwiązania Browserify -> https://github.com/substack/node-browserify Bardzo ciekawe narzędzie jeśli chcemy wykorzystać moduły dostarczane z Node.js. Browserify stara się umożliwić działanie takiego kodu po stronie przeglądarki - taki też był główny zamysł projektu
  • 34. Serwer i Przeglądarka Najciekawsze rozwiązania Browserify -> https://github.com/substack/node-browserify Bardzo ciekawe narzędzie jeśli chcemy wykorzystać moduły dostarczane z Node.js. Browserify stara się umożliwić działanie takiego kodu po stronie przeglądarki - taki też był główny zamysł projektu Dość duża ilość kodu, obsługującego moduły po stronie przeglądarki (ok. 320 linii).
  • 35. Serwer i Przeglądarka Najciekawsze rozwiązania Browserify -> https://github.com/substack/node-browserify Bardzo ciekawe narzędzie jeśli chcemy wykorzystać moduły dostarczane z Node.js. Browserify stara się umożliwić działanie takiego kodu po stronie przeglądarki - taki też był główny zamysł projektu Dość duża ilość kodu, obsługującego moduły po stronie przeglądarki (ok. 320 linii). Niestety nie radzi sobie z niektórymi ścieżkami (nie sczytuje modułów z zewnętrznych pakietów ?)
  • 36. Serwer i Przeglądarka AMD czyli Asynchronous Module Definition
  • 37. Serwer i Przeglądarka AMD czyli Asynchronous Module Definition Ostatnio pojawiło się wiele materiałów na ten temat: http://addyosmani.com/writing-modular-js/ http://blog.millermedeiros.com/2011/09/amd-is-better-for-the-web-than-commonjs- modules/ http://unscriptable.com/index.php/2011/09/30/amd-versus-cjs-whats-the-best- format/
  • 39. Serwer i Przeglądarka AMD ? Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży modułów AMD
  • 40. Serwer i Przeglądarka AMD ? Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży modułów AMD
  • 41. Serwer i Przeglądarka AMD ? Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży modułów AMD AMD ma nie wiele wspólnego z Modułami CommonJS, wymaga innej dyscypliny pisania kodu
  • 42. Serwer i Przeglądarka AMD ? Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży modułów AMD AMD ma nie wiele wspólnego z Modułami CommonJS, wymaga innej dyscypliny pisania kodu • Wszystkie zależności deklarujemy na początku modułu
  • 43. Serwer i Przeglądarka AMD ? Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży modułów AMD AMD ma nie wiele wspólnego z Modułami CommonJS, wymaga innej dyscypliny pisania kodu • Wszystkie zależności deklarujemy na początku modułu W modułach CommonJS możemy sięgać po zewnętrzne moduły w dowolnym miejscu - podobnie będzie w Harmony
  • 44. Serwer i Przeglądarka AMD ? Zaprojektowane z myślą o przeglądarkach - Node.js nie obsłuży modułów AMD AMD ma nie wiele wspólnego z Modułami CommonJS, wymaga innej dyscypliny pisania kodu • Wszystkie zależności deklarujemy na początku modułu W modułach CommonJS możemy sięgać po zewnętrzne moduły w dowolnym miejscu - podobnie będzie w Harmony • Ponownie każdy moduł musimy owijać funkcją deklarującą moduł
  • 46. Serwer i Przeglądarka Dlaczego tak jest ? AMD próbuje rozwiązywać dwa problemy: • Modularyzacja/Organizacja kodu • Dynamiczne dociąganie zależności (na żądanie)
  • 47. Serwer i Przeglądarka Dlaczego tak jest ? AMD próbuje rozwiązywać dwa problemy: • Modularyzacja/Organizacja kodu • Dynamiczne dociąganie zależności (na żądanie) Brzmi obiecująco, ale czy warto ?
  • 48. Serwer i Przeglądarka Jak wygląda AMD ?
  • 49. Serwer i Przeglądarka Jak wygląda AMD ? add.js define(function () { return function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; }); increment.js define(['add'], function (add) { return function(val) { return add(val, 1); }; }); program.js define(['increment'], function (inc) { var a = 1; inc(a); // 2 });
  • 50. Serwer i Przeglądarka Najpopularniejsza implementacja -> http://requirejs.org/ wymaga od nas wciągnięcia do przeglądarki ok 2000 linii kodu
  • 51. Serwer i Przeglądarka Najpopularniejsza implementacja -> http://requirejs.org/ wymaga od nas wciągnięcia do przeglądarki ok 2000 linii kodu ... tylko po to byśmy mogli uruchomić właściwy kod
  • 52. Serwer i Przeglądarka Najpopularniejsza implementacja -> http://requirejs.org/ wymaga od nas wciągnięcia do przeglądarki ok 2000 linii kodu ... tylko po to byśmy mogli uruchomić właściwy kod ... którego i tak bez kompilacji dodatkowym narzędziem nie będziemy mogli wykorzystać po stronie serwera (w Node.js).
  • 53. Serwer i Przeglądarka Ok, ale co z dynamicznym doładowywaniem zależności ? Taki jest przecież główny cel i przyczyna złożoności AMD.
  • 54. Serwer i Przeglądarka Ok, ale co z dynamicznym doładowywaniem zależności ? Taki jest przecież główny cel i przyczyna złożoności AMD. Dynamiczne doładowywanie powinno się rozgrywać na poziomie funkcjonalności nie na poziomie modułów.
  • 55. Serwer i Przeglądarka Ok, ale co z dynamicznym doładowywaniem zależności ? Taki jest przecież główny cel i przyczyna złożoności AMD. Dynamiczne doładowywanie powinno się rozgrywać na poziomie funkcjonalności nie na poziomie modułów. (takie jest przynajmniej moje zdanie ;)
  • 57. Serwer i Przeglądarka Podsumowanie: Brakuje lekkiej i czystej implementacji modułów CommonJS (precyzyjniej modułów Node.js),
  • 58. Serwer i Przeglądarka Podsumowanie: Brakuje lekkiej i czystej implementacji modułów CommonJS (precyzyjniej modułów Node.js), Implementacji, która nie próbuje dodatkowym kosztem rozwiązywać innych problemów.
  • 59. Serwer i Przeglądarka Podsumowanie: Brakuje lekkiej i czystej implementacji modułów CommonJS (precyzyjniej modułów Node.js), Implementacji, która nie próbuje dodatkowym kosztem rozwiązywać innych problemów. Kod wiążący moduły powinien być minimalny, niezauważalny w porównaniu do kodu aplikacji.
  • 60. Serwer i Przeglądarka Ostatecznie narodził się nowy projekt:
  • 61. Serwer i Przeglądarka Ostatecznie narodził się nowy projekt: modules-webmake -> https://github.com/medikoo/modules-webmake npm install -g webmake
  • 62. Modules Webmake modules-webmake buduje drzewo zależności między modułami i wypluwa je jako jeden plik wykonywalny po stronie przeglądarki.
  • 63. Modules Webmake modules-webmake buduje drzewo zależności między modułami i wypluwa je jako jeden plik wykonywalny po stronie przeglądarki. Obecna implementacja jest bardzo podstawowa, można powiedzieć jesteśmy na starcie.
  • 64. Modules Webmake modules-webmake buduje drzewo zależności między modułami i wypluwa je jako jeden plik wykonywalny po stronie przeglądarki. Obecna implementacja jest bardzo podstawowa, można powiedzieć jesteśmy na starcie. Nie przeszkadza to jednak w budowaniu dużych aplikacji, złożonych z kilkuset modułów, pochodzących z kilkunastu pakietów (package’y)
  • 65. Modules Webmake modules-webmake buduje drzewo zależności między modułami i wypluwa je jako jeden plik wykonywalny po stronie przeglądarki. Obecna implementacja jest bardzo podstawowa, można powiedzieć jesteśmy na starcie. Nie przeszkadza to jednak w budowaniu dużych aplikacji, złożonych z kilkuset modułów, pochodzących z kilkunastu pakietów (package’y) Z modules-webmake już teraz możecie budować duże, złożone aplikacje
  • 66. Modules Webmake Jak wygląda wygenerowany plik ?
  • 67. Modules Webmake Jak wygląda wygenerowany plik ? (function (modules) { // 53 linie kodu obsługującego zależności }) ({ "root": { "add.js": function (exports, module, require) { module.exports = function () { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; }, "increment.js": function (exports, module, require) { var add = require('./add'); module.exports = function (val) { return add(val, 1); }; }, "program.js": function (exports, module, require) { var inc = require('./increment'); var a = 1; inc(a); // 2 } } }) ("root/program");
  • 68. Modules Webmake Jak wygląda wygenerowany plik ? (function (modules) { // 53 linie kodu obsługującego zależności }) ({ "root": { "add.js": function (exports, module, require) { module.exports = function () { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; }, "increment.js": function (exports, module, require) { var add = require('./add'); module.exports = function (val) { return add(val, 1); }; }, "program.js": function (exports, module, require) { var inc = require('./increment'); var a = 1; inc(a); // 2 } } }) ("root/program"); <- Wykonanie modułu inicjującego aplikację
  • 69. Modules Webmake • modules-webmake może być wykorzystywany zarówno z poziomu konsoli jak i programistycznie - możemy podczepić narzędzie bezpośrednio pod serwer http w Node.js i tym samym skonfigurować automatyczne generowanie plików
  • 70. Modules Webmake • modules-webmake może być wykorzystywany zarówno z poziomu konsoli jak i programistycznie - możemy podczepić narzędzie bezpośrednio pod serwer http w Node.js i tym samym skonfigurować automatyczne generowanie plików • Zależności są parsowane statycznie, stwarza to pewne ograniczenia. Dla specyficznych przypadków możemy wymusić dociągnięcie wybranych zależności opcją ‘include’
  • 71. Modules Webmake • modules-webmake może być wykorzystywany zarówno z poziomu konsoli jak i programistycznie - możemy podczepić narzędzie bezpośrednio pod serwer http w Node.js i tym samym skonfigurować automatyczne generowanie plików • Zależności są parsowane statycznie, stwarza to pewne ograniczenia. Dla specyficznych przypadków możemy wymusić dociągnięcie wybranych zależności opcją ‘include’ • modules-webmake sczytuje zależności z lokalnego pakietu jak i z zewnętrznych pakietów, jedynym ograniczeniem (obecnie) jest to, że nie rozróżnia dwóch różnych wersji tego samego pakietu.
  • 72. Modules Webmake • modules-webmake może być wykorzystywany zarówno z poziomu konsoli jak i programistycznie - możemy podczepić narzędzie bezpośrednio pod serwer http w Node.js i tym samym skonfigurować automatyczne generowanie plików • Zależności są parsowane statycznie, stwarza to pewne ograniczenia. Dla specyficznych przypadków możemy wymusić dociągnięcie wybranych zależności opcją ‘include’ • modules-webmake sczytuje zależności z lokalnego pakietu jak i z zewnętrznych pakietów, jedynym ograniczeniem (obecnie) jest to, że nie rozróżnia dwóch różnych wersji tego samego pakietu. • Pełniejsza dokumentacja zawsze dostępna pod adresem: https://github.com/medikoo/modules-webmake
  • 73. Modules Webmake Na początku tego miesiąca skończyłem pracę nad aplikacją budowaną z pomocą modules-webmake. • Aplikacja HTML5, adresowana tylko pod nowoczesne przeglądarki (Najnowsze wersje FF, Chrome i Safari (OSX oraz iOS)) • Tryb offline, wymusza to przeniesienie całej logiki aplikacji, wraz z szablonami i prostym silnikiem bazy danych na stronę klienta. • Strona serwera obsługiwana przez Node.js zajmuje się synchronizacją klientów oraz zapisywaniem zmian do fizycznej bazy danych (mongodb) • Minimalistyczna komunikacja klient-serwer oparta na socket’ach (obecnie Socket.IO)
  • 74. Modules Webmake Plik wynikowy po stronie klienta obecnie, wykorzystuje 273 moduły z 19 pakietów. 176 powyższych modułów pracuje również po stronie serwera. Daje to w przybliżeniu ok 60% kodu wykorzystywanego po obu stronach. Połączony plik składa się z ok 11 tysięcy linii kodu Zajmuje, ok 370kB przed minifikacją i spakowaniem. Jest to dość obiecujące, jeśli weźmiemy pod uwagę, że zawarte są w nim szablony dla całej aplikacji oraz wszystkie moduły składające się na aplikację wraz z silnikiem bazy danych. Po zaciągnięciu aplikacji komunikacja z serwerem jest ograniczona do minium, wszystkie strony są generowane przez klienta.
  • 75. Modules Webmake Zmiany zaplanowane na najbliższą przyszłość:
  • 76. Modules Webmake Zmiany zaplanowane na najbliższą przyszłość: • Nie tylko parser zależności ale również pełnoprawny silnik modułów. W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska przeglądarkowego.
  • 77. Modules Webmake Zmiany zaplanowane na najbliższą przyszłość: • Nie tylko parser zależności ale również pełnoprawny silnik modułów. W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska przeglądarkowego. • Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików trzymanych w pamięci podręcznej.
  • 78. Modules Webmake Zmiany zaplanowane na najbliższą przyszłość: • Nie tylko parser zależności ale również pełnoprawny silnik modułów. W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska przeglądarkowego. • Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików trzymanych w pamięci podręcznej. • Opcjonalna minifikacja, kompilacja
  • 79. Modules Webmake Zmiany zaplanowane na najbliższą przyszłość: • Nie tylko parser zależności ale również pełnoprawny silnik modułów. W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska przeglądarkowego. • Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików trzymanych w pamięci podręcznej. • Opcjonalna minifikacja, kompilacja • Wykrywanie niewykorzystanych zależności
  • 80. Modules Webmake Zmiany zaplanowane na najbliższą przyszłość: • Nie tylko parser zależności ale również pełnoprawny silnik modułów. W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska przeglądarkowego. • Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików trzymanych w pamięci podręcznej. • Opcjonalna minifikacja, kompilacja • Wykrywanie niewykorzystanych zależności • Rozbijanie plików, w celu szybszego podawania kodu przeglądarce
  • 81. Modules Webmake Zmiany zaplanowane na najbliższą przyszłość: • Nie tylko parser zależności ale również pełnoprawny silnik modułów. W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska przeglądarkowego. • Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików trzymanych w pamięci podręcznej. • Opcjonalna minifikacja, kompilacja • Wykrywanie niewykorzystanych zależności • Rozbijanie plików, w celu szybszego podawania kodu przeglądarce • Inteligentna generacja wielu plików (moduły nie powinny się powtarzać w różnych plikach)
  • 82. Modules Webmake Zmiany zaplanowane na najbliższą przyszłość: • Nie tylko parser zależności ale również pełnoprawny silnik modułów. W jakim celu? Umożliwi to testowanie modułów wraz z ich zależnościami w różnie skonfigurowanych środowiskach, np. tylko V8 i Moduły, lub emulacja środowiska przeglądarkowego. • Praca w tle, czyli natychmiastowa aktualizacja plików po zaobserwowanych zmianach lub przy integracji z serwerem natychmiastowe serwowanie plików trzymanych w pamięci podręcznej. • Opcjonalna minifikacja, kompilacja • Wykrywanie niewykorzystanych zależności • Rozbijanie plików, w celu szybszego podawania kodu przeglądarce • Inteligentna generacja wielu plików (moduły nie powinny się powtarzać w różnych plikach) • Poprawianie kodu pod silniki z niepełnym wsparciem ES5 np. owijanie apostrofami nazw właściwości, które odpowiadają nazwom zastrzeżonym (drobne udogodnienia)
  • 83. Przyszłość: Harmony Będziemy mieli natywny silnik modułów w JavaScript. http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples
  • 84. Przyszłość: Harmony Będziemy mieli natywny silnik modułów w JavaScript. http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples Podstawa modułów w Harmony jest koncepcyjnie taka sama jak modułów w CommonJS.
  • 85. Przyszłość: Harmony Będziemy mieli natywny silnik modułów w JavaScript. http://wiki.ecmascript.org/doku.php?id=harmony:modules_examples Podstawa modułów w Harmony jest koncepcyjnie taka sama jak modułów w CommonJS. Różnice leżą w dedykowanej składni jak i w dodatkowych możliwościach - dynamiczne ładowanie, możliwość importowania modułów przez url itp.
  • 87. Harmony Modules Tak obecnie jest w Node.js: add.js module.exports = function() { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; increment.js var add = require('./add'); module.exports = function(val) { return add(val, 1); }; program.js var inc = require('./increment'); var a = 1; inc(a); // 2
  • 88. Harmony Modules Tak będzie w Harmony: add.js export function add () { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; increment.js import add from './add'; export function increment (val) { return add(val, 1); }; program.js import { increment: inc } from './increment'; var a = 1; inc(a); // 2
  • 89. Harmony Modules Modules Webmake dla ES3/5: (function (modules) { // 53 linie kodu obsługującego zależności }) ({ "root": { "add.js": function (exports, module, require) { module.exports = function () { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; }, "increment.js": function (exports, module, require) { var add = require('./add'); module.exports = function (val) { return add(val, 1); }; }, "program.js": function (exports, module, require) { var inc = require('./increment'); var a = 1; inc(a); // 2 } } }) ("root/program");
  • 90. Harmony Modules Modules Webmake dla Harmony: module add { export function add () { var sum = 0, i = 0, args = arguments, l = args.length; while (i < l) sum += args[i++]; return sum; }; }; module increment { import add from add; export function increment (val) { return add(val, 1); }; }; module program { import { increment: inc } from increment; var a = 1; inc(a); // 2 }; import * from program;
  • 91. Serwer i Przeglądarka Jeśli dziś korzystasz z Modułów CommonJS, przejście za parę lat na Moduły w Harmony będzie bezproblemowe
  • 92. Serwer i Przeglądarka Jeśli dziś korzystasz z Modułów CommonJS, przejście za parę lat na Moduły w Harmony będzie bezproblemowe Dziś: CommonJS Modules & modules-webmake
  • 93. Serwer i Przeglądarka Jeśli dziś korzystasz z Modułów CommonJS, przejście za parę lat na Moduły w Harmony będzie bezproblemowe Dziś: CommonJS Modules & modules-webmake Jutro: Harmony Modules
  • 94. Serwer i Przeglądarka Jeśli dziś korzystasz z Modułów CommonJS, przejście za parę lat na Moduły w Harmony będzie bezproblemowe Dziś: CommonJS Modules & modules-webmake Jutro: Harmony Modules (& modules-webmake ?)
  • 96. Dziękuję ! Mariusz Nowak mariusz@medikoo.com @medikoo github.com/medikoo