Dzielenie kodu aplikacji na wiele plików jest niezbędne do utrzymania porządku w projekcie. Dotychczas JavaScript nie posiadał wbudowanych mechanizmów do wygodnego współdzielenia kodu między plikami. Deweloperzy byli zmuszeni wrzucać każdy plik do osobnego tagu script
w htmlu, co było niezmiernie irytujące, bądź korzystać z zewnętrznych bibliotek, jak requireJS. Na szczęście z nadejściem ES6 moduły oraz ich import i eksport stały się proste jak niemiecka autostrada i wygodne jak fotel z wysuwanym podnóżkiem.
Import i eksport
Podstawowa teoria modułów w ES6 jest banalnie prosta i wystarczy kilka przykładów, by załapać, o co chodzi. Tak więc bez zbędnych ceregieli, przejdźmy do kodu.
/* lib.js */
export const PI = 3.141592;
export function double(x) {
return x * 2;
}
export class Robot {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
Lub zbierając wszystkie eksporty w jednym miejscu:
/* lib.js */
const PI = 3.141592;
function double(x) {
return x * 2;
}
class Robot {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
export { PI, double, Robot };
/* main.js */
import { PI, double, Robot } from './lib';
console.log(PI); //3.141592
console.log(double(5)); //10
const robotron = new Robot('Robotron');
robotron.sayName(); //My name is Robotron
Jak widać na przykładach, aby użyć funkcji, stałej, czy klasy znajdującej się w innym pliku, wystarczy przy jej deklaracji dopisać słowo kluczowe export, a następnie zaimportować do pliku docelowego podając nazwę importowanego modułu i ścieżkę do pliku źródłowego.
Co jednak w przypadku, gdy chcemy zaimportować wiele stałych i wypisywanie ich wszystkich w imporcie zajęłoby zbyt dużo czasu i miejsca? Wystarczy posłużyć się znakiem gwiazdki (*
) i słowem kluczowym as
.
/* const.js */
export const THE_ANSWER = 42;
export const PI = 3.141;
export const EULER = 2.718;
export const BEAST = 666;
export const GOLDEN_RATIO = 1.618;
/* main.js */
import * as numbers from './const';
console.log(numbers.PI); //3.141
console.log(numbers.EULER); //2.718
console.log(numbers.BEAST); //666
Gwiazdka sprawia, że importujemy wszytko, co zostało wyeksportowane, a as
pozwala nadać nazwę zbiorczą, pod którą znajdą się wszystkie moduły.
Default
Moduły w ES6 to temat dość szeroki i nie będę opisywał tu wszystkich ich możliwości. Warto jednak wspomnieć jeszcze o eksportach domyślnych oznaczanych słowem kluczowym default
. Konstrukcja ta używana jest przede wsztystkim wtedy, gdy z całego pliku eksportowany jest tylko jeden moduł. Na przykład:
/* lib.js */
const square = x => x * x;
export default function quadruple(x) {
return square(x) * square(x);
}
/* main.js */
import libQuadruple from './lib'; //brak nawiasów klamrowych wokół nazwy importu
console.log(libQuadruple(2)); //16
Zauważ, że importując moduł wyeksportowany z użyciem default
, przy imporcie możesz nazwać go zupełnie dowolnie.
Obsługa przez przeglądarki
W momencie pisania tego artykułu sprawa wygląda tak, że popularne przeglądarki niestety nie obsługują modułów wcale. Chwalebnym wyjątkiem jest Safari 10, które jako jedyne wspiera 100% standardu ES6/2015. Najprostszym sposobem na użycie ES6 modules już dzisiaj jest więc skorzystanie z narzędzi takich jak Babel i Webpack, które przekonwertują kod modułów ES6 na zrozumiały przez przeglądarki. Tutorial, jak to zrobić, znajdzieciesz tutaj: http://www.2ality.com/2015/04/webpack-es6.html.