
Путешествие в мир модульных загрузчиков
Кирилл Кайсаров




2
Кратко обо мне
Javascript разработчик в команде 2gis.ru
3
Что такое модуль?
Модуль — функционально законченный фрагмент программы, оформленный в виде отдельного файла с исходным кодом или поименованной непрерывной её части, предназначенный для использования в других программах. Модули позволяют разбивать сложные задачи на более мелкие в соответствии с принципом модульности. Обычно проектируются таким образом, чтобы предоставлять программистам удобную для многократного использования функциональность (интерфейс) в виде набора функций, классов, констант.
Источник: Wikipedia
4
Плюсы использования модулей
— Независимость блоков кода
— Упрощает Unit тестирование и поиск ошибок
— Явные зависимости
5
В реальном мире
Родоначальники


Node.JS
Стандарт: CommonJS
Первый релиз: 2009 год
RequireJS
Стандарт: AMD
Первый релиз: Фев. 2010 года
var http = require('http');
function callback (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
};
http.createServer(callback).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
require(["helper/util"], function(util) {
// Эта функция не вызовется до тех пор пока
// не загрузиться helper/util.js
// Если внутри util.js есть define,
// то эта функция не вызовется пока не загрузятся
// зависимости указанные в define.
// Аргумент util вернет интерфейс util.js
});
— Синхронная загрузка
— Работает только на сервере
— Асинхронная загрузка
— Работает только в браузере
6
Единый стандарт
Мы хотим писать код который выполняется в разных
окружениях без лишних сложностей

22 сентября 2010 года James Halliday, также известный как substack, выложил 37 строчный кусок кода который трансформировал node.js модули в browser-compability код.

https://github.com/substack/node-browserify/commit/b0363a
Появление browserify дало толчек развитию изморфных приложений.
Также появление этого решения позволило активно развиваться
пакетному менеджеру npm который сейчас
является самым популярным хранилищем
pre-written кода как для серверных так и для
клиентских приложений.
7
Новые испытания

С развитием HTML5 и появлением новых стандартов, таких как
Web Components, стало понятно что модульному принципу должны следовать не только Javascript блоки кода, но и остальные элементы, такие как CSS таблицы, шрифты и графика.
Загрузчики
// module.js
require('some.less');
// console
> browserify -t lessify module.js > build.js
Пример:
Webpack и Require.JS реализовывает этот функционал через loaders, Browserify через transform'ы
8
Попытка стандартизации
Известный Open-Source разработчик TJ Holowaychuk, также известный как visionmedia и tj, предложил коммьюнити компоненты как стандарт клиентских библиотек. Для описания которых использовался, отличный от привычного package.json, component.json. В нем содержались ссылки на все зависимости модуля, в том числе и стилевые таблицы, изображения и так далее...

Репозиторий проекта
https://github.com/componentjs/component
Хранилище компонентов
https://github.com/component
9
Попытка стандартизации

{
"name": "dialog",
"description": "Dialog component",
"version": "0.4.0",
"keywords": [
"dialog",
"ui",
"modal"
],
"dependencies": {
"component/emitter": "1.1.3",
"component/overlay": "0.3.1",
"component/domify": "1.3.1",
"component/event": "0.1.4",
"component/classes": "1.2.1",
"component/query": "0.0.3"
},
"development": {
"visionmedia/mocha": "*",
"dominicbarnes/expect.js": "*"
},
"scripts": [
"index.js"
],
"styles": [
"dialog.css"
],
"templates": [
"template.html"
],
"demo": "http://component.github.io/dialog/"
}
Component.json
К сожалению широкого распространения component не получил, но стандарт описания активно используется таким пакетным менеджером как Bower
Также мир компонентов пытался покорить такой пакетный менеджер как Duo (http://duojs.org/).
Основной идеей которого была возможность подтягивать пакеты прямо из github репозиториев.
@import 'necolas/normalize.css';
var tip = require('component/tip');
10
Следующие шаги развития

Chunk-loading on-demand
С развитием Javascript приложений, появилась проблема доставки пользователю "большой" браузерной сборки кода. Особенно трудно перенесли это мобильные устройства, часть из которых плохо кешируют любые файлы больше 80-100кб. Для решения этой проблемы сборки отдают по частям.
Webpack

Встроенная функциональность базирующаяся на
экспериментальном стандарте require.ensure
Browserify
Возможность разделения сборок с помощью плагина factor-bundle. Больше ориентирован на многократные точки входа и частоиспользуемые модули

11
Новая эра Javascript и ES6
Разработчики стандарта EcmaScript 6, не пропустили мимо себя возможность добавить в язык модули, и начали активную работу в 2013 году над написанием стандарта.
В июле 2014 года TC39 финализировала синтаксис модулей:
// lib.js
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
// main.js
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
12
Новая эра Javascript и ES6
Также не маловажным пунктом стал и механизм загрузки модулей. В ранних стандартах можно было увидеть глобальный объект System. Цель которого была загрузка модулей в разных окружениях.
System.import('mymodule').then(function(m) {
new m.q();
});
Пример:
К большому сожалению группа разработки отказала в разработке этого формата и перешла к новым обсуждениям этого вопроса.
Status: This document is a work in progress and dreams of becoming a living standard.
13
ES6 прямо сейчас!

С активным развитием нового стандарта, появились реализации экспериментального стандарта ES6 Loader
Polyfill для старого стандарта с объектом System, и активным развитием в сторону нового стандарта с объектом Reflect
Универсальный загрузчик модулей для разных стандартов. AMD, CommonJS, ES6 Modules, Node.JS, Global
Package менеджер для system.js
Спасибо!!!
Приятных путешествий!!!
deck
By Kirill Kaysarov
deck
- 1,148