Последние полгода много пишут о неоправданной сложности клиентского JavaScript. Недавняя статья How it feels to learn JavaScript in 2016 и ее перевод на хабре вызвали много внимания, критика во многом справедливая, но...


Усложнять просто, упрощать сложно. (Один из законов Мерфи)


В этой статье я дам практические советы, как можно просто сделать фронт-энд приложение, используя при этом современные технологии. Вначале практические детали реализации, а в конце статьи будет анализ выбранного стека.


Как пример используется приложение для работы с коллекцией фильмов. Фильмы отображаются в списке с постраничной выборкой, поиском, сортировкой, редактированием и удалением.


Использованный стек: create-react-app как сборщик для клиента, React, bootstrap, API с json-server или json-заглушки.



Работающее демо здесь: Movies List.
В уже упомянутой статье, ведется диалог между опытным фронт-энд разработчиком и бэк-энд разработчиком, который немного знает фронт-энд и хочет написать простое клиентское приложение используя современные технологии. Фронт-энд "гуру" вываливает все многообразие технологий которое можно использовать, и так озадачивает своего коллегу, что тот отказывается от своей идеи вообще или решает писать все по-старому с JQuery.


Я попытаюсь дать более практические советы о том как это сделать, более того покажу код готового приложения, чтобы можно было использовать его как пример.


GitHub репозиторий здесь.


Клиентская сборка с React Scripts


Первая проблема в современной фронт-энд разработке — это необходимость клиентских сборок. Мы будем использовать готовую build систему, где все сразу работает "из коробки".


Create-react-app или React Scripts — это молодой проект (первый комит в июне 2016) созданный Дэном Абрамовым, создателем Redux, который сейчас работает в facebook.


Чтобы начать


# установить create-react-app глобально
npm i -g create-react-app

# создать новое приложение в папке my-app
create-react-app my-app

React-scripts билдит клиентское приложение, без необходимости дополнительной настройки. Поддерживаются 2 режима development и production.


В режиме development используются клиентские сборки в памяти (с WebPack dev-server) сразу работает hot-reload (вы меняете код, страница перегружается), код проверяется линтером (например, если у вас есть неиспользуемая переменная, будет соответствующее предупреждение) и другое.


Для запуска в development режиме, просто:


#cd my-app
npm start

Если нужно сделать production сборку:


npm run build

Это создаст сборку приложения в папке "/build", где будет минимизированная и готовая к развертке версия.


Для импорта стилей и путей к картинкам, используется метод WebPack, просто делайте import для нужных ресурсов.


//импорт bootstrap стили из папки npm пакета
import '../node_modules/bootstrap/dist/css/bootstrap.css';
//импорт картинки из локальной папки приложения, в somePicture путь к картинке
import somePicture from '../media/picture.png';

Более подробно о работе с react-scripts читайте на GitHub страничке проекта.


React


В качестве JS фреймворка мы выбираем React. Есть другие хорошие опции (VueJS, Angular2), но в отличии от них, React имеет наиболее стабильную экосистему. Это означает стабильность API (не сильно меняется от версии к версии), поддержку в IDE, устоявшийся набор дополнительных библиотек (Redux, react-router), набор готовых компонентов (react-bootstrap, material-ui).


При этом, сам синтаксис React JSX не прост для начинающего и это, наверное, самое сложное с чем придется столкнуться в выбранном стеке.


Само приложение movies-list умышлено написано просто, чтобы было легче понятно для начинающих (например, в реальном приложении можно было бы сделать более детальное разбиение на компоненты).


Существует огромное количество всевозможных учебников по React, для выбранного стека вам нужно чтобы в учебнике использовался ES6 синтаксис (компоненты объявляются через class), и вам не нужно изучать Redux или React Router. С ними вы можете разобраться позже, если будет необходимость.


Примером такого учебника может быть React Fundamentals on Eggheads, стоит так же почитать официальную документацию.


Дополнительные модули


Модули используются как npm пакеты. В качестве CSS фреймовка используется "bootstrap". Для интеграции с React используются компоненты "reeact-bootstrap" (хорошо описаны на сайте проекта).


Пакет "toastr" используется для всплывающих сообщений об ошибке или уведомлении об успешной операции (например: фильм был сохранен). Этот пакет требует включение "jquery" и для реального проекта может иметь смысл найти аналог на React, чтобы не включать JQuery и уменьшить размер упакованного приложения.


Для выбора нескольких значений для жанра фильмов используется "react-select" — продвинутая версия компонента для выпадающего списка.


При использовании ES6 классов нужно делать связывание (bind) для функций. Пакет "react-autobind" упрощает эту задачу, потенциально может повлиять на производительность (вы привязываете все методы, а не только те, где это нужно), но облегчает разработку. Подробнее о bind в React здесь.


    //вместо: 
    constructor() {
        super()
        this.update = this.update.bind(this);
        //... все другие методы
    }

    //c autobind
    import autoBind from 'react-autobind';
    ...
    constructor() {
        super()
        autoBind(this);
    }

Для более удобной манипуляции css классами используется пакет "classnames".


import classnames from 'classnames';

let oneClass = classnames('foo', 'bar'); //значение "foo bar"

let isActive = true;
let anotherClass = classnames({
    'foo': true,
    'bar': false,
    'active': isActive 
}) // значение "foo active"

API


Если у вас нет возможности или желания использовать серверную часть для клиентского приложения, то есть несколько альтернативных возможностей:


JSON-заглушки — начальные данные приложения хранятся в JSON файле, который импортируется как внешний ресурс.


import jsonData from '../myJsonFile.json';

В дальнейшем все операции происходят уже с загруженными данными. Вы реализуете операции поиска, редактирования, удаления самостоятельно, работая с начальными данными из JSON.


В movie-list этот подход используется по умолчанию, логика в файле 'movieServiceStubs'.


Использование json-server — пакет json-server при запуске дает доступ к набору API на основе структуры JSON файла.


Например, если у вас есть db.json в котором есть массив movies, то автоматически будут доступны следующие API:


GET    /movies
GET    /movies/1
POST   /movies
PUT    /movies/1
PATCH  /movies/1
DELETE /movies/1

При этом, API меняют исходный db.json файл, для GET запросов поддерживается поиск, постраничная выборка, сортировка.


Кроме этого json-server поддерживает много дополнительных опций — кастомные маршруты, авто-генерация тестовых данных, поддержка связей между разными элементами.


В movie-list есть возможность работы с json-server, нужно использовать movieService вместо movieServiceStub, кроме этого:


#установить json-server глобально
npm i -g json-server
##запустить json-server через npm-scripts
npm run server

Для AJAX запросов в React Scripts предлагается использовать fetch API. Это новый браузерный стандарт, которые более удобен, чем XMLHttpRequest. Для поддержки старых браузеров в React Scripts используется полифил.


В отличии от JQuery, axios и других клиентских библиотек, Fetch это стандарт, который можно использовать уже сейчас и который будет всерьез и надолго.


Языковые функции


Чтобы не усложнять код дополнительными библиотеками, в movie-list я использую только ES6 фичи (без lodash)


Помимо стрелочных функций ((x) => ...) стоит обратить внимание на такие, как:


» Шаблонные строки
» Итерация по колекции for… of ...
» Клонирование объекта c Object.assign
»Методы массивов map, filter, reduce


Благодаря новым функциям ES6, в Lodash и подобных библиотеках уже нет такой острой необходимости, хотя их использование все равно может быть полезно.


В проекте не используются ES2016+ фичи, они поддерживаются React Scripts, но API менее надежны и хуже поддерживаются (документация, примеры, поддержка в IDE и др.). Если вам все-таки интересно, можете попробовать использование async/await вместо Promise и static свойства в React компонентах.


Публикация


Есть много сайтов на которых вы можете выложить статические ресурсы (HTML/CSS/JS). React Scripts предлагает использовать для этого GitHub pages, в документации описано как это сделать и после 5-минутной настройки вы можете опубликовать демо-версию своего приложения. При этом, необходимо использовать json-заглушки, а это значит приложение потеряет свое состояние после полной перегрузки страницы, что для демо даже лучше.


Анализ выбранного стека


В уже упомянутой статье указываются несколько проблем современного фронт-энда:


Необходимость клиентских билдов


Во-первых, зачем они вообще нужны? Почему нельзя как раньше просто включать скрипт в HTML странички и просто начинать писать код.


В основном, из-за того, что некоторые браузеры очень медленно имплементируют новые стандарты (не будем показывать пальцем, но в основном это касается IE). Пока эти браузеры не уйдут в историю (а это как минимум пару лет), будет существовать необходимость в клиентских сборках, хотя бы для того, чтобы использовать новые функции языка ES6. Помимо этого, если у вас большое приложение, то вам стоит минифицировать ваш код, и если он разбит на много файлов объединять их в одну сборку с учетом связей (если модуль A использует модуль Б, то модуль Б должен быть включен перед модулем A).


Самостоятельно настраивать клиентский билд сложно. Нужно подключить webpack, babel, с десяток webpack loaders, поддерживать dev/prod сборки. На это может уйти куча времени и нервных переживаний, даже при использовании boilerplate вам будет не просто его выбрать, а потом поддерживать. К счастью, появились сборщики (пока не много) для клиентского приложения, в которых все это скрыто внутри отдельного пакета и все что вам нужно это подключить этот сборщик и писать свое приложение с учетом определенных особенностей.


