Собираем простое MariontteJS+ES6 приложение с помощью Brunch

    Здравствуйте. Я хотел бы рассказать как с помощью Brunch можно собрать MariontteJS+ES6 приложение.



    Сегодня уже 2016-й год и способов собирать приложения очень много. Ниже я предлагаю рассмотреть Brunch

    Ставим brunch глобально и генерируем пустой скелет
    npm install -g brunch
    brunch new


    Если не хотите его ставить глобально тогда просто
    git clone github.com/brunch/dead-simple

    Все равно будем запускать brunch с помощью npm.

    Теперь нужно сконфигурировать package.json и bower.json.

    package.json
    {
      "name": "marionette-es6-brunch",
      "description": "Marionette brunch es6 simple app",
      "author": "denar90",
      "version": "0.0.1",
      "license": "MIT",
      "repository": {
        "type": "git",
        "url": "https://github.com/denar90/marionette-es6-brunch"
      },
      "scripts": {
        "postinstall": "./node_modules/.bin/bower install",
        "start": "./node_modules/.bin/brunch w --server"
      },
      "dependencies": {
        "javascript-brunch": "~1.8.0",
        "css-brunch": "~1.7.0",
        "stylus-brunch": "~1.8.1",
        "handlebars-brunch": "~1.9.0",
        "uglify-js-brunch": "~1.7.8",
        "clean-css-brunch": "~1.8.0",
        "jshint-brunch": "~1.8.0",
        "babel-brunch": "~6.0.0",
        "babel-preset-es2015": "~6.3.13",
        "babel-plugin-transform-decorators-legacy": "~1.3.4",
        "bower": "~1.7.2",
        "brunch": "~2.1.0"
      }
    }
    


    bower.json
    {
      "name": "marionette-es6-brunch",
      "version": "0.0.1",
      "dependencies": {
        "marionette": "~2.4.4",
        "bootstrap": "~3.3.2",
        "core.js": "~2.0.2"
      }
    }
    


    Нам особенно интересны эти библиотеки:
    • babel-brunch
    • babel-preset-es2015
    • babel-plugin-transform-decorators-legacy
    • core-js

    Именно они делают всю магию с es6.

    Перейдем к конфигу самого brunch.

    brunch-config.js
    exports.config = {
      paths: {
        watched: ['app']
      },
      files: {
        javascripts: {
          defaultExtension: "js",
          joinTo: {
            "javascripts/app.js": /^app/,
            "javascripts/vendor.js": /^bower_components/
          },
          order: {
            before: [
              'bower_components/jquery/dist/jquery.js',
              'bower_components/underscore/underscore.js',
              'bower_components/backbone/backbone.js',
              'bower_components/marionette/lib/backbone.marionette.js',
              'bower_components/bootstrap/dist/js/bootstrap.js'
            ]
          }
        },
        stylesheets: {
          defaultExtension: "styl",
          joinTo: "stylesheets/app.css"
        },
        templates: {
          defaultExtension: "hbs",
          joinTo: "javascripts/app.js"
        }
      },
      plugins: {
        babel: {
          presets: ['es2015'],
          ignore: [
            /^(bower_components|vendor|node_modules)/
          ],
          pattern: /\.(es6|jsx)$/,
          plugins: ['babel-plugin-transform-decorators-legacy']
        }
      },
      modules: {
          autoRequire: {
            'javascripts/app.js': ['initialize']
        }
      },
      server: {
        port: 8080,
        run: true
      }
    };
    


    Вот строчки которые помогают билдить es6

    ...
    plugins: {
        babel: {
          presets: ['es2015'],
          ignore: [
            /^(bower_components|vendor|node_modules)/
          ],
          pattern: /\.(es6|jsx)$/,
          plugins: ['babel-plugin-transform-decorators-legacy']
        }
      }
    ...
    

    Теперь можно спокойно перейти к коду. Здесь все стандартно: Model, View, и т.д.
    Единственный момент на который хотелось бы обратить внимание — это установка атрибутов. Есть несколько способов:

    export default class ItemView extends Marionette.ItemView {
        tagName() { return "li"; }
    
        constructor(options) {
            super(options);
        }
    }
    

    export default Marionette.ItemView.extend({
        tagName: 'li',
    
        initialize(options) {
        }
    });
    

    import { props } from 'decorators';
    
    @props({
        tagName: 'li'
    })
    export default class ItemView extends Marionette.ItemView {
        initialize(options) {
        }
    });
    

    Мне нравится последний способ. Я нашел его здесь

    Выполняем
    npm start
    

    и наслаждаемся своим творением открыв в браузере localhost:8080/.

    Единственное что нам еще нужно — это тесты.
    Наши тесты будут лежать в папке specs.

    Добавим devDependecies в нашем package.json файле
    "devDependencies": {
        "phantomjs": "~1.9.18",
        "coveralls": "~2.11.6",
        "karma": "~0.13.19",
        "karma-es6-shim": "~0.2.3",
        "karma-mocha": "~0.2.1",
        "karma-chai-plugins": "~0.6.1",
        "karma-coverage": "~0.5.3",
        "karma-coveralls": "~1.1.2",
        "karma-phantomjs-launcher": "~0.2.3"
      }
    

    Немножко изменим brunch-config.js

    brunch-config.js
    exports.config = {
      paths: {
        watched: ['app', 'specs']
      },
      files: {
        javascripts: {
          defaultExtension: "js",
          joinTo: {
            "javascripts/app.js": /^app/,
            "javascripts/specs.js": /^specs/,
            "javascripts/vendor.js": /^bower_components/
          },
          order: {
            before: [
              'bower_components/jquery/dist/jquery.js',
              'bower_components/underscore/underscore.js',
              'bower_components/backbone/backbone.js',
              'bower_components/marionette/lib/backbone.marionette.js',
              'bower_components/bootstrap/dist/js/bootstrap.js',
              'bower_components/es6-shim/es6-shim.js'
            ]
          }
        },
        stylesheets: {
          defaultExtension: "styl",
          joinTo: "stylesheets/app.css"
        },
        templates: {
          defaultExtension: "hbs",
          joinTo: "javascripts/app.js"
        }
      },
      plugins: {
        babel: {
          presets: ['es2015'],
          ignore: [
            /^(bower_components|vendor|node_modules)/
          ],
          pattern: /\.(es6|jsx)$/,
          plugins: ['babel-plugin-transform-decorators-legacy']
        }
      },
      modules: {
          autoRequire: {
            'javascripts/app.js': ['initialize']
        }
      },
      server: {
        port: 8080,
        run: true
      },
      overrides: {
        testing: {
          modules: {
            autoRequire: {
              'javascripts/specs.js': ['specs/initialize']
            }
          }
        }
      }
    };
    



    Создадим наш
    karma.conf.js
    module.exports = function(config) {
        config.set({<code>
            browsers: ['PhantomJS'],
            frameworks: ['mocha', 'chai', 'es6-shim'],
            files: [
                "public/javascripts/vendor.js",
                "public/javascripts/app.js",
                "public/javascripts/specs.js"
            ],
            reporters: ['coverage', 'coveralls'],
            preprocessors: {
                'public/javascripts/app.js': 'coverage'
            },
            coverageReporter: {
                type: 'lcov',
                dir: 'coverage/',
                subdir: '.'<a href="https://github.com/denar90/marionette-es6-brunch"></a>
            },
            singleRun: true
        });
    };
    


    И добавим еще один скрипт в package.json.

    "test": "./node_modules/.bin/brunch b --env testing && ./node_modules/.bin/karma start karma.conf.js"
    


    Для полноты картины сделаем интеграцию с Travis CI.
    travis.yml
    language: node_js
    node_js:
      - '4.0'
    after_script:
      - cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
    


    Мой пример можно посмотреть здесь.

    Спасибо за внимание.
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 5
    • +1
      А в чем преимущество с Brunch и с чем его сравнивать?
      • 0
        Его авторы указывают на преимущества перед Grunt и Gulp: простота и быстродействие.
        • +1
          Про Gulp рассказывали то же самое:) С простотой оказалось не все так просто, а скорость достигается за счет параллелизации — благодаря которой очень трудно понять, что же именно тормозит:) Но конфиг из примера выглядит достаточно приятно.
          • +1
            Автор Brunch немного лукавит приводя на сайте типичные примеры конфигов grunt, gulp и brunch. Для конкурентов приведён полный боекомплект, а для своего продукта элементарнейшый случай. И за маркетингом сразу не понять, действительно ли конфиги brunch проще.
            • 0
              Ну они реально проще, ибо если, скажем, gulp — по сути, утилита для создания своего build-pipeline-а, то Brunch — это уже готовый пайплайн, то есть просто более высокий уровень. При работе с gulp в больших проектах кроме самих gulp-тасков обычно появляются такие высокоуровневые конфиги аля brunch.

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