Как стать автором
Обновить
87
0

Пользователь

Отправить сообщение
Все нормально с «расшифровкой» хорошо написанного полгода назад Angular-кода, пусть и нетривиального. Его главный недостаток, как мне видится — отсутствие какого-то единого направления по работе с моделями и, иногда, слишком много способов решить одну задачу.

Насчет атрибутов — это одна из киллер-фич, однозначно. Никакие они не магические. Директивы, которые «цепляются» к атрибутам — это самый что ни на есть «unobtrusive JavaScript». Например, вы же можете добавить какой-нибудь атрибут, вроде 'data-tooltip=«Hi I am a tooltip»' к элементу, чтобы потом с помощью JS найти этот элемент и реализовать логику этого самого tooltip-а. То же самое и здесь, только возможностей куда больше. По сути, ни для чего, кроме вашего приложения такой атрибут смысла не несет в любом случае, а директиву можно привязать к любому из существующих элементов или атрибутов.

Насчет изучения множества новых концепций — согласен, порог входа низок, но чтобы сделать что-то реальное — вначале нужно сломать немало копий.
Не спорю — веб-компоненты — шикарная штука, очень ждем ее и все такое. Однако, это никак не избавляет от проблем, связанных с самой концепцией SPA-приложений. Просто какие-то вещи решаются нативными средствами, но логику-то все равно писать на старом добром JS, который с поисковиками (пока) не дружит. Что касается чистоты, инкапсуляции и элегантности подхода в целом — все гуд.
Веб-Компоненты и React/Ember/Angular/etc — никак друг другу не противоречат.

React.js — это генерация разметки с помощью JS, а значит поисковые системы это не увидят, а значит нужно делать fallback на серверном языке, а значит двойная работа.

Во-первых, вопрос касается не только React — это относится к любым генерируемым на клиенте UI. А во-вторых — все современные поисковики поддерживают индексацию AJAX-контента (на примере Гугла, но и у Яндекса, и у Бинга тоже это есть). Кроме прочего, Гугл активно «учится» выполнять JS, ну и напоследок — задача индексации замечательно решается, просто нужен другой подход — сервисы, вроде Prerender.io именно для этих целей.
Могли бы пояснить, чем Angular — «костыли в чистом виде»?
Ну в Backbone то тоже низкий, чего там может быть сложного. Бойлерплейта много получается в обоих случаях. Но код React, впрочем, немного посовременнее выглядит, однако JSX — это «вырви глаз».

Насчет подхода — очень похоже на Angular, но в последнем присутствует куда более мощная концепция директив и никакого HTML в контроллерах.
Ну, если речь про голый React, то по ходу дела даже голый Backbone и тот понятнее в итоге. Но в случае с Мореарти (название глаз режет :) получилось в самом деле компактно
// Sass

.scr {
  float: left;
  display: inline-block;
  width: 25%;

  @media #{$medium-or-less} {
    width: 50%;
  }
}
Блин! К чертям такую «авиацию», для которой софт в каком-либо виде завязан на WinXP-SP2!
Так к тому и вопросы, что эти задачи решаются при использовании любого формата модулей и нет никакой очевидной необходимости менять их в зависимости от масштаба/сложности проекта. AMD по определению поддерживает асинхронную подгрузку. Бандлы, очевидно, можно создавать с помощью r.js. Что касается ES6-модулей, то там вообще круто разделено само определение модуля и способ его загрузки — «бандлить» можно как угодно и транс-компилировать в AMD (если нужно) или в CommonJS (для Browserify-подобных упаковщиков).
Ну, если работаете уже со всеми форматами модулей — достаточно разобраться и настроить один раз.

И если уже работаете с ES6-модулями, то зачем Browserify?
А как масштаб проекта влияет на выбор формата модулей?
К слову, сейчас транс-компиляция все равно идет в один из существующих форматов модулей в зависимости от того, каким образом нужно модули использовать. И если нужно что-то лениво подгружать — в итоге технически используются именно AMD-модули для этого.
А в чем проблема? Lazy-loading то можно реализовать. Я понимаю, как работает require, если ему передать строку — require('some-module') — он будет искать этот модуль, причем еще до загрузки основного модуля, который содержит такой вызов (парсит все содержимое функции в виде строки). А что насчет require(['module-name'], function (module) {… })? То, что возвращает загруженные модули — это понятно, более того, поддерживает их состояние.