Уже существуют аналоги React Scripts, для VueJS это vbuild, для Angular2 альтернативы я пока не видел, но есть билд система для Ionic2 который построен на Angular2. Эти проекты пока еще не так обкатаны, но появление подобных инструментов лишь вопрос времени.


Некоторые сомневаются, что это подходит для серьезных приложений. Это вполне возможно, но при использовании готовой системы клиентской сборки вы должны соблюдать некоторые соглашения, например, точка входа в одна и находится в src/index.js, не используются CSS препроцессоры, код проверяется определенным набором правил линтера. При этом, само приложение может быть как простым "hello world" так и сложным клиентом на много страниц. К примеру, в проекте Contoso Express react scripts используются для гораздо более сложного приложения.


В конце концов, если через несколько месяцев вам понадобится что-то чего нельзя добиться готовым сборщиком, вы можете сделать свое кастомное решение, но вам не придется заниматься этим в самом начале.


Проблема быстрого устаревания технологий


Вы учите новую технологию, тратите много времени, а она устаревает через полгода или в новой версии API кардинально меняются и приходиться разбираться заново.


Это справедливо для многих технологий, цена прогресса, но не для всех. Если не хочется столкнуться с подобной ситуацией, нужно просто правильно выбирать стек. В нашем стеке большинство технологий давно существуют, работают надежно и не будут сильно меняться в дальнейшем.


Нельзя с полной уверенностью говорить про React (хотя после перехода на ES6 синтаксис, для компонентов никаких значительных изменений в базовом синтаксисе не было). Но что касается ES6, Fetch, Promises — это то, что уже является стандартом JS и будет актуально многие годы, и уже поддерживается в большинстве браузеров.


Проблема слишком большого выбора


Умение правильно подбирать инструменты важно не только в программировании. Проблема в JS, что нет основного (mainstream) подхода, для большинства случаев, как например в .NET. И выбор сильно усложняется. В этом плане экосистема React достаточно устоялась, например, если вначале для React существовало множество Flux имплементаций, то сейчас большинство приложений использует Redux, есть только одна популярная версия для клиентской маршрутизации React Router, и т.д.


При этом важно не использовать лишние инструменты, используя прогрессивный процесс разработки. Начать с необходимого минимума, добавляя новые компоненты только при реальной необходимости. Например, в уже не раз упомянутой статье, для простого одностраничного приложения, предлагались некоторые технологии, в которых совсем не было смысла:


  • ES2016+ — приятное дополнение, но особой необходимости нет.
  • TypeScript/Flow — дает преимущества строгой типизации, но требует дополнительных усилий при настройке и использовании, для начинающих будет лишь дополнительной морокой (в React Scripts можно подключать Flow).
  • Functional programming — для простого приложения, необходимости в этом нет вообще, а для сложного приложения без этого вполне можно обойтись.
  • Lodash/Rumda — с использованием ES6 многие полезные функции стали доступны на уровне языка, можно начать без них.
  • Flux(Redux) — для сложного приложения необходим способ совместного использования состояния (данных) приложения для различных компонентов, для простого приложения отказ от них облегчит начальную разработку.
  • Тестирование UI — для простого приложения без них можно обойтись (в React Scripts есть поддержка Jest для тестирования React компонентов).

Спасибо, тем кто дочитал до конца.


Happy coding! Stay tuned.

Поделиться с друзьями
-->

