53
JSSDK НАЧАЛО

JSSDK: Начало

  • Upload
    -

  • View
    162

  • Download
    1

Embed Size (px)

DESCRIPTION

«JSSDK: Начало» Когда использовать готовые решения, а когда писать самим. Какие шаги нужно сделать, чтобы ваша работа не оказалась напрасной и принесла пользу окружающим. Все эти нюансы будут рассмотрены на примере внутреннего фреймворка, который возник вследствие необходимости объединения кодовой базы двух проектов.

Citation preview

Page 1: JSSDK: Начало

JSSDKНАЧАЛО

Page 2: JSSDK: Начало

Велосипед или продукт?

Page 3: JSSDK: Начало

Основные проблемы

- Устаревание

- Зависимость от специфичной технологии

- Узкая специализация

- Отсутствие возможности расширения

- Поддержка

Page 4: JSSDK: Начало

http://mailru.github.io/FileAPI/

Page 5: JSSDK: Начало

Спустя время

- Большая и мобильная почта

- Одноклассники

- Облако, Ответы, Документы

- и многие другие (~2К stars, ~260 forks)

Page 6: JSSDK: Начало

«Тач» почта

Page 7: JSSDK: Начало

Выбор решения

- Использовать наработки большой почты

- Взять популярный фреймворк

- Написать самим

Page 8: JSSDK: Начало

«Тач» почта

- Grunt — сборка проекта

- RequireJS — организация модулей

- Backbone — работа с данными

- fest — шаблонизация

Page 9: JSSDK: Начало

Проблемы

vs

Page 10: JSSDK: Начало

Новое серверное API

Проверка токена

GET /folders/all/RPC.call("folders/all")

.then(doneFn, failFn)

запрашиваем,токен POST /token/

проверкаавторизации

токен получен,идет за папками GET /folders/all/

Проверка токена,список папок

resolve(body);

Page 11: JSSDK: Начало

Базовый набор инструментов

- Emitter — излучатель событий

- Promise — обещания

- request — отправка HTTP-запросов к

серверу

Page 12: JSSDK: Начало

Базовый набор инструментов

- RPC — отвечает за логику работы с

серверным API

- Model — класс модели

- Model.List — класс для работы со списком

моделей (коллекция)

Page 13: JSSDK: Начало

Что делать дальше?

Page 14: JSSDK: Начало

Поиск готовых решений

1. Составьте список требований

2. Добавьте к нему пункт «расширяемость»

3. Всё.

Page 15: JSSDK: Начало

Готовые решения

1. Составление списка готовых решений

2. Изучение списка

3. Если решение не подходит, пробуем

изменить задачу

4. Если ничего не подошло, то готовы ли вы…

Page 16: JSSDK: Начало

Модели

Page 17: JSSDK: Начало

Требования к моделям

- Dot notation — доступ к свойствам модели

- Getters — доступ к свойствам без `get`

- Caching — возможность получения данных

из localStorage или IndexedDB

- Persist model — целостность модели

Page 18: JSSDK: Начало
Page 19: JSSDK: Начало
Page 20: JSSDK: Начало

Backbone Большая почта

Dependencies jQuery, undescore jQuery

Dot notation - -

Getters - +

Caching - -

Persist model - +

Сравнение

Page 21: JSSDK: Начало

Getters

- Backbone.Mutators

- писать самим

Dot notation

- Backbone.Nested

- Backbone.DeepModel

Page 22: JSSDK: Начало

Целостностьчто это?

Page 23: JSSDK: Начало

// Поиск моделиfunction findOne(id) {

var dfd = $.Deferred(),model = new Backbone.Model({ id: id });

model.fetch({success: dfd.resolve,error: dfd.error

});

return dfd.promise();}

Пример получения модели

Page 24: JSSDK: Начало

// Где-то в коде #1findOne(123).then(function (model) {

model.on("change:flag", function () { // Слушаемconsole.log(model.get("flag"));

});});

Пример получения модели

// Где-то #2findOne(123).then(function (model) {

model.set("flag", true); // и ничего не происходит});

Page 25: JSSDK: Начало

var _promises = {}; // список обещаний// Поиск моделиfunction findOne(id) {