Насчет собственных модульных систем — ни к чему, как по мне. Сам не особо рад оберткам в виду «define» для всех AMD-модулей (отчасти решается build-процессом), но тут еще вопрос совместимости с другими разработками и сторонними библиотеками. Ну и сейчас уже, похоже, время переходить на ES6-модули, где, наконец-то, определение модуля не зависит от того, как он будет загружаться.
AMD-модули асинхронны по-определению. Никто не мешает вызвать «require» внутри какой-нибудь функции, и загрузка модуля начнется только после этого (если не был ранее затребован и загружен каким-нибудь другим вызовом «require»).

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

Другой способ — когда мы изначально подключаем все компоненты Angular, но в каждом из них только по необходимости запускаем загрузку модуля, который непосредственно исполняет код. То есть, к примеру, в качестве контроллера создаем функцию, которая сначала все загружает, и только по факту загрузки выполняет нужную работу. Таким образом, приложение изначально «знает» обо всех своих компонентах, но не в курсе, что они на самом деле делают. Не самый гибкий способ, но также вполне работоспособный. Только надо аккуратно запускать $digest-цикл вручную.
А тут все очень просто.

Папки:
static/
  css/     (здесь хранится скомпилированный, но еще не уменьшенный css, содержит source-maps)
  fonts/   (здесь подключаемые шрифты)
  img/     (здесь общие картинки и SVG, которые не меняются, лого, иконки)
  js/
    app/ (здесь Angular приложение)
      ...
      components/ (повторно используемые, независимые от бизнес-логики компоненты)
      core/       (здесь основа приложения, layout-директивы, лэйауты, аутентификация, и так далее)
        controllers/
        models/
        services/
        templates/      (использование отдельных подпапок "templates" - дело вкуса и размера проекта)
          header.html
          main-content.html
          ...
      features/         (различные элементы, "фичи", специфичные для приложения)
        account/
          controllers/
          services/
          models/
          templates/
          init.js       (подключаемый модуль "фичи", собирает все контроллеры, сервисы, роуты)
          routes.js     (роуты "фичи")
        some-feature1/
        some-feature2/
      ...
      app.js      (сам файл приложения, подключение зависимостей, и прочее)
      init.js     (загрузочный файл приложения, аналог bootstrap.js из топика)
      routes.js   (общие маршруты приложения и маршруты по-умолчанию)
    main.js   (файл настроек require.js, обычно он же запускает по-умолчанию модуль "app/init", директория "static/js" устанавливается базовой для require.js)
  lib/   (здесь находятся все зависимости для клиента, bower устанавливает свои компоненты сюда)
  sass/
    ...
    _some-styles.scss (файлы с префиксами - партиалы, подключаются в app.css
    app.scss (файл стилей, только он компилируется sass-ом)
index.html (точка входа, загружаемая страница может генерироваться сервером, а может отдаваться в статическом виде напрямую из корня проекта)


Пара замечаний:
— Во время запуска build-процесса в корне создается папка dist. Ее структура повторяет папку проекта в целом, но содержит оптимизированные версии js/css-файлов.
— Для production все шаблоны собираются в отдельный js-файл, являющийся AMD-модулем, содержимое которого включается в основной JS-файл приложения (то есть, шаблоны не загружаются асинхронно в продакшене).
Да отнюдь не миф — более того, еще и легко упаковывается в Cordova/PhoneGap и запускается на мобильниках (обычно спец-версия с дополнительными оптимизациями).

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

Для какого «каждого языка»? Шаблоны Angular-приложения — это шаблоны, которые доступны только этому приложению, это его view-слой.

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

Зачем? А media-queries? А если прямо отдельное что-то, например, для особых платформ, вроде старых мобильников — то проще делать отдельное приложение для них, нежели утяжелять/усложнять основное, поскольку самый камень преткновения, обычно, скрипты, а не разметка.
Ну, в идеале, если это отдельное приложение — оно вообще целиком статика, работающее с Web-API (http/websockets). И его проще воспринимать именно как отдельное приложение, а не как некую структуру, части которой генерируются на сервере. То есть, после загрузки страницы, все данные идут в виде JSON.

Стили я тоже не сторонник хранить разбросанными по приложению. Они вообще лежат за пределами папки приложения — у них просто сильно другая структура организации и очень много абстрактных/общих компонентов.
А require.js все равно не обеспечивает «ленивой загрузки».

Именно это он и обеспечивает при необходимости. Ну это так, к слову :)
Ну Express — это не HTTP-сервер, это утилита вокруг http-модуля самого Node. Что же там за велосипед, который умудряется так замедлить работу сервера?

Информация

В рейтинге
Не участвует
Дата рождения
Зарегистрирован
Активность