Комментарии (135)


  1. staticlab
    21.10.2016 10:04
    +3

    И чем по-вашему create-react-app отличается от любого шаблона из yeoman?


    1. Yeggor
      21.10.2016 10:55
      +3

      В отличии от готового boilerplate шаблона для клиентской сборки, create-react-app это отдельный пакет. Это значит что его легко интегрировать, легко обновить в будущем. Представте что у вас уже есть проект с кучей зависимостей, если вы хотите прикрутить к нему какой-то шаблон, то вам нужно вручную его смержить. К тому же create-react-app гораздо качественее большинства других шаблонов.


      1. staticlab
        21.10.2016 11:22
        +3

        The feature set is intentionally limited. It doesn’t support advanced features such as server rendering or CSS modules. The tool is also non-configurable because it is hard to provide a cohesive experience and easy updates across a set of tools when the user can tweak anything.

        То есть, когда рано или поздно придётся внести правки в конфигурацию, придётся сделать eject, что навсегда отвяжет приложение от react-scripts.


        1. Ohar
          21.10.2016 12:18

          Именно. Всем приходится со временем снимать подгузники.


          1. staticlab
            21.10.2016 12:25

            Да, но если хочется сразу "модное" приложение на redux с hot reloading, css modules с cssnext (или хотя бы sass) и прочими вкусными фишечками, то из подгузников придётся выпрыгивать уже при рождении.


            1. justboris
              21.10.2016 15:36

              Что значит "хочется"?


              Если вы профессионал и знаете, какие проблемы решают css-modules, например, то у вас не будет проблем с их настройкой.
              Если вы просто где-то слышали, что это круто, то необязательно кидаться внедрять это себе в проект непонятно для чего.
              А если все-таки очень хочется, то будьте готовы к трудностям в изучении, ведь это технологии advanced-уровня, не нужные на каждой веб-страничке


        1. VolCh
          24.10.2016 06:25

          Можно сделать свой форк react-scripts и пользоваться им долго.


          1. Yeggor
            25.10.2016 02:28

            или воспользоваться существующими, вот пример форка где есть больше возможностей для кастомной конфигурации


            https://www.npmjs.com/package/custom-react-scripts


  1. dshster
    21.10.2016 10:07

    Babel (или ему подобное) не уйдёт никогда — браузеры будут внедрять стандарты, но новейшие экспериментальные стандарты так же будут создаваться, другой вопрос в унификации, создание стандартных библиотек для поддержки экспериментального кода с минимумом настроек.


    1. Ohar
      21.10.2016 12:28

      Да, потому что веб — это неопределённое окружение и вам всегда надо выпускать максимально со всеми совместимый код. Вы же не собираетесь его писать руками, правда?


  1. DenimTornado
    21.10.2016 10:40
    +25

    Слушайте, ну где проще-то? Для такого приложения тянуть React, это в 2016 проще? Серьёзно? Просто, чтобы вывести список киношек с обёрткой бутстрапа? Блин, мир фронтенда сходит с ума. У вас SPA + 3,5 ajax запроса. Ну на кой чёрт здесь фреймворк?


    1. poxu
      21.10.2016 10:47
      +4

      Как я понимаю — жизнь и так сложная штука. Так зачем усложнять её, пытаясь искать индивидуальный подход там, где можно делать всё под одну гребёнку. Вот например берём ангуляр и всегда делаем интерфейс ангуляром. Думать начинаем когда возникают проблемы — не раньше.


      Вот и тут — делаем реактом, потому что умеем. Так быстрее получится сделать, только надо выработать подход — как собирать код с реактом.


      1. DenimTornado
        21.10.2016 10:55
        +4

        Окей, не спорю, но в заголовке посыл в другом. Я его прочёл как — «Простой современный подход к разработке на JS». Я ожидал тут увидеть Web Components и ES6, но никак не очередной «npm i -g create-react-app». Это не проще, это быстрее. Проще будет, когда понятно КАК это работает. А тут, селект оттуда, JSON отсюда, а потом шаг влево/вправо и уже совсем непросто станет.


        1. poxu
          21.10.2016 11:09

          Просто это не обязательно когда понятно как это работает. Просто это ещё и когда нет необходимости разбираться как оно работает.


          1. pacaya
            21.10.2016 11:36
            +2

            “просто” не равно “легко”, хорошее объяснение разницы — https://www.youtube.com/watch?v=rI8tNMsozo0


    1. Yeggor
      21.10.2016 10:51
      +1

      К сожалению, на JQuery особо проще не будет, SPA писать сложнее, чем приложение на пост-бэках. Показывать модальные окна, валидировать ввод пользователя, генерировать HTML по из шаблонов, с JQuery тоже не тривиальная задача. Но в отличии от React или подобных фреймворков, JQuery решение хуже маштабируется, когда проект становится больше. Проще не значит просто :)


      1. DenimTornado
        21.10.2016 11:01
        +1

        Ну если касаться масштабируемости и поддержке, то почему я должен выбрать React, а не Angular или тот же незаслуженно игнорируемый многими Ember?


      1. staticlab
        21.10.2016 11:04
        +2

        Извините, но React — не фреймворк. Если же под фреймворком понимается связка React + Redux + etc, то, как показывает опыт, у redux-приложения тоже возникают проблемы с масштабированием. Причём, намного раньше, чем ожидалось. Да, Абрамов в курсе. В частности, например, в jQuery, Angular, Vue, Mobx можно реализовать компонентный подход, а вот для redux он чужероден. Впрочем, если у вас есть реальное решение проблемы масштабирования для redux-приложения, смело пишите статью. Полезно будет всем.


      1. AlgenGold
        21.10.2016 11:15
        +1

        Подключаешь буттстреп, и jquery. Дальше весь код пишешь на vanila js + babel. Шаблоны очень просто генерируются без всяких библиотек. В ES6 добавили `` и html код очень удобно записывать.
        jquery можно использовать только для ajax запросов. Проблем с расширением функционала приложения не возникнет, если изначально заложить правильную архитектуру.


        1. franzose
          23.10.2016 01:13

          Для шаблонов можно Handlebars использовать, клёвая штука.


          1. AlgenGold
            24.10.2016 10:41

            Я тоже так думал. Код с ним только разрастается. А используя новенькие штуки из ES6, код становится меньше и проще.


      1. cachealot
        21.10.2016 13:26
        +1

        Конкретно такое же приложение можно сделать используя и чистый js + простой шаблонизатор + небольшие плагины не завязанные на jQuery

        ИМХО Проблема современного фроент-мира — все пытаются найти готовое решение вместо того что бы использовать вещи которые уже есть в нативном js и написать лишних 5-10 строчек кода


        1. faiwer
          21.10.2016 13:33
          +5

          А самое странное во всём это то, что при таком армии жаждущих найти готовое решение, все готовые решения не готовы. Где-то нет вменяемого кеширования, где-то недостаточно гибкости, где-то целая куча избыточных зависимостей, ну и т.д… Апогеем стала невозможность обычного подключения библиотеки в обход webpack-а.


          1. bromzh
            21.10.2016 16:59
            +1

            Апогеем стала невозможность обычного подключения библиотеки в обход webpack-а.

            А можно юзкейс? Может проблема не в вебпаке?


            Так-то, он может подключать библиотеки (да и вообще любой js-код) по-всякому и можно найти подход даже к совсем уж странным и старым библиотекам.


    1. phoenixweiss
      21.10.2016 18:31
      +3

      Полностью согласен, вообще фронтенд в 2016-м это фэшн ради фэшна, потому что для решения маленьких задач выбирается такой набор компонентов, который несмотря на свою навороченность, по сути действительно излишен.

      Точно также, если мне нужно сделать простенькое одностраничное приложение в мире руби, я не буду разворачивать рельсы, мне будет достаточно синатры, либо вообще какого-нибудь грейпа если речь идет об API.
      Конечно, я не пронтендер, но я не понимаю почему в 2016-м нельзя просто решить поставленную задачу при помощи того же jQuery который может дергать те же данные в json. Конечный пользователь разницы точно не заметит, а разработчик средней руки не будет ломать голову над тем как обуздать +1 новый фреймворк.

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


      1. taujavarob
        21.10.2016 19:07
        -4

        phoenixweiss > В бэкенде конечно все значительно проще как по количеству решений так и по их инфраструктуре, стабильности релизов и ожиданиям.

        Да, это можно выразить одним словом — там застой! ;-)

        phoenixweiss > Во фронтенде я действительно чувствую что попал в какой-то футуристический мегаполис где все светится и сверкает неоновыми иероглифами и я могу ориентироваться только на ощупь не понимая куда иду понимая только частично надписи.

        Да, и это можно выразить одним словом — тут фан. ;-)

        phoenixweiss > но я не понимаю почему в 2016-м нельзя просто решить поставленную задачу при помощи того же jQuery который может дергать те же данные в json.

        jQuery не запрещён в 2016 году. Можно и только на нём.

        Но дело в том, что вам придётся писать расширяемое большое приложение (или искать работу где это придётся делать) — вот поэтому надо начинать с этого всего, что описано в статье, чтобы дальше… дальше… дальше писать код. Современный код. ;-)

        Имхо, конечно, имхо.


        1. gen_dalf
          23.10.2016 01:29

          У меня другое мнение:

          Да, и это можно выразить одним словом — тут фан. ;-)


          Это можно выразить одним словом — тут анархия!

          (Представим себе африканскую страну, где повсюду орудуют банды, делают что хотят — грабят, убивают. Принцип — живи здесь и сейчас, не строй долгосрочных планов, никаких заводов, науки; поехал в соседнюю деревню ограбил жителей, ищешь другую деревню и т.д.)

          Да, это можно выразить одним словом — там застой! ;-)


          Это можно выразить одним словом — тут порядок!

          (Представим себе современных мегаполис, например, Нью-йорк. Здесь царит закон и порядок. Существую правила, есть те, кто за ними следят. Жизнь размерена — люди могут спокойно заводить детей, строить планы на будущее, нет боязни, что тебя убьют при выходе из дома. В супермаркетах есть еда. Есть постоянная работа и т.д.)

          Имхо, конечно, имхо.


          1. taujavarob
            24.10.2016 16:51

            gen_dalf > Это можно выразить одним словом — тут анархия!

            Вряд ли. Стандартов хватает. Даже слишком! :-)

            gen_dalf > (Представим себе африканскую страну, где повсюду орудуют банды, делают что хотят — грабят, убивают. Принцип — живи здесь и сейчас, не строй долгосрочных планов, никаких заводов, науки; поехал в соседнюю деревню ограбил жителей, ищешь другую деревню и т.д.)

            Представим себе современный город, типа Нью-Йорк — где каждую неделю открываются по несколько новых кафе, каждый месяц по несколько новых ресторанов и всю ночь можно тусоваться!

            gen_dalf > Это можно выразить одним словом — тут порядок!… Представим себе современных мегаполис, например, Нью-йорк. Здесь царит закон и порядок…

            Стоп! — Нью-Йорк я уже представил себе совершенно иначе! ;-)


        1. phoenixweiss
          24.10.2016 04:59

          Последнее что нужно заказчику — это знать что его проект пишется на ныне модной технологии которая через год может просто кануть в лету.

          В свое время приходилось каким-то чудом спасать проекты, написанные на модном 10 лет назад «парсере», который очень быстро и модно взлетел но потом также быстро выгорел.

          Все кто смеялся над «этим вашим PHP который вот-вот умрет», в итоге оказались не правы. Прошло 10 лет, парсера нет а PHP до сих пор жив.

          Мы в свое время перешли с PHP на Ruby не только из-за легкого и читаемого синтаксиса но также из-за более-менее прозрачного графика релизов основных фреймворков и очень хорошей поддержки сообщества.

          Если говорить про те же рельсы — мы сейчас спокойно обслуживаем проекты, написанные в 2012-13 году, и прекрасно представляем что нужно чтобы при необходимости актуализировать их с наименьшими трудозатратами. У Рельсов цикл примерно 2-3 года, для сравнения в мире современного фронтенда значимые изменения происходят значительно чаще, и во многих «модных» решениях через полгода-год ломается обратная совместимость и разработчик оказывается в ситуации когда необходимо принять решение что делать дальше и чаще всего вынужден переписывать решение на более новый технологический стек. Стоит ли говорить что заказчику далеко не всегда можно адекватно объяснить почему каждый год необходимо переписывать его приложение чтобы оно продолжало быть поддерживаемым и могло развиваться.

          В этой ветке также очень хорошо кроме меня прокомментировали про анархию / порядок. Чем мне нравится Ruby / Rails? В первую очередь — порядком. Да, конечно это субъективно и справедливо можно заметить о том что этот стек также имеет некоторые проблемы (с теми же turbolinks которые разделились на легаси-ветку classic и основную ветку и многое другое), но я уверен что в одночасье «завтра» большое приложение, написанное на рельсах «вдруг» не превратится в тыкву как в сказке про Золушку. В худшем случае придется переписать несколько тестов и повычищать в коде депрецированные методы. Но мы на своей памяти спокойно мигрировались с 3-х рельсов на 4-е, а сейчас также спокойно значимые проекты переводим на пятые, параллельно осознавая то что написанные на четверке еще пару лет проживут спокойно.


          1. taujavarob
            24.10.2016 19:52

            phoenixweiss > Последнее что нужно заказчику — это знать что его проект пишется на ныне модной технологии которая через год может просто кануть в лету.

            Вряд ли год — это слишком. Обычно через три года и более. Это уже терпимо.

            phoenixweiss > В свое время приходилось каким-то чудом спасать проекты, написанные на модном 10 лет назад «парсере», который очень быстро и модно взлетел но потом также быстро выгорел.

            10 лет выгорал — это нормально. ;-)

            phoenixweiss > У Рельсов цикл примерно 2-3 года, для сравнения в мире современного фронтенда значимые изменения происходят значительно чаще, и во многих «модных» решениях через полгода-год ломается обратная совместимость и разработчик оказывается в ситуации когда необходимо принять решение что делать дальше и чаще всего вынужден переписывать решение на более новый технологический стек.

            Ломка обратной совместимости не связано с «модностью».
            У Swift это заложено изначально.

            А бают, что Piton, старше Java на 4 года, но поломал обратную бинарную совместимость недавно, в версии Piton-3

            phoenixweiss > а сейчас также спокойно значимые проекты переводим на пятые, параллельно осознавая то что написанные на четверке еще пару лет проживут спокойно.

            Так вы нормально двигаетесь то, шагами и с перспективой на пару(!) лет, а не застряли в версии 2, к примеру этих Ruby / Rails. ;-)


            1. phoenixweiss
              25.10.2016 07:41

              По сабжу — все упирается в конкретику, но в общем современный фронтенд все же значительно более хаотичен и подвержен критичным изменениям, нежели бэкенд. К сожалению, по Python-у поддержать беседу не могу, ибо крайне слабо с ним знаком.

              P.S. И я извиняюсь, но обилие смайлов на все ваши комментарии и «Piton» как-то подсознательно заставляют воспринимать комментарии несерьезно. Так что я думаю в дальнейшем беседу поддерживать малополезно. Ваша позиция понятна.


              1. taujavarob
                25.10.2016 16:39

                phoenixweiss > но в общем современный фронтенд все же значительно более хаотичен и подвержен критичным изменениям, нежели бэкенд.

                Да, там больше фана. Я просто сбежал из мира Java. Там скука и тлен.

                phoenixweiss > но обилие смайлов на все ваши комментарии и «Piton» как-то подсознательно заставляют воспринимать комментарии несерьезно.

                Не обращайте внимание. Да я и на работу в джинсах прихожу. ;-)

                Вот у меня есть друг — он начальник отдела разработки в банке. Солидный человек. В галстуке. Там базы данных. SQL. Он уже про базы и говорить не хочет. — Так и говорит — ни слова о базах — давай о поэзии. ;-)

                А другой знакомый (практика SQL не один год) мне говорит, что молодёжь от скуки в мире SQL придумывает всякие несуразности (так он считает) — ну чем то им всё же хочется там развлекаться. ;-)

                Я же просто сбежал в мир Javascript. Пока… хоть тут ещё есть жизнь. ;-)

                Остальной мир всё больше закоболяется (от слово Кобол). ;-)

                Имхо, конечно, имхо.


    1. SPAHI4
      23.10.2016 01:29

      «тянуть React» — как будто это монстр-фреймворк, а не просто view. К тому же, можно использовать preact (3kb gzip)


  1. myrkoxx
    21.10.2016 11:12
    +3

    JavaScript 2016, а можно попроще?
    Ответ: Можна. EmberJs.
    How to:

    1) npm install -g ember-cli

    2) ember new my-new-app

    3) ember server

    Под катом уже RestAdapter, JsonAdaper. Удобная EmberData (ActiveRecord) для моделей, Controller, Router и тд. Минимум усилий для нормального старта + документация на уровне


    1. Gemorroj
      21.10.2016 13:03

      >> ember server
      но я не хочу сервер на js.


      1. Odrin
        21.10.2016 13:27
        +1

        Так Вам никто и не предлагает это на прод выкатывать. js server нужен для разработки и локального запуска. Хотите использовать другой сервер — никаких проблем.


        1. Gemorroj
          21.10.2016 13:48

          Я в принципе бэкенд на js не хочу.
          Было бы удобно взаимодействие с клиентом по rest/soap/etc… без жесткой зависимости клиент-серверной архитектуры.
          В принципе, выскажу крамольную мысль, что по факту Rich UI (Недавняя статья на хабре) удобнее чем полноценный MVC фреймворк на клиенте.
          Как мне видится нормальная разработка:
          Клиенту сгружаются сырые данные, js фреймворк их превращает в модели, готовая GUI компонета их отображает. Нам остается реализовать обработчики событий, фильтры и т.п.


          1. Odrin
            21.10.2016 14:09
            +3

            А при чем тут бэкенд на js? Есть Ember, есть ajax запросы, делайте бэк на чем Вам угодно.


          1. myrkoxx
            21.10.2016 14:09

            Так опять никто и не говорит о бекенде на javascript. У нас несколько проектов где фронт на EmberJS а бекенд на Symfony. Здесь ember server только для разработки фронта (под капотом ember server поднимает livereload что позволяет сразу видеть проводимые изменения). Подозреваю что вы не просто не так меня поняли =)


          1. DenimTornado
            21.10.2016 19:59

            Ember при билде собёртся в 4* файлика. 2 js, 2cs + статика. Всё. Далее вы эти файлики скармливаете беку и nginx.


  1. faiwer
    21.10.2016 11:22
    +11

    Пара вопросов к аудитории:


    1. Как вы подключаете react-router? Библиотека client-side. Берём bower. Смотрим что подключать. Гхм. Кандидатов нет. Внимательно шерстим все файлы — не понятно. В readme указано, что нужно просто прописать import в коде. И оно заработает. Оо, чего? Ок, в readme указано, что вот по ссылке доступен уже готовый umd-файл, качайте. Чего? Оо. Качать файл с сети и руками его заталкивать в проект? Вроде бы 2016. Брр. Такс. Идея. А может глянем в npm? Смотрим в npm, о, а тут есть вариант для es6-модулей. Открываем файлы и видим, что там иерарические import-ы. В то время как файловая структура в 1 уровень. Откуда они берут эти файлы? ага, вот рядом лежит webpack. Они что на полном серьёзе мне предлагают её собирать? Гхм. О, вот есть готовый собранный umd-вариант. По старинке руками прописываем путь к нему в сборочный скрипт. ЧЯДНТ?
    2. Сборочный скрипт. Хочу чтобы он автоматически копировал скрипты всех bower-зависимостей куда я укажу. Ищу gulp-плагин. Нахожу. Подключаю — опа, а он подключает не то. Смотрим почему. Ага, у ряда библиотек криво прописаны настройки пакета. Городим костыли-исключения. Ок. Смотрим. 2 MiB. О боже, откуда столько? А ну да, это не минифицированные версии слоновсовременных библиотек. Хочу минифицированные версии. Где взять? Ну вот же они рядом с файлами лежат почти во всех плагинах. Ок. Где плагин, который их поищет и поправит пути? Гхм. Нет такого. Есть один кривой, который заменяет саму bower-обёртку, не годится. Что делать? Ок, пишем костыли. Ух, а это что такое? Это наш любимый ReactNative.js. Почему camelCase? Видимо авторам так нравится. ВСЕ остальные библиотеки kebab-case. Ок, подключаем lodash, пишем костыль с _.kebabCase. Хм. Я хотел как-то попростенькому исопльзуя достижения js-человечества подключить скрипты из репозитория. А что получилось? Куча каких-то костылей.

    Привёл 2 примера. Но по сути куда бы я не полез, везде, везде вынужден что-то городить. Т.к. то, что есть или не работает, или работает в пол-силы. Или вообще кривое до нельзя. Самыми странными мне показались бубны с цепочкой всяких gulp-browserify — gulp-babelify — babel — browserfy — babelify — watchify и прочим. От них всех крыша едет. Одно очевиднее другого. В итоге опять костыли-костыли-костыли.


    Хотя казалось бы, столько хайпа. Светлое будущее наступило. А на деле вот.


    отладка

    image


    1. staticlab
      21.10.2016 11:32

      1. В ридми же написано:


        npm i -S react-router
        
        import { Router, Route, Link } from 'react-router'

      2. Webpack


      1. faiwer
        21.10.2016 11:36
        +2

        1. И как это должно работать? Вот вы написали "import ...". Приведите всю цепочку, весь механизм.
        2. И зачем он мне? С его возможностями я примерно знаком по скринкасту (многочасовому). Совершенно избыточный инструмент для моих текущих нужд. Мне даже бандлы не нужны.


        1. staticlab
          21.10.2016 11:48
          +1

          Смотрите, npm i -S скачает вам пакет в node_modules и пропишет его как зависимость в packages.json. Это означает, что набор установленных пакетов всегда можно будет обновить одной командой npm i.


          Далее, предположим, что используется популярная сборочная связка gulp + webpack + babel. Если вы знакомы со сборкой приложений на C/C++, то gulp — это аналог make (или MSBuild :), babel — это компилятор, а webpack — линкер. Итак, babel берёт файл на es6 и превращает его в es5. При этом все импорты заменяются на вызовы require(). Далее, webpack анализирует код, находит все require, затем находит нужные зависимые файлы или пакеты в node_modules, и соединяет их вместе. Далее собранный бандл может быть минифицирован. gulp же управляет всем этим, а также может собрать стили (если не используются CSS Modules) или выполнить другие операции (вплоть до автоматической закачки собранных файлов на FTP :). Вопросы?


          Немного странное заявление, что вам не нужны бандлы. Предлагаете пользователям качать все скрипты по отдельности? Или у вас HTTP2? В таком случае тоже есть решение — System.js.


          1. faiwer
            21.10.2016 12:04
            +2

            Вопросы?

            Вы сделали очень сильное предположение о том, что я использую: webpack. И что моя конфигурация webpack-а съест это всё. А я его не использую. А теперь следите за руками:


            • мы пишем import { Router, Route, Link } from 'react-router'.
            • браузер не знает такого токена. Беда. Ок. Подключил полифил systemjs, подключил babel и прочее и настроил сборку
            • теперь браузер ругается на то, что по адресу ./react-router ничего нет.
            • ок, нужно при сборке его туда поместить, либо же указать в path нужный путь
            • ладно, но где взять путь? хм, смотрим в bower.json. Беда. Всё разобрано, вхлам, причём без зависимостей. Беда.
            • ладно ищем глазами — готового файла нет
            • ладно ставим из npm (уже костыли пошли), смотрим package.json, та же самая проблема. Только теперь зависимости разложены по node_modules (а их пути к тому же могут меняться)
            • ищем глазами и наконец находим по необычному адресу готовый js.
            • подключаем к механизму сборки. работает.
            • какого чёрта? это единственная из библиотек что мне на текущий момент попадались, которая была настолько лихой.

            Предлагаете пользователям качать все скрипты

            • В данный момент у меня мобильное приложение на cordova. вот скажите, на кой чёрт мне бандлы?
            • Даже безотносительно этого, в dev-режиме с отдельными файлами работать проще, а сами эти файлы собираются быстрее. Особенно учитывая какого веса нынче библиотеки. Да и sourcemap увы не идеальны. Несмотря на многолетний стаж.
            • http2 тоже реален

            В таком случае тоже есть решение — System.js.

            Да-да, смотрим выше.


            1. staticlab
              21.10.2016 12:21
              +1

              Я уже понял, что вы не используете webpack, но вы же, вроде, сами хотели, чтобы компьютер сам резолвил все зависимости и позволял вам пользоваться всеми достижениями js-человечества.


              И что моя конфигурация webpack-а съест это всё

              Ну он резолвит дерево зависимостей из коробки, не нужно специально его для этого настраивать.


              Даже безотносительно этого, в dev-режиме с отдельными файлами работать проще, а сами эти файлы собираются быстрее. Особенно учитывая какого веса нынче библиотеки. Да и sourcemap увы не идеальны. Несмотря на многолетний стаж.

              webpack поднимает для этого dev-сервер.


              В react-router главным файлом (main в packages.json) указан lib/index.js, в настройках systemjs


              {
                paths: {
                  '*': './node_modules/*'
                },
                packageConfigPaths: ['./node_modules/*/package.json']
              }

              не прописывали?


              1. faiwer
                21.10.2016 12:35
                +1

                но вы же, вроде, сами хотели, чтобы компьютер сам резолвил все зависимости и позволял вам пользоваться всеми достижениями js-человечества.

                Таки не всеми, всеми слишком жирно будет. У webpack-а другое предназначение. Это не инструмент для разрешения зависимостей. Это лишь одна из его возможностей. Которая всё равно разбивается о суровую реальность кривых .json файлов. Помнится в скринкасте был чудесный пример, как оно мановением руки может затащить в бандл десятки ненужных файлов.


                webpack поднимает для этого dev-сервер.

                Кстати ещё и это. Даёшь больше энтропии на ровном месте. Каждый 1-ый npm-пакет обязан тащить с собой json-сервер. И желательно на expressjs, иначе не кошерно будет.


                не прописывали?

                Нет, конечно. Оно не сработает, т.к. не пробьётся в node_modules, его просто нет в сборке. И не должно быть. Я не потащу в cordova-приложение эту помойку на 70+ MiB. И не потащу на web-production тоже.


                Но вы меня заинтриговали. Оно будет спамить сервер насилуя node_module/*/project.json-ы? В самом деле? о_О. Это новое слово во фронтенде :) Я думал хуже не куда, видимо я ошибался.


                1. staticlab
                  21.10.2016 12:50
                  +1

                  Которая всё равно разбивается о суровую реальность кривых .json файлов. Помнится в скринкасте был чудесный пример, как оно мановением руки может затащить в бандл десятки ненужных файлов.

                  Для этого в webpack 2 будет tree-shaking.


                  Даёшь больше энтропии на ровном месте. Каждый 1-ый npm-пакет обязан тащить с собой json-сервер. И желательно на expressjs, иначе не кошерно будет.

                  Извините, но это больше похоже на истерику. По-моему, вполне хорошее решение для разработки. И всё-таки не каждый пакет тянет за собой веб-сервер. И да, в итоговую сборку он не попадёт.


                  Я не потащу в cordova-приложение эту помойку на 70+ MiB. И не потащу на web-production тоже.

                  Вот для этого и необходимы разрешение зависимостей и оптимизация импортов. Более того, нет нужды тянуть всю сборку пакета (как lodash.min.js), если требуется только одна небольшая сущность из него.


                  Оно будет спамить сервер насилуя node_module/*/project.json-ы? В самом деле? о_О. Это новое слово во фронтенде :) Я думал хуже не куда, видимо я ошибался.

                  Так HTTP2 же :) Или спамить на сотню min.js лучше, чем загрузить один бандл, который нам "не нужен"?


                  1. faiwer
                    21.10.2016 13:44

                    Вы меня заинтриговали.


                    • Вы говорите, что webpack позволит вытащить из lodash только необходимое. Звучит вкусно. А как? Автоматически он это сделать скорее всего не сможет, просто исходя из того, что в package.json прописан уже собранный скрипт (17 тысяч строк). Нужно подключать окольными путями? К чему будет сведён конфиг? Перефразирую вопрос: насколько сложно это будет растачивать, чтобы оно правда так работало и либа функционировала?
                    • Разруливание зависимостей звучит приятно. Но возьмём скажем knockoutjs. На npm его нет. Но есть в bower. Есть два готовых файла, один из которых прописан в main. В dev-разработке однозначно нужен второй (.debug), т.к. без него debug сильно затруднён. Вопрос — во что выльется настройка такого поведения webpack-а?
                    • Ряд библиотек собираются таким образом, что часть кодовой базы срезается для production-а. Как это используется webpack-ом?
                    • Подключил я, скажем, какой-нибудь хороший control. Скажем select2. Помимо самого select2 мне нужна локализация. Причём не вся (там огого сколько всего). Как это будет реализовано в webpack-конфиге?

                    Сдаётся мне, что автоматическое выруливание зависимостей сыграет свою роль только в react-router-е. Да и то, вместо подлючения готого собранного umd файла будет подключены 3-4 десятка мелких, каждый из которых будет обёрнут в webpack обёртку. Кстати говоря вопрос — а сможет ли он сократить эти 4 десятка в один десяток, проанализировав всю кодовую базу на предмет их использования? Вроде что-то такое было заявлено.


                    Но, возможно, когда-нибудь спецификации пакетов будут столь хороши, что можно будет сделать это всё без шуму и пыли. Или будущее уже наступило?


                    1. zxcabs
                      21.10.2016 14:00
                      +1

                      1) гугулим «webpack 2 tree shaking», или подключаем только то что нужно например для lodash:

                      import array from 'lodash/array';
                      

                      2) Читаем документацию: https://webpack.github.io/docs/usage-with-bower.html
                      Для дев конфига можно прописать алиас на не минифицированный файл.
                      3) Если библиотека правильная то все что для продакшина не нужно, срезается установкой переменой окружения `NODE_ENV=production`, собственно строка запуска будет такой: `NODE_ENV=production webpack ...`
                      4) В вебпак кофиге это ни как реализовывать не нужно, просто нужно подключить только ту локализацию которая нужна прямо в коде приложения


                      1. faiwer
                        21.10.2016 14:16

                        Ок, почитаю. Спасибо.


                    1. staticlab
                      21.10.2016 14:16
                      +1

                      Вы говорите, что webpack позволит вытащить из lodash только необходимое.

                      Ну вот конкретно насчёт lodash, конечно, нужно будет импортировать в модуль отдельные функции как import groupBy from "lodash/collection/groupBy" или вообще добавлять отдельным пакетом: import groupBy from "lodash.groupBy". Вообще в пакетах импорт отдельных сущностей (как, например, import { Router } from 'react-router', подгрузит только модуль Router его зависимости).


                      Но возьмём скажем knockoutjs. На npm его нет.

                      Есть. К сожалению, дефолтный импорт импортирует debug-версию. Впрочем, для dev- и prod-конфигураций вебпака можно настроить алиасы.


                      Ряд библиотек собираются таким образом, что часть кодовой базы срезается для production-а. Как это используется webpack-ом?

                      Как уже написал выше, будут импортированы только отдельные модули плюс, если соответствующим образом запущена сборка, то вебпак обрабатывает "compile-time"-условия типа if (process.env.NODE_ENV !== 'production') { ... }, как это сделано в Реакте.


                      Подключил я, скажем, какой-нибудь хороший control. Скажем select2. Помимо самого select2 мне нужна локализация. Причём не вся (там огого сколько всего). Как это будет реализовано в webpack-конфиге?

                      Просто импортируете "select2" и "select2/i18n/ru". Сделать это, перечислив все языки, можно в отдельном модуле. Конфиг вебпака трогать не нужно.


                      сможет ли он сократить эти 4 десятка в один десяток, проанализировав всю кодовую базу на предмет их использования? Вроде что-то такое было заявлено.

                      Это как раз и есть tree-shaking.


                      Но, возможно, когда-нибудь спецификации пакетов будут столь хороши, что можно будет сделать это всё без шуму и пыли. Или будущее уже наступило?

                      Вообще плясать с бубном нужно только для легаси-библиотек. В нашем проекте такой является jquery.inputmask. Но современные библиотеки пишутся с учётом поддержки соглашений commonjs, и проблем с ними не возникает.


                      1. faiwer
                        21.10.2016 14:22
                        +1

                        О, пошёл конструктив. Спасибо за информацию.


            1. Ohar
              21.10.2016 12:31
              +1

              Мои требования полностью покрываются вебпаком.
              Я не использую вебпак, потому что не хочу.
              Веб-технологии плохие, они не могут сделать как мне надо.

              Вы не видите тут противоречий?


              1. faiwer
                21.10.2016 12:38

                Вы не видите тут противоречий?

                Угу, достаточно всего одного слова: избыточный. Он делает слишком много лишнего и совсем не так, как мне это нужно. Этот инструмент в целом мне понравился, и я полагаю, что буду в будущем его применять для очень больших модульных проектов. Т.к. главная его вкусная вещь это умение хитрым образом строить бандлы по всем хитросплетениям зависимостей.


                Но вот ездить на K700 по песочнице — увольте.


                1. Ohar
                  21.10.2016 12:39
                  +1

                  Ну страдайте тогда, или пишите свой вебпак, не избыточный лично для вас.
                  И никому кроме вас не нужный.


                  1. faiwer
                    21.10.2016 12:45

                    Уже готово. 50-70 строк. Быстро и то, что нужно. По поводу того, что кроме меня оно никому не нужно: вы полагаете, что это должно меня как-то расстраивать? Удивительно.


                    1. Ohar
                      21.10.2016 12:54
                      +1

                      Нет, почему же.


                      Это вполне нормально, если это будет использоваться только в ваших личных проектах.


                      А вот если это будет использоваться в работе компании, то вы сразу получаете ворох проблем.


                      • Поддерживать этот код и и обновлять будете лично вы. Когда вы этого делать не будете, он будет устаревать. То есть почти всё время.
                      • Другим разработчикам, которые приходят на проект и ваше поделие видят впервые, объяснять принципы его работы тоже будете лично вы. Каждый раз. Они вас за это будут очень любить.
                      • Вы, конечно, можете написать документацию и периодически её обновлять. Теперь вам нужно поддерживать не только код, но ещё и документацию
                      • Тестировать тоже будете лично вы. Тесты, очевидно, вам тоже нужно поддерживать и обновлять.

                      Если вас это всё устраивает или вы ещё на светлой стороне программирования, то я очень рад за вас и ваш энтузиазм.


                      1. faiwer
                        21.10.2016 13:26

                        Как вы всё хитро обыграли.


                        • а почему только только я? все умерли?
                        • другие разработчики, помимо этих строк, ещё и всю остальную кодовую базу разделяют
                        • какая документация? примитивный .pipe код для gulp-а, с парой комментариев в узких местах. я напомню, решение простое, в отличии от webpack-а (вы откройте любой webpack-бандл… хуже только бинарники)
                        • тестировать будем все, или все умерли?

                        Тёмная сторона, светлая сторона. Занесло вас. А кодовую базу вы тоже по кубикам собираете? Скажем, если вам потребовалась кнопочка, а готовой либы не нашлось, вы будете подключать dojo.js? Там она есть, честно-честно.


                        1. Ohar
                          21.10.2016 14:12
                          +1

                          а почему только только я? все умерли?

                          кроме меня оно никому не нужно

                          Поэтому


                          другие разработчики, помимо этих строк, ещё и всю остальную кодовую базу разделяют

                          Другая кодовая база никуда деться не может, её придётся разделять в любом случае. А ваш эту задачу усложняет самим своим существованием. Его вполне можно из неё исключить и облегчить разработчикам задачу. То есть ускорить вникание в проект и работу над ним. То есть удешевить разработку. Понимаете?


                          какая документация?
                          примитивный .pipe код для gulp-а, с парой комментариев в узких местах

                          Вот эта самая. Её надо читать.


                          тестировать будем все, или все умерли?

                          Что лишний раз увеличивает сложность проекта


                          Скажем, если вам потребовалась кнопочка, а готовой либы не нашлось, вы будете подключать dojo.js? Там она есть, честно-честно.

                          Тогда, к сожалению, кнопочку придётся написать. И это плохо.


            1. arvitaly
              21.10.2016 12:44
              +1

              >В данный момент у меня мобильное приложение на cordova. вот скажите, на кой чёрт мне бандлы?
              В первую очередь это касается SPA и cordova. Приложение из одного файла будет грузиться быстрее, чем из сотни мелких файлов.
              > Даже безотносительно этого, в dev-режиме с отдельными файлами работать проще, а сами эти файлы собираются быстрее.
              WebPack заменяет только те части, которые изменились.
              > http2 тоже реален
              HTTP2 никак не решает проблему иерархических зависимостей.


              1. faiwer
                21.10.2016 12:49
                +2

                В первую очередь это касается SPA и cordova. Приложение из одного файла будет грузиться быстрее, чем из сотни мелких файлов.

                Один или несколько файлов с ssd-диска будут грузиться и правда немного быстрее. Но совсем не радикально. К тому же для production-сборки можно (нужно) добавить строку с gulp-concat. Хорошо когда есть выбор.


                WebPack заменяет только те части, которые изменились.

                Гхм, а как вы себе представляете переписывание файла-бандла не целиком? Это же обычный текстовый файл. Прошу пояснить, что вы имеете ввиду. Или вы имеете ввиду то, что остальные файлы берутся из кеша? Ну дык а как иначе, иначе оно будет просто люто тормозить.


                HTTP2 никак не решает проблему иерархических зависимостей.

                А вот тут я с вами соглашусь. Это больше спрайтов касается. Там иерархии нет.


                1. arvitaly
                  22.10.2016 15:37
                  -1

                  > Гхм, а как вы себе представляете переписывание файла-бандла не целиком?
                  https://nodejs.org/api/fs.html#fs_fs_createreadstream_path_options
                  Если вас интересует, как работает файловая система или как ОС позволяет работать с файлами, то можете почитать, иначе, просто поверьте на слово. А лучше запустите webpack и все увидите сами.

                  Webpack работает и работает все лучше и лучше, и вы не привели ни одного аргумента, чтобы использовать что-то самописное, кроме фатального недостатка. Так что, советую оглянуться.


                1. goodhoopoe
                  23.10.2016 01:30
                  +1

                  для cordova production вообще можно изгаляться как хочешь, ибо файлы все равно зашиты и скрыты, а gulp благодаря плагинам и самому себе соберет так, как ему скажешь, просто нужно сразу продумать порядок и расположение загрузки различных частей приложения.


            1. vintage
              21.10.2016 22:11

              Браузеры ощутимо тупят, когда число скриптов исчисляется сотнями, поэтому эффективней склеить в один бандл. Обычным конкатом с поддержкой сорсмапов.


          1. poxu
            21.10.2016 12:27

            У меня вопрос по поводу вебпаков и system js. Вот есть бэкенд на джаве и фронтенд на ангуляре. node_modules к этому фронтенду весят 90 мегабайт и там файлов очень много. Деплой для разработчика — травматичная вещь. Допустим раз мы задеплоили node_modules, потом их можно не копировать, но надо же приверить на изменения папку и это тоже время занимает.


            Хочется деплоить не весь node_modules, а только файлы, которые реально нужны. Можно как-то этого достичь?


            1. staticlab
              21.10.2016 12:34

              node_modules не надо деплоить. Они разворачиваются на основе packages.json (и, возможно, npm-shrinkwrap.json).


              1. poxu
                21.10.2016 12:39

                Деплой и развёртывание это разве не синонимы?


                1. Odrin
                  21.10.2016 12:46

                  Перед развертыванием приложения на сервере, его необходимо собрать. node_modules нужны во время сборки, но не во время развертывания.


                  1. poxu
                    21.10.2016 12:51

                    Ок, хорошо. Можно сборку как-то ускорить, убрав из node_modules всё, что не нужно для работы приложения? Чтобы он не 90 мегабайт весил?


                    1. Laney1
                      21.10.2016 12:58

                      размер можно уменьшить, используя npm link. Время сборки — исключая из нее стандартные пакеты. Например, какой смысл каждый раз собирать react, если он и так есть на всех cdn и его можно подключить прямо в html?


                      1. poxu
                        21.10.2016 13:11

                        Вот в node_modules в каждом модуле, помимо библиотеки есть тесты, документация и всё такое. Можно как-то оставить только нужный код?


                        Ещё каждый модуль тянет свои зависимости. Можно как-то оставить только по одной версии каждой зависимости?


                        1. staticlab
                          21.10.2016 13:42

                          При сборке в любом случае получится бандл, в котором нет тестов, примеров, документации и прочего. Только необходимые для приложения модули. И пакеты сборочного конвейера (webpack, gulp и т.п.) тоже туда не попадут. Ещё раз об аналогии с миром C/C++: рассматривайте node_modules как весь SDK с компилятором, системой сборки и исходниками библиотек. Разумеется, размер конечного файла будет меньше всего этого.


                          1. faiwer
                            21.10.2016 13:48

                            Не могли бы вы пояснить на примере или суть? Про npm link выдаёт вот это, где речь идёт о различных symlink-ах.


                            1. staticlab
                              21.10.2016 14:21
                              +1

                              Ну смотрите, вы установили пакет foo, внутри которого лежат src/, tests/, docs/ (хотя, обычно, доки игнорят в npmignore), README, LICENSE и т.п. Вы импортируете его через import foo from "foo". Webpack посмотрит в раздел main файла packages.json или по дефолту попробует найти index.js. Подключит нужный файл. Посмотрит, что он require'ит. Подключит эти модули тоже. Всё остальное в бандл не попадёт. Симлинки тут ни при чём, они нужны, чтобы связать локальные директории как пакеты.


                              1. faiwer
                                21.10.2016 14:27

                                Я похоже не правильно вас понял. Я думал, что вы говорите, что есть простая возможность упаковки node_modules для production. Т.е., включая все стили, изображения, прочие необходимые файлы, но исключая все примеры, документацию и многое многое другое. Для этого недостаточно информации в project.json. Если же речь шла именно про webpack и подключённое через него в коде или конфиге, тогда ясно.


                                1. staticlab
                                  21.10.2016 14:46

                                  Если речь идёт об урезанной версии node_modules, которая будет висеть в продакшене, то такого инструмента нет.


                    1. Odrin
                      21.10.2016 13:36

                      Чем вам мешают 90 мегабайт на сервере сборки? И как уменьшение размера node_modules ускорит сборку? Это ускорило бы первое скачивание всех пакетов, да и то попахивает экономией на спичках.


                      1. poxu
                        21.10.2016 14:13

                        На сервере сборки наверное ничем не помешает. А на локальной машине разработчика приложение долго полностью перезапускать.


                        1. staticlab
                          21.10.2016 14:23
                          +1

                          Вы имели в виду установку зависимостей? Так по этой причине, в частности, yarn и придумали — он это делает быстрее.


                        1. Odrin
                          21.10.2016 14:35

                          Вы вероятно имели ввиду «пересобирать»? И остается прежний вопрос, как уменьшение размера node_modules ускорит сборку?


                          1. poxu
                            21.10.2016 15:08

                            Сейчас можно сначала собрать фронтенд, а потом собрать джаву мавеном и мавен просто возьмёт весь фронтенд, включая node_modules и скопирует в директорию сборки.


                            Если node_modules уменьшить — время сборки меньше будет из-за того, что копировать меньше.


                            Или надо как-то мавеном собирать уже на месте, но как я пока не решил.


                            1. staticlab
                              21.10.2016 16:13

                              Не понял. Фронтенд же уже собран. На выходе будет какая-нибудь папочка dist. Теперь node_modules уже не нужно.


                              1. poxu
                                24.10.2016 08:42

                                Собственно в том и мой вопрос был. Чем и как собирать, чтобы node_modules нужен не был.


                                1. staticlab
                                  24.10.2016 12:14

                                  Webpack или Browserify


                                  1. poxu
                                    24.10.2016 12:51

                                    Чем сами пользуетесь?


                                    1. staticlab
                                      24.10.2016 13:09

                                      Gulp + Webpack + Babel


                                      1. poxu
                                        24.10.2016 13:09

                                        Понял, спасибо


                            1. Anarions
                              23.10.2016 01:30

                              Так, я запутался, проблема у разработчиков? В то что во время разработки фронтэнд долго билдится?


                              1. poxu
                                24.10.2016 08:41

                                Типа того. Долго перезапускается. Потому что для чистого перезапуска нужно node_modules копировать.


                                1. Anarions
                                  24.10.2016 17:15

                                  а зачем копировать кажый раз? Почему нельзя оставить в покое, как это обычно делается?


                                  1. poxu
                                    24.10.2016 18:11

                                    Чистый перезапуск подразумевает, что мы перед этим всё сотрём. Может не стоит чистый перезапуск часто делать, это да. В данный момент у node_modules всегда проверяется на актуальность, если хоть какой-нибудь джаваскрипт модифицировать. Сборщик должен же проверить, что изменений нету по сравнению с предыдущим запуском.


                                    1. staticlab
                                      24.10.2016 18:30

                                      Думается, версии всех зависимостей стоит строго фиксировать через npm-shrinkwrap.json или yarn.lock. Так что перекачивать каждый раз модули не стоит.


                                      1. poxu
                                        24.10.2016 18:46

                                        Дело не в том, что модули перекачиваются каждый раз. Дело в том, что сначала собирается фронтенд, в том числе node_modules, а потом его надо скопировать в директорию, где джава будет искать статические файлы.


                                        1. staticlab
                                          24.10.2016 18:56

                                          Да зачем вам это нужно-то? Есть директория с проектом, есть директория public для статики. Сборщик возьмёт точку входа в приложение (например, app.js или main.js), автоматически рекурсивно отыщет все файлы-зависимости среди файлов приложения и файлов модулей из node_modules, объединит их в один, затем этот бандл минифицирует и положит в public. Всё! Ничего никуда и копировать не надо. В крайнем же случае, сборщик может положить его куда-нибудь в dist, откуда его уже достанет maven и сам положит, куда ему надо.


                                          Если же мы чего-то не понимаем, то ответьте нам, пожалуйста, вразумительно, зачем вам куда-то копировать node_modules? Зачем оно java-приложению? Собранный скрипт туда ссылаться не будет.


                                          1. poxu
                                            24.10.2016 19:28

                                            Да нет, вы, судя по всему, всё поняли правильно. И дали очень полезные советы, спасибо вам большое :). Копировать node_modules мне на данный момент надо потому, что для подгрузки модулей используется system.js. Я так понимаю надо его заменить на webpack


                                        1. vintage
                                          24.10.2016 21:02

                                          Можете попробовать не копировать, а сделать симлинк или хардлинк. Но лучше, конечно, собирать самодостаточный бандл.


                1. staticlab
                  21.10.2016 13:38

                  Простите, на автомате почему-то написал сценарий для сервера на node.js. Под "разворачиванием" имел в виду установку пакетов.


            1. Ohar
              21.10.2016 12:40

              Не надо деплоить node_modules.


              Надо


              1. Выкачать правки через git checkout master и git pull
              2. Обновить зависимости через npm i и npm update
              3. Собрать node_modules в минифицированный бандл
              4. Выкатить этот бандл.

              Проблема в том, что это не мгновенная операция и именно для её ускорения фейсбук выпустил свой Yarn.


              1. poxu
                21.10.2016 12:42
                +1

                Меня больше всего интересуте третий шаг. Сборка в минифицированный бандл. Сейчас на фронтенде зависимости подтягиваются через system.js.Если собирать в бандл, нужно от него отказатся? И чем собирать? Вебпаком?


                1. Ohar
                  21.10.2016 12:45

                  Да чем угодно. Хоть грантом, хоть вебпаком. Мне последний нравится больше.


                  1. poxu
                    21.10.2016 12:52

                    Гранту, насколько я помню нужно отдать список файлов для бандла. Можно как-то построить его автоматически? Или надо руками его поддерживать?


                    1. Ohar
                      21.10.2016 14:14

                      Вот чего не знаю того не знаю.


                      1. poxu
                        21.10.2016 14:18

                        Вы сами руками список поддерживаете, я правильно понимаю?


                        1. Ohar
                          21.10.2016 14:22

                          Да, он не сильно меняется, поэтому это не проблема.


                          1. poxu
                            21.10.2016 14:24

                            Вы не в курсе, это общепринятая практика? Я недавно вопросом занимаюсь, не хочется потом узнать, что вообще-то всё давно решено.


                            1. Ohar
                              21.10.2016 14:25

                              Скажем так, я не видел вживую проектов, где это было бы не так.


                              1. poxu
                                21.10.2016 14:25

                                Понял, спасибо :)



                        1. faiwer
                          21.10.2016 14:31

                          В gulp можно сделать как-то вот так. Для части библиотек потребуется вести список вручную. Остальные же подгрузятся через .json из пакетов.


      1. tenbits
        22.10.2016 00:36

        Скажите пожалуйста, везде читаю про "глобальную" сборку, а как выглядит разбиение и сборка по страницам. Я сейчас имею ввиду не классические страницы, а всё ещё single page app. Просто его нужно же тоже разбивать на страницы (view), таким образом, что если пользователь заходит изначально в один view, то ресурсы для других не загружаются, переходит пользователь в другое вью, мы просто подгружаем ресурсы для него, и так далее, ну вы меня понимаете. Так вот, например, react-router: есть у нас компоненты UserList и UserEditor под разные маршруты. У каждой страницы свои зависимости. Но есть и глобальные зависимости для приложения, jquery.js например. И теперь когда собираем приложение:


        • будут ли ресурсы разделены по бандлам, например global.js, user-list.js и user-editor.js?
        • будут ли бандлы грузиться в зависимости от маршрута?
        • что будет происходить с компонентами которые будут и в UserList, и в UserEditor использованы, но не в глобальных зависимостях?
        • система сборки как-то перепишет мой код, что бы грузить сначала нужный бандл, вместо десятка скриптов для страницы?

        Может знаете пример небольшого приложение, где будет разделение на страницы и соответственно сборка тоже по страницам. Не обязательно реакт, что нибудь, интересен просто подход. Или просто статью, где именно акцент на view dependencies.


        1. staticlab
          22.10.2016 12:48

          будут ли ресурсы разделены по бандлам

          Webpack 1 позволяет задать точки сборки для нескольких бандлов. Они должны быть загружены в браузер самостоятельно через теги <script>, либо полуавтоматически через bundle-loader (поскольку для этого требуется явно обозначить такие импорты).


          будут ли бандлы грузиться в зависимости от маршрута?

          В общем случае webpack не способен определить, когда приложению действительно потребуется тот или иной модуль. Так, например, компонент вьюшки реально не будет отображён, пока не будет выбран соответствующий роут. Но на этапе сборки распознать это нельзя. Можно, конечно, сделать обёртку, которая будет лениво подгружать реальный компонент вьюшки при componentDidMount через bundle-loader (webpack 1) или System.import (webpack 2).


          что будет происходить с компонентами которые будут и в UserList, и в UserEditor использованы, но не в глобальных зависимостях?

          CommonsChunkPlugin может найти «общий знаменатель» отдельных бандлов и автоматически выделить его в отдельный бандл.


          система сборки как-то перепишет мой код, что бы грузить сначала нужный бандл, вместо десятка скриптов для страницы?

          Не совсем понял, если честно. Да, webpack сделает один или несколько бандлов, но полностью автоматизировать ленивую подгрузку он не сможет.


        1. vintage
          22.10.2016 14:05

          Есть мнение, что лучше загрузить сразу все скрипты и положить их в кеш, зато потом переключать страницы мгновенно, чем быстро показать первую страницу, а потом тупить над каждой следующей.


          1. faiwer
            22.10.2016 17:13

            А истина где-то посередине. Проекты, их размеры, модульность, требования к проекту… всё это бывает очень по-разному. Webpack это такой монстр, которому это под силу. Мне кажется, именно для этого он и задумывался, т.к. эта часть его арсенала наиболее выдающаяся. Правда, похоже, современный frontend любит большие и сложные инструменты навязывать как для простых задач, так и для сложных.


        1. amakhrov
          22.10.2016 20:25

          что будет происходить с компонентами которые будут и в UserList, и в UserEditor использованы, но не в глобальных зависимостях?

          Отличный вопрос. Я его пока для себя так и не закрыл. Пока что все большие общие зависимости выношу в отдельный бандл (подключается всегда). А зависимости поменьше включаются в каждый бандл, где они используются. Мирюсь с небольшим оверхедом по размеру.


          Может знаете пример небольшого приложение, где будет разделение на страницы и соответственно сборка тоже по страницам

          https://github.com/davezuko/react-redux-starter-kit
          Здесь шаблон spa с парой преднастроенных страниц. И да, динамическая загрузка бандлов для них.


    1. neoxack
      21.10.2016 12:59

      Привёл 2 примера. Но по сути куда бы я не полез, везде, везде вынужден что-то городить. Т.к. то, что есть или не работает, или работает в пол-силы.

      Если использовать правильные инструменты и читать документацию, то никаких проблем с реактом и его экосистемой не возникнет.


    1. phoenixweiss
      21.10.2016 18:37

      Очень верный комментарий, тоже вот такие моменты раздражают.


    1. franzose
      23.10.2016 02:12

      В итоге оборачиваю точку входа setTimeout-ом (снова костыль) и получаю нормальные стектрейсы.

      А не могли бы вы чуть подробнее написать об этом? :)


      1. faiwer
        23.10.2016 08:58

        • SystemJS.import('app.js');
        • в app.js есть ошибка, скажем, вызов несуществующего метода или что-нибудь ещё
        • ошибка валится в консоль, скриншот я привёл. Основной стек-трейс абсолютно бесполезен. А настоящий вшит в message. Однако, в нём ссылки на транспайлернутый файл и строку в нём. Т.е. ткнув по ней в консоли вы попадёте не в оригинальный файл, а итоговый. А он может быть весьма страшным и неудобным. Более того если там какой-нибудь bundle, то он может быть ещё и громадным. Чёрт ногу сломит. Жить можно, но довольно грустно.
        • помещаем содержимое проблемной части кода в setTimeout и ошибка падает в консоль уже на следующем тике работы js-движка, без задействования System.js
        • наблюдаем нормальный stack-trace.


  1. Odrin
    21.10.2016 12:17

    для Angular2 альтернативы я пока не видел

    angular-cli?
    npm install -g angular-cli
    ng new PROJECT_NAME
    cd PROJECT_NAME
    ng serve
    


  1. Laney1
    21.10.2016 12:33
    +1

    В основном, из-за того, что некоторые браузеры очень медленно имплементируют новые стандарты (не будем показывать пальцем, но в основном это касается IE)

    строго говоря, IE сейчас вообще ничего не имплементирует — все новое MS запиливает, и довольно оперативно, в Edge
    В этом плане экосистема React достаточно устоялась, например, если вначале для React существовало множество Flux имплементаций, то сейчас большинство приложений использует Redux

    это вы далеки от истины) Сейчас многим нравится не redux, а mobx; создатель react недавно сказал, что если бы он писал react сейчас, то сделал бы как в inferno.js (такой же как react, но другой); плюс сейчас похоже все перейдут с npm на yarn. В общем, колесо сансары не только не думает останавливаться, но крутится даже быстрее)


    1. Ohar
      21.10.2016 12:44
      -1

      строго говоря, IE сейчас вообще ничего не имплементирует — все новое MS запиливает, и довольно оперативно, в Edge

      Каждый раз, когда слышу про то, что Edge — это совсем не IE, вспоминаю эту рекламу


      1. Odrin
        21.10.2016 12:48

        Тем не менее с поддержкой современных стандартов у Edge все довольно неплохо.


      1. zxcabs
        21.10.2016 13:35

        а если убрать бессмысленные придирки и посмотреть вот сюда: http://kangax.github.io/compat-table/es6/
        то можно заметить что edge имеет поддержку es6 даже больше чем babel, а отсутствующие фичи не так уж и критичны.


  1. Ohar
    21.10.2016 12:38

    del


  1. HexNeo
    21.10.2016 13:18
    -8

    Мне сегодня в голову пришло в чем проблема с развитием яваскрипта.
    Проблема в недообразованности.
    Есть ЧТО мы хотим сделать и что МОЖНО сделать, а как это программируется (ЯваСкрипт это язык программирования) только КАЖЕТСЯ что ясно.

    Вот приведу пример недообразованности:

    JSON это что? это JavaScript object notation, то есть ЯЗЫК описания обьектов используя язык JavaScript
    а в разговорах и везде используется как протокол передачи данных или как тип сервиса «передать джейсоном, вызвать джейсон»
    и дело не в том что людям лень говорить JSON over HTTP, а в том что проще о таких вещах НЕ ДУМАТЬ…

    JS был и до того как на нем придумали делать фронтенд. Мне кажется HTMLщики просто чувствовали себя ущербно из-за того что они не могут сделать сайт «полностью» без бакендеров. Вот это и привело к тренду программирования на JS.

    Kстати отдельная тема для разговора «есть во всех браузерах». Херушки нету.
    Потому как все бразуеры имплементируют реализацию языка сами. Нет производителя JavaScripta, а есть браузеры поддерживающие запуск текста на JS так, как им кажется верным. При должном развитии языка мы придем к ситуации в которой придется писать скрипт браузер депендент (как это было и слегка ощущуется и сейчас).

    Кстати себя я не считаю «шибко образованным» скорее наоборот.


    1. PaulZi
      21.10.2016 15:03

      Проблема JS в том что в нём дохрена всего нет, вот и появляется как на дрожжах фреймворки, которые решают недостатки JS.


    1. taujavarob
      21.10.2016 20:14

      HexNeo > Мне кажется HTMLщики просто чувствовали себя ущербно из-за того что они не могут сделать сайт «полностью» без бакендеров. Вот это и привело к тренду программирования на JS.

      Обсуждалось недавно. Тренд JS возник из-за увеличения скорости движка, появления движка V8 — он увеличил на порядок (в 10 раз) скорость выполнения JS, И вот тогда и понеслось. Ибо появился скоростной «мотор».

      А скоростной мотор — это всегда фан! ;-)

      HexNeo > Кстати себя я не считаю «шибко образованным» скорее наоборот.

      Это проходит со временем. ;-)


  1. TargetSan
    21.10.2016 14:23

    del


  1. vintage
    21.10.2016 20:59
    +1

    Для более удобной манипуляции css классами используется пакет "classnames".

    //import classnames from 'classnames';
    
    //let oneClass = classnames('foo', 'bar'); //значение "foo bar"
    
    let oneClass = ['foo', 'bar'].join(' '); //значение "foo bar"
    
    let isActive = true;
    
    //let anotherClass = classnames({
    //    'foo': true,
    //    'bar': false,
    //    'active': isActive 
    //}) // значение "foo active"
    
    let anotherClass = [ 'foo', isActive ? 'active' : '' ].join(' ') // значение "foo active"


  1. necotumusimnapsat
    23.10.2016 01:30

    Не пойму такое кол-во жалоб на JS в 2016, какая разница на чем вам писать и что учить когда на это есть спрос и вам за это платят?
    Свой проект можете писать на чем вам удобнее.
    На работе ипользуем frontend — синтаксис CoffeeScript в Google closure и React, backend Java, db PL/SQL, еще 2 месяца назад иногда пользовался jQuery а так в основном PHP, и проблем нет, фирма платит за обучение…


    1. taujavarob
      24.10.2016 18:00

      necotumusimnapsat >Не пойму такое кол-во жалоб на JS в 2016, какая разница на чем вам писать и что учить когда на это есть спрос и вам за это платят?… db PL/SQL ,,, фирма платит за обучение

      Ну, не всем же платят за программирование, например на PL/1.

      Поэтому народ и хочет писать на современных то языка и по современному. Тем более тренд есть к этому. А где тренд там и спрос на вакансии.

      Имхо, конечно, имхо.


  1. nicuini
    23.10.2016 16:29

    Rumbda? Ramda, наверное.


    1. xGromMx
      24.10.2016 01:40

      хорошо хоть не Rumba :D


    1. Yeggor
      25.10.2016 02:31

      да, точно, исправил, я сам пользуюсь lodash, ramda для примера привел :)