Добрый день, мир не стоит на месте, в прошлом году состоялся релиз ECMAScript 2015 (он же ES6), который привнес множество нововведений, огорчает лишь одно ExtJS и Sencha cmd пока не научились поддерживать данную спецификацию. Причин для того, что бы уже сейчас разрабатывать приложение с учетом ES6 множество. Основные как мне видится — изучение нового стандарта (ваша рыночная конкурентно-способность возрастает) и создание более простого и лаконичного кода, который радует глаз. В данной статье показывается процесс добавления возможности писать ES6 код для ExtJS, с помощью кросс-компилятора Babel со сборкой на лету.

Настройка Babel


Для начала, нам понадобится создать тестовое приложение

sencha -sdk "path\to\framework" generate app TestApp "path\to\application"

Так же нам понадобится npm для установки Babel. В корневой директории созданного приложения, создадим файл package.json с помощью команды

npm init

Console output


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

npm install babel-cli --save-dev

npm install babel-preset-es2015 --save-dev

Далее необходимо добавить команды сборки проекта, для этого добавляем в package.json секцию scripts. Так же не забудем добавить плагины для Babel, без них от просто не будет работать, для этого добавим секцию Babel.

...
  "scripts" : {
    "build-prod": "./node_modules/.bin/babel es6 -d app --comments=false --compact=true",
    "build-debug": "./node_modules/.bin/babel es6 -d app --sourceMaps=true",
    "watch": "./node_modules/.bin/babel es6 -d app --watch"
  },
  "babel": {
    "plugins": [
      "check-es2015-constants",
      "transform-es2015-arrow-functions",
      "transform-es2015-block-scoped-functions",
      "transform-es2015-block-scoping",
      "transform-es2015-classes",
      "transform-es2015-computed-properties",
      "transform-es2015-destructuring",
      "transform-es2015-for-of",
      "transform-es2015-function-name",
      "transform-es2015-literals",
      "transform-es2015-object-super",
      "transform-es2015-parameters",
      "transform-es2015-shorthand-properties",       
      "transform-es2015-spread",       
      "transform-es2015-sticky-regex",       
      "transform-es2015-template-literals",       
      "transform-es2015-typeof-symbol",       
      "transform-es2015-unicode-regex",       
      "transform-regenerator", 
      [ "transform-es2015-modules-commonjs", { "strict" : false }]
    ]
  }
...


Настройка Sencha cmd


Со стороны ExtJS проекта, необходимо перенести файл app.js из корня проекта в папку app. Далее папку app необходимо переименовать в es6.

mv app.js app
mv app es6

Не забудьте указать новое расположение app.js в файле app.json.

...
    "js": [
...
        {
            "path": "app/app.js",
            "bundle": true
        }
    ]
....

Остался последний шаг, отредактируем файл build.xml в корне проекта, добавив в него следующую конструкцию внутрь тега project

<target name="-before-build">
	<x-shell reloadprofile="true" dir="${basedir}">
		npm run build-debug
	</x-shell>
</target>

Теперь при любых командах sencha (build, watch, refresh) проект будет пересобран на лету, весь исходный код приложения следует хранить в папке es6. Поздравляю, теперь вы можете двигаться в ногу со временем :)

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


  1. bromzh
    08.04.2016 21:26

    Ну т.е. просто запускаем babel перед сборкой. Как-то тривиально для целой статьи.


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

    Можно просто создать в корне файл .babelrc с таким содержимым:


    {
      "presets": ["es2015"]
    }

    "build-prod": "./node_modules/.bin/babel es6 -d app --comments=false --compact=true",

    А почему для прода не генерируются source-map'ы?


    И кстати, всё это дело можно настроить, чтобы поддерживало import'ы из es6?


    1. ChALkeRx
      09.04.2016 09:17

      Импорты из es6 пока не стандартизованы полностью, так что имейте это ввиду при использовании их через babel.
      Вполне может оказаться что когда всё остальное заработает и без babel — импорты придётся переделывать.


      1. bromzh
        09.04.2016 10:28

        Хм, вообще-то синтаксис модулей (import/export) включён в стандарт и не изменится. Сейчас babel просто заменяет их на require. По-сути, это синтаксический сахар над CommonJs-овскими require/module.exports и деструктуризация (когда импортируется с фигурными скобками). Так что код менять не придётся.


        А вот как загружать и где искать модули — пока не утверждено. Но есть загрузчики модулей, например webpack или SystemJs.
        Так что тут больше вопрос в том, как настроить ещё и загрузчик в связке с ExtJS, удобно ли будет пользоваться, и т.д. На npmjs нет extjs.
        Сам же extjs использует свою функцию require. И оно понятно почему: библиотека старая, создавалась когда модулей и в зачатках не было.
        Но, например, ангуляр (первый) тоже использует свои функции для загрузки модулей и проверки зависимостей, так как он тоже уже достаточно древний. Однако, его легко включить в современную es6-инфраструктуру: модуль экспортирует просто своё имя. Потом мы импортируем его и добавляем в список зависимостей. Ну и почти все ангуляр-пакеты следуют этому принципу. Так что можно писать так:


        import angular from 'angular';
        import uiRouter from 'angular-ui-router';
        
        angular.module('app', [uiRouter]);

        А что у ExtJS?


        1. ChALkeRx
          09.04.2016 10:51

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

          Например, если вы использовали Babel на стороне Node.js и использовали import — с большой долей вероятности вам придётся как минимум поменять расширение всех файлов к тому времени, как это заработает нативно.

          Одна из проблем при загрузке модулей — отличить модуль от обычного js файла, у них семантика различается (как минимум, модули всегда в strict mode). Плюс надо чтобы модули могли использовать cjs, и чтобы cjs мог использовать модули, и чтобы при использовании сторонних пакетов вам было всё равно, на чём они написаны.

          В общем и целом, в Node.js решили идти по пути отдельного расширения файлов для модулей.

          Что конкретно у ExtJS — не знаю =).


          1. kosmonaFFFt
            11.04.2016 08:29

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


  1. Demogor
    09.04.2016 12:11

    Есть еще 1 «bit hackish way», что бы не тащить пачку зависимостей — берем https://github.com/Daniel15/babel-standalone. Для разработки можно на этом и остановиться, для продакшна можно либо прогнать все файлы ручками и подключить готовые версии, либо подключить какой-нибудь file-watcher, который, реагируя на изменения, будет пересохранять исходники в отдельную папку.