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

Кирилл Кайсаров

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