Окружение JavaScript, наверно, самая быстроразвивающаяся отрасль в мире разработки программного обеспечения. Все слышали шутку про книгу “36 новых JavaScript фреймворков, выпущенных в марте”, и это не далеко от правды.
В своем обзорном докладе я расскажу о своем пути во frontend. О том, как вижу современную индустрию, о существующих проблемах и путях их решения. Все не так уж радужно, как может показаться. Надеюсь, мой доклад позволит вам взглянуть на мир JavaScript с другой стороны или, по крайней мере, задуматься о том, в правильном ли направлении вы движетесь?
Доклад с конференции D2D Pizza JS - http://dev2dev.ru/events/8/
2. Кто я?
• Тимлид и один из основателей bro.agency
• Разрабатываю веб-формочки на python в течение 8 лет
• Продвигаю функциональное программирование в массы
• Провожу воркшопы и мастер-классы
2
3. Про что доклад?
• JavaScript сейчас на гребне волны
• Я расскажу свой личный опыт. Свое видение индустрии
• Расскажу о причинах, по которым произошел такой бурный рост
JavaScript
• Расскажу о проблемах и возможном пути их решения
3
4. Когда-то давно все было просто
<script type="text/javascript">
$(document).ready(function() {
$(".fancybox").fancybox();
});
</script>
4
5. Когда-то давно все было просто
<script type="text/javascript">
$(document).ready(function() {
$(".fancybox").fancybox();
});
</script>
5
6. Потом стало немного сложнее
<script type="text/javascript">
$(document).ready(function() {
$("p").click(function() {
$(this).slideUp();
});
});
</script>
6
7. Потом стало немного сложнее
<script type="text/javascript">
$(document).ready(function() {
$("p").click(function() {
$(this).slideUp();
});
});
</script>
7
8. Дальше появилась динамика
<script type="text/javascript">
$.get("ajax/test.html", function(data) {
$(".result").html(data);
});
</script>
8
9. Дальше появилась динамика
<script type="text/javascript">
$.get("ajax/test.html", function(data) {
$(".result").html(data);
});
</script>
9
10. Дальше появилась динамика
<script type="text/javascript">
$.get("ajax/test.html", function(data) {
$(".result").html(data);
});
</script>
10
11. Браузеры стали еще быстрее
• 2009 — Mozilla Firefox 3.5 TraceMonkey(SpiderMonkey)
• 2010 — Mozilla Firefox 4.0 JägerMonkey
11
13. Кто из вас знает, почему JQuery
плох для больших фронтенд
проектов со сложной логикой?
13
14. Проблемы JQuery
• Не задает структуру проекта
• Не задает архитектуру приложения
• Набор низкоуровневых императивных примитивов
• Нет единого мнения, как делать правильно
• Очень много степеней свободы
14
15. Крупные компании с опытом сразу
это понимали.
Они делали внутренние
фреймворки для создания
фронтенда.
15
16. Нельзя написать сложный
фронтенд на JQuery без подготовки
<script type="text/javascript">
...
$('a.tra.papa').unbind('click');
$('a.tra.papa').bind(doSomething);
...
</script>
16
17. Нельзя написать сложный
фронтенд на JQuery без подготовки
<script type="text/javascript">
...
$('a.tra.papa').unbind('click');
$('a.tra.papa').bind(doSomething);
...
</script>
17
18. Нельзя написать сложный
фронтенд на JQuery без подготовки
<script type="text/javascript">
...
$('a.tra.papa').unbind('click');
$('a.tra.papa').bind(doSomething);
...
</script>
18
19. Компромиcсы на бэкэнде
{% for fset, cap, tid in study_formsets.fset_cap_tid %}
$(function() {
$('.form_container_{{ tid }}').formset({
prefix: '{{ fset.prefix }}',
formCssClass: '{{ tid }}',
extraClasses: ['myrow1', 'myrow2']
});
});
19
20. У кого был legacy проект на JQuery,
который хотелось быстрее
забросить?
20
29. AngularJS
• Код из примеров и документации не подходит для реальных
проектов
• Много магии, которую ты не понимаешь
• С определенного момента, не зная эту магию, нельзя создавать
эффективные приложения
29
34. React открыл дверь
функциональному миру во
фронтенд
Виртуальный дом решил проблему производительности, что
позволило использовать концепции реактивного программирования
для фронтенда на реальных проектах
34
37. Gradual typing
Недостаточно писать код на императивном языке со слабой
динамической типизацией
Нужно больше гарантий - нужна система типов
• Typescript
• Flow
37
55. React Native
Проект начали в ноябре на react-native 0.13.0
В процессе разработки обновились до 0.15.0, дальше не получилось
Закончили активную разработку при 0.19.0
Сейчас 0.23.0
55
56. React Native
Проект начали в ноябре на react-native 0.13.0
В процессе разработки обновились до 0.15.0, дальше не получилось
Закончили активную разработку при 0.19.0
Сейчас 0.24.1
56
74. Elm
• Статически типизированный с автоматическим выводом типов
• Изначально ориентирован на фронтенд
• Свой менеджер пакетов
• Интеграция с JavaScript
• Интеграция с webpack и React
74
76. Изначально ориентирован на
фронтенд
• The Elm Architecture
• Реактивный
• Компоненты могут вкладываться друг в друга бесконечно
• Высокая модульность и ориентированность на повторное
использование кода
76
77. Реактивный
• Интерфейс — свертка потока событий
• Логирование всех событий
• Time travel debugger
77
78. Свой менеджер пакетов
• Содержит все необходимые базовые примитивы
• Легко интегрируется с github
• Документация генерируется автоматически
• Строго следит за тем, чтобы пакеты следовали semver
78
79. Интеграция с JavaScript runtime
Elm interop guide
var div = document.getElementById('elm-stamps');
var stamps = Elm.embed(Elm.Stamps, div, { reset:[] });
stamps.ports.reset.send([]);
stamps.ports.count.subscribe(function(count) {
console.log(count);
});
79
80. Интеграция с JavaScript runtime
Elm interop guide
var div = document.getElementById('elm-stamps');
var stamps = Elm.embed(Elm.Stamps, div, { reset:[] });
stamps.ports.reset.send([]);
stamps.ports.count.subscribe(function(count) {
console.log(count);
});
80
81. Интеграция с JavaScript runtime
Elm interop guide
var div = document.getElementById('elm-stamps');
var stamps = Elm.embed(Elm.Stamps, div, { reset:[] });
stamps.ports.reset.send([]);
stamps.ports.count.subscribe(function(count) {
console.log(count);
});
81
82. Интеграция с JavaScript runtime
Elm interop guide
var div = document.getElementById('elm-stamps');
var stamps = Elm.embed(Elm.Stamps, div, { reset:[] });
stamps.ports.reset.send([]);
stamps.ports.count.subscribe(function(count) {
console.log(count);
});
82