if (_promises[id] === undefined) {var dfd = $.Deferred();var model = new Backbone.Model({ id: id });model.fetch({ success: dfd.resolve,

error: dfd.reject });_promises[id] = dfd.promise();

}return _promises[id];

}

Добавляем целостность

Page 26: JSSDK: Начало

А коллекции?

Page 27: JSSDK: Начало

// Отфильтруем и получим все id

var ids = collection

.where({ flag: true })

.pluck("id");

// TypeError: undefined is not a function

Коллекции

Page 28: JSSDK: Начало

Итого

- Dot notation —Nested / DeepModel

- Getters — писать самим

- Сaching — ничего вразумительного не

нашел, т.е. писать самим

- Persist model — писать самим

Page 29: JSSDK: Начало

Если вам так ничего и

не подошло, то готовы ли вы…

Page 30: JSSDK: Начало

Готовы ли вы...

- Писать общее решение, а не решать узкую

задачу?

- Писать тесты и документацию

- Поддерживать 24/7?

- Делать всё это бесплатно?

Page 31: JSSDK: Начало

Я готов,

с чего начать?

Page 32: JSSDK: Начало

Главное не кодить

Page 33: JSSDK: Начало

Инфраструктура

Page 34: JSSDK: Начало

Инфраструктура

- Сборка проекта

- Тесты, контроль покрытия и code style

- Поддержка браузерами

- Автоматизация контроля изменений

- Документирование кода и документация

- Способ распространения

Page 35: JSSDK: Начало

Инфраструктура

- GruntJS для сборки проекта

- JSHint, QUnit + Istanbul

- grunt-autopolyfiller

- git hooks + Travis CI

- JSDoc3 для документирования кода

- Private GitHub и подключение через subtree

Page 36: JSSDK: Начало

С чего начинает

разработчик?

Page 37: JSSDK: Начало
Page 38: JSSDK: Начало

Модуль

- MyModule.js — код модуля

- MyModule.tests.js — тесты

- MyModule.banch.js — тесты

производительности (если они нужны)

- README.md — документация (по JSDoc3)

> grunt module:create:MyModule

Page 39: JSSDK: Начало

список изменённых файлов

pre-commitgrunt JSHint

pre-pushgrunt QUnit

Page 40: JSSDK: Начало
Page 41: JSSDK: Начало
Page 42: JSSDK: Начало
Page 43: JSSDK: Начало

Веб-интерфейс

Page 44: JSSDK: Начало

Веб-интерфейс

Page 45: JSSDK: Начало

Веб-интерфейс

Page 46: JSSDK: Начало

var CloudEntry = Backbone.Model.extend({// ...

});var CloudEntries = Backbone.Collection.extend({

model: CloudEntry});

var entries = new CloudEntries({ id: "/" });entries.fetch({

success: function () {entries.each(function (entry) {

if (entry.isFile()) {}

});}

});

Было

Page 47: JSSDK: Начало

app.loadFolder = function (id) {return api.folder(id).then(function (entries) {

_normalize(entries);return entries;

});};

app.loadFolder(123).then(function (/**Object[]*/entries) {entries.forEach(function (entry) {

if (entry.is_file) {}

});});

Было

Page 48: JSSDK: Начало

var CloudEntry = RPCModel.extend({url: "...",defaults: { ... },isFile: function () {

// ...}

});

CloudEntry.find("/").then(function (entries) {entries.each(function (entry) {

if (entry.isFile()) {}

});});

Стало

Page 49: JSSDK: Начало

CloudEntry.find("/").then(function (entries) {entries.each(function (entry) {

if (entry.is_file) {}

});});

Но в Облаке должно быть...

Page 50: JSSDK: Начало

var CloudEntry = RPCModel.extend({url: "...",defaults: { ... },

getters: {is_file: "isFile"

},

isFile: function () {// ...

}});

Стало: Почта + Облако

Page 51: JSSDK: Начало

x16

x4

x5

x4

x4

x4

Page 52: JSSDK: Начало

x4.6

x4.6

x4.4

x4.2

x4.2

x1.9

x1.9

Page 53: JSSDK: Начало

Продолжение следует...

https://github.com/mailru/

https://github.com/RubaXa/

@ibnRubaXa