JavaScript a modularizace kódu
Květena kraje Jindřichohradeckého
Se zvláštním přihlédnutím ke Kardašově Řečici
JavaScript a modularizace kódu
Se zvláštním přihlédnutím ke klientskému JS
Ondřej Žára, @0ndras
Rozděl a panuj
- Modularizace je zásadním vývojovým stupněm
- Izolace, udržovatelnost
- Znak vyspělosti jazyka
- Dlouhodobý nedostatek JS
Pravěk: globals
App.MyComponent.MyModule = { ... }
- Stále funguje a fungovat bude
-
- Nutnost vyjmenovat všechny soubory
- Nutnost dodržení pořadí
- Žádná izolace
node.js
- Jediný rozšířený standard CommonJS Modules
- Funkce
require
, proměnné exports
a později i module
- Synchronní import, čisté API
-
- Automagie (příklad na konci)
- Kruhové závislosti a
module.exports
(příklad na konci)
Browserify
- A další: Webpack, SystemJS, Rollup…
- Preprocessor pro modularizovaný kód (např. pomocí CommonJS)
- Výstupem je balíček all inclusive pro prohlížeč
-
- Další úroveň abstrakce
- Další úroveň složitosti
- Objem
Browserify v akci
# node modul
projects/musicmetadata $ du -bh lib
55K lib
# browserify build
projects/musicmetadata $ du -bh dist
228K dist
Opičíme se: AMD
- Taková ta věc s
define
- Snaha emulovat CommonJS v prohlížeči
-
- Z definice trpí asynchronností klientského JS
- V prohlížeči nutná knihovna (typick RequireJS)
ES2015 Modules
- Everything is awesome!
- Podpora pro modularizaci již na úrovni syntaxe
- Klíčová slova
import
a export
- Statická analýza, kruhové závislosti
ES2015 Modules: statický graf závislostí
// fasáda zastřešující funkce specifické pro platformu
module.exports = require("./" + process.platform);
- V ES2015 modulech nelze
- Daň za statickou analýzu závislostí
ES2015 Modules: nativní podpora
ES2015 Modules: babel
- Babel umí transpilovat ES2015 moduly
- Který z existujících formátů ale na výstupu zvolit?
- Vyberme si:
npm install babel-plugin-transform-es2015-modules-commonjs
npm install babel-plugin-transform-es2015-modules-amd
npm install babel-plugin-transform-es2015-modules-umd
npm install babel-plugin-transform-es2015-modules-factory
npm install babel-plugin-transform-es2015-modules-systemjs
...
System API
// nacist a vratit...
System.import("nejaky/modul").then(...);
// alternativne nejprve zaregistrovat v ramci nacitani JS
System.register("jmeno/modulu", depends, initializer);
System API polyfill
- System API má stejnou (marnou) podporu prohlížečů, jako ES2015 moduly
- Existují polyfilly
- es6-micro-loader, necelé 2kB
Module IDs
- Koncepční odlišnost modularizace na serveru/klientu
- Jaký je význam řetězce, identifikujícího modul?
import from "a"
NEBO
import from "a.js"
- Server: automagické doplnění přípony, index.js, node_modules
- Klient: nikdo neví!
< Domenic> ondras: I would bet with 80% odds on the .js being required.
But there's a substantial amount of uncertainty still.
Bonus #1: node.js, automagie
~/projects/myproject $ strace
2>&1
| grep stat
| wc -l
> 70
Bonus #2: CommonJS, kruhová závislost
// index.js
var log = require("./log").log;
exports.value = 42;
log();
// log.js
var index = require("./index");
exports.log = function() {
console.log(index.value);
}
$ node .
> 42
Bonus #3: node.js, kruhová závislost
// index.js
var log = require("./log");
module.exports = 42;
log();
// log.js
var index = require("./index");
module.exports = function() {
console.log(index.value);
}
$ node .
> undefined