Skip to content

Instantly share code, notes, and snippets.

@tomfun
Last active July 7, 2016 12:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomfun/68ac0236b8eddc9cacd98cbd3f536567 to your computer and use it in GitHub Desktop.
Save tomfun/68ac0236b8eddc9cacd98cbd3f536567 to your computer and use it in GitHub Desktop.
how to be with frontend dependencies

Предложение к разработке новых продуктов внутри custom отдела

Глоссарий

bundle - пакет/библиотека содержащая в себе ресурсы и код для бекенда и фронтенда. у бандла обязательно есть версия, он ставится через пакетный менеджер.

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

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

Проблематика

Конфликт

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

Пример конфликта

Два разных бандла требуют разную версию jQuery. В браузере 2 разные jQuery использовать нельзя. Должна быть выбрана 1 версия, которая будет удовлетворять оба бандла.

Решение 1

Обновляется бандл, который использует неактуальную версию jQuery, исправляются проблемы, связанные с этим.

Решение 2

В проекте ставится другая версия этого пакета (jQuery), проверяется работоспособность бандлов.

Ресурсы

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

Пример

Листинг товаров использует бекбон модель категории для фильтрации в одной категории. Приложению удобно отэкстендиться от этой модели и добавить в неё/изменить метод getCategoryUrl основанный на требованиях к конкретному проекту.

Решение

Бандл должен быть написан так, чтобы можно было взять атомарную еденицу - одну конкретную модель.
Исходные части бандла категории должны быть доступны в приложении, через requirejs мы меняем путь (map) к коткретной модели и заменяем её своей.

EntryPoint

Бандл как правило имеет входные точки для конечного пользователя - страницы, на которых отображаются нужные UI элементы. Для высокой скорости и удобства пользователя, должна быть возможность предзагрузки ресурсов (js, css, twig, ...) и данных (json data).

Пример

Админка категорий.

Решение

Бандл имеет страницу категорий, которая наследуется от универсального базового twig шаблона, внутри этого шаблона сам бандл выводить в некоторую глобальную js переменную нужные данные (список категорий...) и подключает ресурсы (шрифты, css), подключает через requirejs нужную entryPoint, не пишет в шаблоне никаких другий js моделей, вьюшек, данных, всё это должно быть в этой entryPoint. -И указывает параметры сборки и ряд этих entryPointов.- В галп файле проекта пишется rjs таск для сборки этой конкретной страницы и заменяется entryPoint файл на скомпилированный. В худшем случае, надо заоверрайдить twig шаблон на бекенде и создать entryPoint, если этого не было в бандле.

Предложение

  • использовать единый gulp файл/набор gulp задач
  • этот gulp файл должен будет поддерживать всегда одну и ту же структуру
  • внутри него должен быть механизм резолвинга зависимостей к бандлам
  • внутри него будет встроеный механизм билдинга rjs

Структура конфига и детали

В галпфайле указывается путь к файлу, в котором лежит конфигурация бандлов. Также указывается папка в которой будут устанавливаться зависимости с помощью npm. Сам проект (т.е. папка node_modules уровнем выше) будет использована как фолбек. Т.е. пока в браузере нужен тот же twig, что и на сервере, он не будет отдельно ставиться.

сама конфигурация файлов описывается в json5 формате, пример:

{
  frontendProject: {
    bundlePaths: [
      'from/project/root/to/src/of/bundle'
    ],
    resolves: {
      twig: "^2.1.0",
      jquery: "~2.1.4"
    },
    locations: {
      twig: {
        'node_modules/twig/twig.min.js': 'twig'
      }
      jquery: {
        'node_modules/jquery/dist/jquery.min.js':  'jquery',
        'node_modules/jquery/dist/jquery.min.map': 'jquery',
      }
    }
  }
}

Этот файл будет перезаписываться при необходимости. Предполагается, что раздел locations это дополнение, по которому мы знаем, как обрабатывать пакеты npm (twig), указывая, какие файлы из пакета нужно прокинуть в public папку проекта, и возможно переименовать, оставив старый тип (twig.min.js -> twig*.js*)

resolves даёт возможность указать версию пакета, которая, при конфликтных зависимостях будет выбрана.

В bundlePaths указывается массив путей к папке, в которой есть папка frontend в котороый расположены все исходные коды для браузера и файл package.json в котором есть дополнительный ключ frontendDependencies, пример отрывка package.json:

{
  "name": "brander-cms-bundle",
  "version": "0.0.0",
  "dependencies": {"...": "..."},
  "frontendDependencies": {
    "twig": "^2.1.0",
    "jquery": "~2.1.4"
  },
  "frontendProject": {
    "entryPoints": {
      "brander-cms-bundle/pages/path/to/file/without/extension": {"out": "built_file_name.js"}
    },
    "locations": {
      "twig": {
        "node_modules/twig/twig.min.js": "twig"
      }
    }
  }
}

В папке frontend есть папка js в ней будут все файлы (es6, js, ts, jsx, tsx, coffee) так как они превращаются в js файлы. Обязательно в этой папке должен быть конфиг, по которому происходит сборка, на данный момент распространённый пример это .babelrc, также в будущем tsconfig.json, возможно webpack.config.js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment