Фронтенд
I. Инструменты
Фронтенд
АНТОН ЕПРЕВ // a.eprev \
ЕГОР ДЫДЫКИН // e.dydykin - @corp.mail.ru
ИВАН ЧАШКИН // i.chashkin /
01.
02.
03.
3
Модули
АРХИТЕКТУРА // 2 СЗ + КР
DOM & AJAX // 3 СЗ + КР
ОТДЛАДКА И МОБИЛЬНЫЙ ВЕБ // 3 СЗ + КР
01.
02.
03.
4
Определение
Веб-приложение — клиент-серверное приложение, в котором
клиентом выступает браузер, а сервером — веб-сервер. Логика веб-
приложения распределена между сервером и клиентом, хранение
данных осуществляется, преимущественно, на сервере, обмен
информацией происходит по сети.
Википедия
“5
HTTP, JavaScript,Backbone, DOM,Events, AJAX,WebSockets,Sass, Grunt…
Демо
Контрольные рубежи
РК №1 <= 20
РК №2 <= 60
РК №3 <= 100
01.
02.
03.
8
Итоговая оценка
0 <= "НЕУДОВЛЕТВОРИТЕЛЬНО" <= 59
60 <= "УДОВЛЕТВОРИТЕЛЬНО" <= 74
75 <= "ХОРОШО" <= 89
90 <= "ОТЛИЧНО" <= 100
01.
02.
03.
04.
9
Критерии оценки
СООТВЕТСТВИЕ РЕЗУЛЬТАТА ПРЕДЪЯВЛЯЕМЫМ ТРЕБОВАНИЯМ
ОПТИМАЛЬНОСТЬ ПРЕДЛАГАЕМОГО РЕШЕНИЯ
ПРАКТИЧНОСТЬ РЕШЕНИЯ
КАЧЕСТВО ОФОРМЛЕНИЯ РЕЗУЛЬТАТОВ РАБОТЫ
ДОКАЗАТЕЛЬНОСТЬ АРГУМЕНТАЦИИ ПРИ ЗАЩИТЕ РАБОТЫ
01.
02.
03.
04.
05.
10
tp.eprev.org/p/1
Single PageApplication
Fest
Ресурсы
1. http://nodejs.org
2. https://npmjs.org
3. http://gruntjs.com
4. https://github.com/mailru/fest
17
Проектнаяработа
Подготовка
$ node -v
v0.10.12
01.
02.
19
Приступаем!
$ mkdir epicgame & cd epicgame
$ npm init
$ cat package.json
$ npm install grunt-cli -g
$ npm install grunt grunt-contrib-connect --save-dev
$ vim Gruntfile.js
01.
02.
03.
04.
05.
06.
20
Gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
connect: { … } /* grunt-contrib-connect */
});
grunt.loadNpmTasks('grunt-contrib-connect');
};
01.
02.
03.
04.
05.
06.
21
grunt-contrib-connect
server: { /* Подзадача */
options: {
keepalive: true, /* работать постоянно */
port: 8000, /* номер порта */
base: 'public' /* публичная директория */
}
}
01.
02.
03.
04.
05.
06.
07.
22
Gruntfile.js
$ grunt connect:server
Running "connect:server" (connect) task
Waiting forever...
Started connect web server on http://localhost:8000
01.
02.
03.
04.
23
public
$ cat public/index.html
Hello!
01.
02.
24
HTML
<!DOCTYPE html>
<html><head>
<meta charset="utf-8">
<link rel="stylesheet" href="/css/main.css"/>
</head><body>
<div id="page"></div>
</body></html>
01.
02.
03.
04.
05.
06.
07.
26
Fest
$ npm install grunt-fest --save-dev
27
Fest
<fest:template xmlns:fest="http://fest.mail.ru"
context_name="json">
<div>
<h1>Epic Game</h1>
</div>
</fest:template>
01.
02.
03.
04.
05.
06.
28
Fest
$ vim templates/main.xml
$ vim templates/scoreboard.xml
$ vim templates/game.xml
01.
02.
03.
29
Gruntfile.js
grunt.initConfig({
connect: { … } /* grunt-contrib-connect */
fest: { … } /* grunt-fest */
});
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-fest');
01.
02.
03.
04.
05.
06.
30
grunt-fest
templates: { /* Подзадача */
files: [{
expand: true,
cwd: 'templates', /* исходная директория */
src: '*.xml', /* имена шаблонов */
dest: 'public/js/tmpl' /* результирующая директория */
}], … }
01.
02.
03.
04.
05.
06.
07.
31
grunt-fest ’s options
template: function (data) { /* формат функции-шаблона */
return grunt.template.process(
/* присваиваем функцию-шаблон переменной */
'var <%= name %>Tmpl = <%= contents %> ;',
{data: data}
);
}
01.
02.
03.
04.
05.
06.
07.
32
Grunt
$ grunt fest
$ cat public/js/tmpl/main.js
$ cat public/js/tmpl/scoreboard.js
$ cat public/js/tmpl/game.js
01.
02.
03.
04.
33
Sweetness!
$ npm install grunt-contrib-watch --save-dev
34
Gruntfile.js
grunt.initConfig({
watch: { … } /* grunt-contrib-watch */
…
});
grunt.loadNpmTasks('grunt-contrib-watch');
…
01.
02.
03.
04.
05.
06.
35
grunt-contrib-watch
fest: { /* Подзадача */
files: ['templates/*.xml'], /* следим за шаблонами */
tasks: ['fest'], /* перекомпилировать */
options: {
atBegin: true /* запустить задачу при старте */
}
}
01.
02.
03.
04.
05.
06.
07.
36
Gruntfile.js
grunt.initConfig({
watch: { … } /* grunt-contrib-watch */
connect: { … } /* grunt-contrib-connect */
…
});
…
grunt.registerTask('default', ['connect', 'watch']);
01.
02.
03.
04.
05.
06.
07.
37
grunt-contrib-connect
server: { /* Подзадача */
options: {
keepalive: true, /* работать постоянно */
port: 8000, /* номер порта */
base: 'public' /* публичная директория */
}
}
01.
02.
03.
04.
05.
06.
07.
38
JavaScript
<script src="/js/lib/jquery.js"></script>
<script src="/js/tmpl/main.js"></script>
…
<script>
var $page = $('#page');
$page.html(mainTmpl()); // Рендерим шаблон
</script>
01.
02.
03.
04.
05.
06.
07.
40
JavaScript
function showMainScreen() { // Конструктор экрана "Главный"
$page.html(mainTmpl()); // Рендерим шаблон
// Инициализируем обработчики событий
$page.find('.js-scoreboard')
.on('click', showScoreboardScreen);
$page.find('.js-start-game').on('click', showGameScreen);
}
01.
02.
03.
04.
05.
06.
07.
41
JavaScript
function hideMainScreen() { // Деструктор экрана "Главный"
// Удаляем установленные обработчики событий
$page.find('.js-scoreboard')
.off('click', showScoreboardScreen);
$page.find('.js-start-game').off('click', showGameScreen);
}
01.
02.
03.
04.
05.
06.
42
JavaScript
/* Конструктор экрана "Лучшие игроки" */
function showScoreboardScreen() {
hideMainScreen();
}
/* Деструктор экрана "Лучшие игроки" */
function hideScoreboardScreen() {}
01.
02.
03.
04.
05.
06.
43
Домашнее задание
СФОРМИРОВАТЬ ИДЕЮ ИГРЫ
ОПРЕДЕЛИТЬСЯ С ГРУППОЙ И РОЛЯМИ В НЕЙ
САМОСТОЯТЕЛЬНО ИЗУЧИТЬ GRUNT, FEST И JQUERY
СОЗДАТЬ ПРОТОТИП ВЕБ-ПРИЛОЖЕНИЯ ПО ТЗ
01.
02.
03.
04.
44
II. Архитектура
Immediately-Invoked FunctionExpression, IIFE
var foo = 1;
(function () {
var foo = 2;
alert(foo);
})();
alert(foo);
01.
02.
03.
04.
05.
06.
46
Модуль в JavaScript
var module = (function () {
var name = 'A'; // приватная переменная
return {
say: function () { // публичный метод
alert(name);
}
};
})();
01.
02.
03.
04.
05.
06.
07.
08.47
Устройство веб-приложения
УРОВЕНЬ БИБЛИОТЕК.
УРОВЕНЬ ЯДРА ПРИЛОЖЕНИЯ.
УРОВЕНЬ МОДЕЛЕЙ.
01.
02.
03.
50
Определение
Модуль — функционально законченный фрагмент программы,
оформленный в виде отдельного файла с исходным кодом…
предназначенный для использования в других программах.
Википедия
“51
Модуль веб-приложения
Состоит из HTML, CSS и JavaScript.
Характеризуется слабой связностью.
01.
02.
52
Кнопка тулбара
<div class="toolbar">
<div class="button">Click Me</div>
</div>
.toolbar .button {
background: white;
}
01.
02.
03.
04.
05.
06.
61
Кнопка тулбара
<div class="window">
<div class="toolbar">
<div class="button">Click Me</div>
</div>
<div class="button">Submit</div>
</div>
01.
02.
03.
04.
05.
06.
62
Кнопка тулбара
.toolbar .button {
background: white;
}
.window .button {
background: black;
}
01.
02.
03.
04.
05.
06.
63
Кнопка тулбара (БЭМ)
<div class="window">
<div class="toolbar">
<div class="toolbar__button">Click Me</div>
</div>
<div class="window__button">Submit</div>
</div>
01.
02.
03.
04.
05.
06.
64
Кнопка тулбара (БЭМ)
.toolbar__button {
background: white;
}
.window__button {
background: black;
}
01.
02.
03.
04.
05.
06.
65
БЭМ
toolbar // блок
toolbar__button // блок__элемент
toolbar_fixed // блок_модификатор
toolbar__button_size_xl // блок__элемент_модификатор_значение
http://ru.bem.info
01.
02.
03.
04.
66
Устройство веб-приложения
УРОВЕНЬ МОДУЛЕЙ. // AMD & RequireJS
УРОВЕНЬ ЯДРА ПРИЛОЖЕНИЯ. // Backbone
УРОВЕНЬ БИБЛИОТЕК. // jQuery & Underscore
01.
02.
03.
67
Модуль в JavaScript
var module = (function () {
var name = 'A'; // приватная переменная
return {
say: function () { // публичный метод
alert(name);
}
};
})();
01.
02.
03.
04.
05.
06.
07.
08.69
Asynchronous Module Definition
define('A', function () {
var name = 'A'; // приватная переменная
return {
say: function () { // публичный метод
alert(name);
}
};
});
01.
02.
03.
04.
05.
06.
07.
08.70
Asynchronous Module Definition
define('B', ['A'], function (A) {
var name = 'B'; // приватная переменная
return {
say: function () { // публичный метод
A.say(); // вызов публичного метода модуля A
alert(name);
}
…
01.
02.
03.
04.
05.
06.
07.
08.71
Backbone
МОДЕЛИ // models
КОЛЛЕКЦИИ // collections
ПРЕДСТАВЛЕНИЯ // view
01.
02.
03.
73
Backbone.Events
var object = {};
_.extend(object, Backbone.Events);
object.on("alert", function (msg) {
alert("Triggered " + msg);
});
object.trigger("alert", "an event");
01.
02.
03.
04.
05.
06.
74
Backbone.Model
var PlayerModel = Backbone.Model.extend({});
var player = new PlayerModel();
player.on('change:name', function(model, name) {
alert('Player name is ' + name);
});
player.set({name: 'Mark'});
01.
02.
03.
04.
05.
06.
75
Backbone.View
var PlayerView = Backbone.View.extend({
tagName: "li",
className: "score__item",
template: fest['player'],
…
01.
02.
03.
04.
05.
76
Backbone.View
…
events: {
"click .button_delete": "destroy"
},
destroy: function () {},
…
01.
02.
03.
04.
05.
06.
77
Backbone.View
…
initialize: function () {
this.listenTo(this.model, "change", this.render);
},
render: function () {
this.$el.html(this.template(this.model.attributes));
}
});
01.
02.
03.
04.
05.
06.
07.
08. 78
Backbone.View
var playerView = new PlayerView({
model: player,
id: "player-" + player.id
});
01.
02.
03.
04.
79
Uniform resource locator
scheme://domain:port/path?query_string#fragment_id
81
Событие hashchange
Backbone.history.start();
82
Backbone.Router
var Router = Backbone.Router.extend({
routes: {
'scoreboard': 'scoreboardAction',
'game' : 'gameAction',
'*default' : 'defaultActions'
},
scoreboardAction: function () {},
…
01.
02.
03.
04.
05.
06.
07.
08. 83
Backbone.Router
…
gameAction: function () {},
defaultActions: function () {}
});
new Router();
01.
02.
03.
04.
05.
84
grunt-fest ’s options
template: function (data) {
return grunt.template.process(
/* 'var <%= name %>Tmpl = <%= contents %> ;' */
'define(function () { return <%= contents %> ; });',
{data: data}
);
}
01.
02.
03.
04.
05.
06.
07.
85
Подлючение JavaScript файлов
<script src="/js/lib/jquery.js"></script>
<script src="/js/tmpl/main.js"></script>
<script src="/js/tmpl/scoreboard.js"></script>
<script src="/js/tmpl/game.js"></script>
01.
02.
03.
04.
87
Подлючение JavaScript файлов(RequireJS)
<script data-main="js/main"
src="js/lib/require.js"></script>
01.
02.
88
js/main.js
…
define([
'router'
], function () {
Backbone.history.start();
});
01.
02.
03.
04.
05.
06.
89
Подготовка
$ git remote add tp \
→ https://github.com/eprev/frontend-stub.git
$ git fetch tp
$ git merge tp/v2
01.
02.
03.
04.
90
Домашнее задание
САМОСТОЯТЕЛЬНО ИЗУЧИТЬ UNDERSCORE, BACKBONE И REQUIREJS
ДОРАБОТАТЬ ПРОТОТИП ПО ТЗ
01.
02.
91