WebJars + RequireJS

День добрый, читатели Хабра! В этой статье спешу вам рассказать (хоть и с опозданием) о том что такое WebJars на примере приложения в Play Frameworkimage В практически любом веб-приложении нельзя обойтись без сторонних javascript-библиотек. Самый простой способ добавить их: скачать и добавить в проект, а также добавить файл в git-репозиторий. Решение годное, но лично для меня наличие в проекте какой-либо статики малость раздражает. Есть другой метод: указывать ссылку на внешний хостинг js-библиотек такой как google, yandex. В принципе вариант, но в моей практике были случаи, когда необходимо было продолжить разработку, а доступ в интернет оставлял желать лучшего либо его вообще не было, в итоге клиентская часть не функционировала. Наиболее годным решением мне видится добавления js библиотеки в качестве зависимости в проект, с подобным подходом вы могли сталкивать в Ruby on Rails

Ближе к делу

У нас есть веб-приложение, написанное на java-based языке и нам нужно добавить в него пару javascript библиотек, именно для такого случая нам идеально подойдут WebJars

WebJars — набор библиотек, каждая из которых содержит в себе JS библиотеку и/или CSS модули

Полный список библиотек можно посмотреть здесь. У каждой из них есть несколько версий которые соответствуют версии js-библиотеки. Все WebJars доступны на Maven репозитории

В данном примере я опишу, как WebJars в приложение Play Framework. Описания добавления WebJars в другие фреймворки можно найти здесь

Приступаем

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

К примеру

libraryDependencies ++= Seq ( cache, ws, «org.webjars» %% «webjars-play» % »2.3.0–2», «org.webjars» % «requirejs» % »2.1.14–3», «org.webjars» % «requirejs-domready» % »2.0.1–2», «org.webjars» % «jquery» % »2.1.1», «org.webjars» % «bootstrap» % »3.2.0–2» ) Если вы скомпилируете проект, вы можете обнаружить новую папку web-modules в директории target/web. В ней как раз и содержаться добавленные в проект js и css файлы.

Обращаться к ним из view можно по старинке @routes.Assets.at («lib/requirejs/require.js»), но для этого нужно знать полный путь. Другой более кошерный способ использовать готовые контроллеры WebJars. Для этого добавим в conf/routes новый маршрут специально для WebJars

GET /lib/*file controllers.WebJarAssets.at (file) А для обращения к ним из view мы можем использовать еще метод от WebJars WebJarAssets.locate. Указанный метод сам ищет необходимый файл в каталоге с WebJars. В итоге получаем:

Что на html странице будет выглядеть как

Удобно не правда ли? Но это еще не все

RequireJS

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

WebJars содержит в себе механизм для более удобной интеграции с RequireJS. Если вы зайдете в каталог target/web/web-modules/main/webjars/lib/jquery, то обнаружите файл webjars-requirejs.js c содержимым

/*global requirejs */

// Ensure any request for this webjar brings in jQuery. requirejs.config ({ paths: { «jquery»: webjars.path («jquery», «jquery») }, shim: { «jquery»: { «exports»:»$» } } }); В каждом WebJar есть файл с конфигом для RequireJS. Чтобы получить общий конфиг создадим новый view с именем requireJsConfig

@Html (org.webjars.RequireJS.getSetupJavaScript (routes.WebJarAssets.at (»).url)) Добавим новый экшн в контроллер Application

import play.api.cache.Cached import views._ import play.api.Play.current

def requireJsConfig = Cached («require_js_config») { Action { Ok (html.requireJsConfig ()).as («application/javascript») } } Результат выполнения мы кэшируем, поскольку его содержимое будет меняться только при добавлении/удалении используемых в проекте WebJars. Также результат мы помечаем как application/javascript, чтобы явно указать в содержимое является javascript’ом

Добавляем новый маршрут

GET /files/config.js controllers.Application.requireJsConfig Забавы ради url прописываем как у статического js-файла

Проверяем что получилось, в браузере переходим по url http://localhost:9000/files/config.js

var webjars = { versions: {«requirejs-domready»:»2.0.1», «requirejs»:»2.1.14–3», «bootstrap»:»3.2.0–2», «jquery»:»2.1.1»}, path: function (webJarId, path) { console.error ('The webjars.path () method of getting a WebJar path has been deprecated. The RequireJS config in the ' + webJarId + ' WebJar may need to be updated. Please file an issue: http://github.com/webjars/' + webJarId + '/issues/new'); return ['/lib/' + webJarId + '/' + webjars.versions[webJarId] + '/' + path]; } };

var require = { callback: function () { // Deprecated WebJars RequireJS plugin loader define ('webjars', function () { return { load: function (name, req, onload, config) { if (name.indexOf ('.js') >= 0) { console.warn ('Detected a legacy file name (' + name + ') as the thing to load. Loading via file name is no longer supported so the .js will be dropped in an effort to resolve the module name instead.'); name = name.replace ('.js', ''); } console.error ('The webjars plugin loader (e.g. webjars!' + name + ') has been deprecated. The RequireJS config in the ' + name + ' WebJar may need to be updated. Please file an issue: http://github.com/webjars/webjars/issues/new'); req ([name], function () {; onload (); }); } } });

// All of the WebJar configs

requirejs.config ({«paths»:{«requirejs-domready»:[»/lib/requirejs-domready/2.0.1/domReady», «domReady»]}}) requirejs.config ({«paths»:{}}) requirejs.config ({«paths»:{«bootstrap»:[»/lib/bootstrap/3.2.0–2/js/bootstrap», «js/bootstrap»], «bootstrap-css»:[»/lib/bootstrap/3.2.0–2/css/bootstrap», «css/bootstrap»]}, «shim»:{«bootstrap»:[«jquery»]}}) requirejs.config ({«paths»:{«jquery»:[»/lib/jquery/2.1.1/jquery», «jquery»]}, «shim»:{«jquery»:{«exports»:»$»}}}) } } Данный скрипт настраивает RequireJS необходимым нам образом и должен предшествовать самому RequireJS

Финал

Создадим небольшой coffescript файл (простите, если кого-то этим огорчил, но от чистого javascript я подустал) в каталоге app/assets/js/main.coffee

require ['jquery','requirejs-domready!'],→ $('body').text 'Success' И в интересующей нас view, добавим

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

Итог

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

© Habrahabr.ru