JavaScript 2016, а можно попроще?

  • Tutorial

Последние полгода много пишут о неоправданной сложности клиентского 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
  • +3

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

    • +3

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

      • +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.

        • 0

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

          • 0

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

            • 0

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


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

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

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

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

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


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

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

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

        • +1

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

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

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

              • НЛО прилетело и опубликовало эту надпись здесь
                • 0

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

                    Имхо, конечно, имхо.
                    • 0
                      У меня другое мнение:

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


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

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

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


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

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

                      Имхо, конечно, имхо.
                      • 0
                        gen_dalf > Это можно выразить одним словом — тут анархия!

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

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

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

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

                        Стоп! — Нью-Йорк я уже представил себе совершенно иначе! ;-)
                      • 0
                        Последнее что нужно заказчику — это знать что его проект пишется на ныне модной технологии которая через год может просто кануть в лету.

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

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

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

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

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

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

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

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

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

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

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

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

                          Так вы нормально двигаетесь то, шагами и с перспективой на пару(!) лет, а не застряли в версии 2, к примеру этих Ruby / Rails. ;-)
                          • 0
                            По сабжу — все упирается в конкретику, но в общем современный фронтенд все же значительно более хаотичен и подвержен критичным изменениям, нежели бэкенд. К сожалению, по Python-у поддержать беседу не могу, ибо крайне слабо с ним знаком.

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

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

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

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

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

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

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

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

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

                    • 0
                      «тянуть React» — как будто это монстр-фреймворк, а не просто view. К тому же, можно использовать preact (3kb gzip)
                    • +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 и тд. Минимум усилий для нормального старта + документация на уровне
                      • 0
                        >> ember server
                        но я не хочу сервер на js.
                        • +1
                          Так Вам никто и не предлагает это на прод выкатывать. js server нужен для разработки и локального запуска. Хотите использовать другой сервер — никаких проблем.
                          • 0
                            Я в принципе бэкенд на js не хочу.
                            Было бы удобно взаимодействие с клиентом по rest/soap/etc… без жесткой зависимости клиент-серверной архитектуры.
                            В принципе, выскажу крамольную мысль, что по факту Rich UI (Недавняя статья на хабре) удобнее чем полноценный MVC фреймворк на клиенте.
                            Как мне видится нормальная разработка:
                            Клиенту сгружаются сырые данные, js фреймворк их превращает в модели, готовая GUI компонета их отображает. Нам остается реализовать обработчики событий, фильтры и т.п.
                            • +3
                              А при чем тут бэкенд на js? Есть Ember, есть ajax запросы, делайте бэк на чем Вам угодно.
                              • 0
                                Так опять никто и не говорит о бекенде на javascript. У нас несколько проектов где фронт на EmberJS а бекенд на Symfony. Здесь ember server только для разработки фронта (под капотом ember server поднимает livereload что позволяет сразу видеть проводимые изменения). Подозреваю что вы не просто не так меня поняли =)
                                • 0
                                  Ember при билде собёртся в 4* файлика. 2 js, 2cs + статика. Всё. Далее вы эти файлики скармливаете беку и nginx.
                          • +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


                            Чудесный стек-трейс. Ни бита полезной информации. Он зашит в message. Содержит пути на строки кода файла без учёта sourcemap. Прямо мечта. Особенно если это bundle на десяток тыщ строк. В итоге оборачиваю точку входа setTimeout-ом (снова костыль) и получаю нормальные стектрейсы.


                            Навеяло

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


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

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

                                  • +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

                                      Я уже понял, что вы не используете 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
                                        но вы же, вроде, сами хотели, чтобы компьютер сам резолвил все зависимости и позволял вам пользоваться всеми достижениями js-человечества.

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


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

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


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

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


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

                                        • +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 лучше, чем загрузить один бандл, который нам "не нужен"?

                                          • 0

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


                                            • Вы говорите, что 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
                                              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) В вебпак кофиге это ни как реализовывать не нужно, просто нужно подключить только ту локализацию которая нужна прямо в коде приложения
                                              • 0

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

                                              • +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

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

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

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

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

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


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

                                            • +1

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

                                              • 0

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

                                                • +1

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


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


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


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

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

                                                  • 0

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


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

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

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

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

                                                      Поэтому


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

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


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

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


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

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


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

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

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

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


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

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


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

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

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

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

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

                                              • 0

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


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

                                                • 0

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

                                                  • 0

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

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

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

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

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


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

                                                            • 0

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

                                                              • 0

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

                                                                • +1

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

                                                                  • 0

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

                                                                    • 0

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

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

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

                                                              • +1

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

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

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


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


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

                                                                    • 0

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

                                                                      • 0

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

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

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

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

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

                                                                            • 0

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

                                                                              • 0

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

                                                                                • 0

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


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

                                                                                  • 0

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

                                                                                  • 0

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

                                                            • 0

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

                                                          • 0

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


                                                            Надо


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

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

                                                            • +1

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

                                                              • 0

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

                                                                • 0

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

                                                                  • 0

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

                                                                    • 0

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

                                                                      • 0

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

                                                                      • 0

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

                                                      • 0

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


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

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

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

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


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

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


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

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


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

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

                                                          • 0

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

                                                            • 0

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

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

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


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

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

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

                                                            Если использовать правильные инструменты и читать документацию, то никаких проблем с реактом и его экосистемой не возникнет.
                                                            • 0
                                                              Очень верный комментарий, тоже вот такие моменты раздражают.
                                                              • 0
                                                                В итоге оборачиваю точку входа setTimeout-ом (снова костыль) и получаю нормальные стектрейсы.

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

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

                                                                angular-cli?
                                                                npm install -g angular-cli
                                                                ng new PROJECT_NAME
                                                                cd PROJECT_NAME
                                                                ng serve
                                                                
                                                                • +1
                                                                  В основном, из-за того, что некоторые браузеры очень медленно имплементируют новые стандарты (не будем показывать пальцем, но в основном это касается IE)

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

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

                                                                    Каждый раз, когда слышу про то, что Edge — это совсем не IE, вспоминаю эту рекламу
                                                                    • 0
                                                                      Тем не менее с поддержкой современных стандартов у Edge все довольно неплохо.
                                                                      • 0
                                                                        а если убрать бессмысленные придирки и посмотреть вот сюда: http://kangax.github.io/compat-table/es6/
                                                                        то можно заметить что edge имеет поддержку es6 даже больше чем babel, а отсутствующие фичи не так уж и критичны.
                                                                    • 0

                                                                      del

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

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

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

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

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

                                                                        Кстати себя я не считаю «шибко образованным» скорее наоборот.
                                                                        • 0
                                                                          Проблема JS в том что в нём дохрена всего нет, вот и появляется как на дрожжах фреймворки, которые решают недостатки JS.
                                                                          • 0
                                                                            HexNeo > Мне кажется HTMLщики просто чувствовали себя ущербно из-за того что они не могут сделать сайт «полностью» без бакендеров. Вот это и привело к тренду программирования на JS.

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

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

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

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

                                                                          • 0

                                                                            del

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

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

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

                                                                                  Имхо, конечно, имхо.
                                                                                • 0
                                                                                  Rumbda? Ramda, наверное.
                                                                                  • 0
                                                                                    хорошо хоть не Rumba :D
                                                                                    • 0

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

                                                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.