<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>while (stupidity > reason)</title>
 <link href="http://kaeff.net//atom.xml" rel="self"/>
 <link href="http://kaeff.net/"/>
 <updated>2016-10-06T19:05:03+02:00</updated>
 <id>http://kaeff.net/</id>
 <author>
   <name>kaeff</name>
   <email>hi@kaeff.net</email>
 </author>

 
 <entry>
   <title>Increasing Map Zoom Level in Kibana</title>
   <link href="http://kaeff.net//posts/increasing-map-zoom-level-in-kibana.html"/>
   <updated>2016-10-06T00:00:00+02:00</updated>
   <id>http://kaeff.net//posts/increasing-map-zoom-level-in-kibana</id>
   <content type="html">
&lt;p&gt;On July 11, 2016, users of Kibana were not able to use map visualisations anymore since &lt;a href=&quot;http://devblog.mapquest.com/2016/06/15/modernization-of-mapquest-results-in-changes-to-open-tile-access/&quot;&gt;MapQuest had discontinued the support for their tile service&lt;/a&gt;.
This was fixed with the &lt;a href=&quot;https://www.elastic.co/blog/kibana-4-5-3-and-4-1-10&quot;&gt;release of Kibana versions 4.5.3 and 4.1.10&lt;/a&gt;. These versions circumvent the problem by using Elastic’s newly introduced, own tile service.&lt;/p&gt;

&lt;p&gt;Unfortunately, the &lt;a href=&quot;https://www.elastic.co/elastic-tile-service&quot;&gt;Elastic Tile Service&lt;/a&gt; &lt;strong&gt;restricts the maximum zoom level to 8&lt;/strong&gt;.
The company names scaling and bandwidth as the reasons for the limitation.
However, you can increase the zoom level to the maximum of 18 if you use another tile service, for example &lt;a href=&quot;https://wiki.openstreetmap.org/wiki/Tile_servers&quot;&gt;OpenStreetMap’s openstreetmap-carto&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Two newly introduced parameters in the &lt;code&gt;kibana.yml&lt;/code&gt; settings file allow you to use a custom tile server and maximum zoom level. If you have installed Kibana on macOS using brew, the location is &lt;code&gt;/usr/local/etc/kibana/kibana.yml&lt;/code&gt;. Add the following lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tilemap.options.maxZoom: 18
tilemap.url: http://a.tile.openstreetmap.org/{z}/{x}/{y}.png
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After restarting Kibana, you should be able to increase the zoom to street-level detailedness.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Upcoming project: Trainer at ThoughtWorks University</title>
   <link href="http://kaeff.net//posts/upcoming-project-trainer-at-thoughtworks-university.html"/>
   <updated>2016-05-17T00:00:00+02:00</updated>
   <id>http://kaeff.net//posts/upcoming-project-trainer-at-thoughtworks-university</id>
   <content type="html">
&lt;p&gt;My professional life as a software developer so far included various different technologies, companies, challenges as well as aspect of several different roles.
Yet, my next project will have quite a different twist: This June to October, I’ll have the honour to bring up a new generation of ThoughtWorkers as a trainer at &lt;a href=&quot;https://info.thoughtworks.com/graduates&quot;&gt;ThoughtWorks&lt;/a&gt; University in Pune, India.&lt;/p&gt;

&lt;p&gt;TWU, for short, is &lt;a href=&quot;https://info.thoughtworks.com/graduates&quot;&gt;ThoughtWork’s global graduate development program&lt;/a&gt;.
6 times per year, trainees and trainers from all of our regions come together for a 5-week long immersive learning experience.
In Pune, an immersive learning experience equips colleagues who are just diving into the world of IT with the practises, principles and values that will make them successful as a ThoughtWorker.&lt;/p&gt;

&lt;p&gt;Learning is in inseparable part of work in a fast-changing field like technology, and the fact that I’m always learning is one of the things I like most in my profession.
In addition to that, passing knowledge to peers became an increasing part of my job lately in different ways:
As a developer who also happens to be a consultant, making our practises available to others is an integral to daily work.
Finally, becoming a sponsor in our internal mentoring programme is a great combination of both, as both mentor and mentee get to reflect and grow within a healthy mentoring relationship.&lt;/p&gt;

&lt;p&gt;I’ve also had the honour of coaching two great teams of &lt;a href=&quot;http://railsgirlssummerofcode.org/&quot;&gt;Rails Girls Summer of Code&lt;/a&gt; in &lt;a href=&quot;http://rapidrailsgirls.weebly.com/&quot;&gt;2014&lt;/a&gt; and &lt;a href=&quot;https://teams.railsgirlssummerofcode.org/teams/52&quot;&gt;2015&lt;/a&gt;.
While RGSoC is highly catered towards each individual pair of learners, TWU will be more structured - which has both advantages and disadvantages.
Yet, both programmes share the principles of adult learning that is hands-on and self-directed.&lt;/p&gt;

&lt;p&gt;If you’re interested in life at ThoughtWorks university, I hope to keep you updated within the next months on this blog.
In the past, &lt;a href=&quot;http://www.markhneedham.com/blog/category/thoughtworks-university-2/&quot;&gt;Mark&lt;/a&gt;, &lt;a href=&quot;http://www.learninggeneralist.com/2010/08/thoughtworks-university-story-of-our.html&quot;&gt;Sumeet&lt;/a&gt; and &lt;a href=&quot;https://www.thoughtworks.com/insights/blog/continous-learning-thoughtworks&quot;&gt;Ramesh&lt;/a&gt; have written extensively about various aspects of training at TWU.
For a trainee perspective, refer to &lt;a href=&quot;https://www.thoughtworks.com/insights/blog/south-africa-india&quot;&gt;Tsatsis excellent experience report&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lastly, Chris shot these beautiful impressions while in Pune:&lt;/p&gt;

&lt;iframe width=&quot;780&quot; height=&quot;457&quot; src=&quot;https://www.youtube.com/embed/ycLVQRMXb00&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
</content>
 </entry>
 
 <entry>
   <title>Keeping Standups Short Despite A Large Team</title>
   <link href="http://kaeff.net//posts/keeping-standups-short-despite-a-large-team.html"/>
   <updated>2015-02-24T00:00:00+01:00</updated>
   <id>http://kaeff.net//posts/keeping-standups-short-despite-a-large-team</id>
   <content type="html">
&lt;p&gt;Everyone hates meetings. Everyone hates long meetings. The whole point about stand-ups is: They’re short.&lt;/p&gt;

&lt;p&gt;On my current project, we recently noticed that our dailies got longer and longer. Fair enough: We are a large team of about 20 people, so there is much to talk about. Nevertheless, we managed ourselves to get each other updated within around 12 minutes. This significantly lowered the need for splitting up the team (or not having stand-up at all).&lt;/p&gt;

&lt;p&gt;This post outlines some of the techniques which worked well for us.&lt;/p&gt;

&lt;h2 id=&quot;focus-on-the-wall&quot;&gt;Focus on the wall&lt;/h2&gt;

&lt;p&gt;I’m a fan of the three questions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;What have you done yesterday?&lt;/li&gt;
  &lt;li&gt;What are you going to do today?&lt;/li&gt;
  &lt;li&gt;What blocks you?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yet within a group of 20, doing the full round is not feasible anymore.&lt;/p&gt;

&lt;p&gt;Instead, we go through the wall. From Release to Analysis, we share what’s noteworthy for every story. While there is no fixed format, we tend to focus on updates and blockers.&lt;/p&gt;

&lt;p&gt;Walking through the wall story by story provides a red line and orders the news according to priority. Even without much context on story, everyone gets a sense of what each pair is up to. Individuals learn just enough to notice when to facilitate a catch-up later. Also, time is saved since pairs don’t speak double.&lt;/p&gt;

&lt;p&gt;All in all, this method helped us emphasises flow more: You notice quickly when cards get stuck due to the similar order of topics from one day to the next.&lt;/p&gt;

&lt;h2 id=&quot;move-cards-beforehand&quot;&gt;Move cards beforehand&lt;/h2&gt;

&lt;p&gt;Do you know these stand-ups where people start to shuffle all cards around hectically? It disturbs everyone and ruins the stand-up flow. If the only info you’ll get out of stand-up is “Yeah, that moved”, you might also just send around a picture of the wall.&lt;/p&gt;

&lt;p&gt;Make sure to move your cards before stand-up starts. Your team will be grateful.&lt;/p&gt;

&lt;h2 id=&quot;have-general-announcements-after-moving-through-the-wall&quot;&gt;Have general announcements after moving through the wall&lt;/h2&gt;

&lt;p&gt;Ideally, all tasks the team is working on should be reflected on the wall, alleviating the need for an unfocussed round of &lt;em&gt;“Oh, by the way…“&lt;/em&gt;’s. Yet, there are always some general announcements that don’t fit in here or there, yet the team needs to know about them.&lt;/p&gt;

&lt;p&gt;Have general announcements &lt;strong&gt;after&lt;/strong&gt; moving through the wall. When everything related to core work has already been said, people are less tempted to squeeze in less important facts or even delve into chatter.&lt;/p&gt;

&lt;p&gt;Some time back, we started stand-up with general announcements, before hearing the actual progress in terms of stories. This sucked the focus out of the stand-up super soon: Rather unimportant yet mention-worthy chatter stole our focus. Some Manger-y team members would even dump all their announcements in a big batch and then leave.&lt;/p&gt;

&lt;h2 id=&quot;time-each-other-out&quot;&gt;Time each other out&lt;/h2&gt;

&lt;p&gt;When in such a big stand-up, the need for timing each other out is very important. Don’t worry, getting the T-shaped hand sign from around the room happens to everyone. Getting this feedback is an effective way of learning to shape your communication and be meaningful in general, far beyond stand-ups.&lt;/p&gt;

&lt;h2 id=&quot;use-separate-channels-for-details&quot;&gt;Use separate channels for details&lt;/h2&gt;

&lt;p&gt;With an average speaking time of under 40 seconds per person, important details &lt;strong&gt;will&lt;/strong&gt; get lost. Therefore, several side channels started to emerge over time. These leave room for sharing updates with more room for background infos or questions.&lt;/p&gt;

&lt;p&gt;These are the specialised announcement channels we currently employ:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Tech Huddle&lt;/strong&gt;: After the board walk and announcements, the technical team gathers closely around the board. The team self-organizes the task distribution: Cards are pulled, avatars move and pairs rotate.&lt;/li&gt;
  &lt;li&gt;Analysis Huddle: Shortly before stand-up, Analysts and Product Owners gather to get an overview of the board. The discuss priorities for the day, blockers. The team benefits from a clear board and ready to play cards during stand-up.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Migration steam stand-up&lt;/strong&gt;: For a good balance between the isolations of a team split and the overload of a single team, we categorise our work in 2-3 work streams. Currently, one of these streams is occupied with a complex data migration of an old system. Since this work requires close collaboration and frequent reorganisation, the stream uses a separate stand-up for their stories in addition to the regular stand-up.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tech announcements via mailing list&lt;/strong&gt;: These topics tended to become lengthy and get discussed, so we agreed to send them out via mail. Now, everyone can read them asynchronously whenever it suits them. Urgent announcements or gentle reminders are still part of the Tech Huddle.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;no-silver-bullet&quot;&gt;No silver bullet&lt;/h2&gt;

&lt;p&gt;Naturally, our stand-up efficiency improvements also bears some risks to it. More silent people may get overrun during the fast-paced walk through the wall. Speaking in such a big round might be intimidating for some, compared to a smaller, more reasonably-sized team stand-up. These factors require attention; you might miss out important updates completely if people remain silent more than occasionally.&lt;/p&gt;

&lt;p&gt;Whenever there are less people due to leave, we like to diversify the stand-up format and experiment with it - for example by going back to the good old three questions.&lt;/p&gt;

&lt;p&gt;How do you keep stand-ups short in your team? Let me know in the comments!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>RailsRumble 2013: Building SeeMeSpeak</title>
   <link href="http://kaeff.net//posts/seemespeak-sign-language-dictionary-railsrumble-2013.html"/>
   <updated>2013-10-30T00:00:00+01:00</updated>
   <id>http://kaeff.net//posts/seemespeak-sign-language-dictionary-railsrumble-2013</id>
   <content type="html">
&lt;p&gt;&lt;em&gt;This post introduces our entry for this year’s RailsRumble.
Please &lt;a href=&quot;http://rumble.seemespeak.org&quot;&gt;have a look at SeeMeSpeak&lt;/a&gt; and &lt;a href=&quot;http://railsrumble.com/entries/39-see-me-speak&quot;&gt;vote for us at railsrumble.com&lt;/a&gt; if you like it.
Thanks!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Biggest props to team members Bodo (&lt;a href=&quot;https://twitter.com/bitboxer&quot;&gt;@bitboxer&lt;/a&gt;), Florian (&lt;a href=&quot;https://twitter.com/Argorak&quot;&gt;@Argorak&lt;/a&gt;) and Jan (&lt;a href=&quot;https://twitter.com/JanNilpferd&quot;&gt;@JanNilpferd&lt;/a&gt;) whom it was and honor and great joy to work with.
Be sure to follow &lt;a href=&quot;https://twitter.com/seemespeakdict&quot;&gt;@seemespeakdict&lt;/a&gt; on twitter to stay up to date with the future of this open platform&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;seemespeak-a-crowd-sourced-dictionary-for-sign-languages&quot;&gt;SeeMeSpeak, a crowd-sourced &lt;strong&gt;dictionary for sign languages&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/seemespeak/videos_index.png&quot; alt=&quot;List of videos on rumble.seemespeak.org&quot; /&gt;&lt;/p&gt;

&lt;p&gt;While many people take online dictionaries like &lt;a href=&quot;http://dict.leo.org&quot;&gt;Leo&lt;/a&gt; as granted and use them on a daily basis, there is no such “go-to” solution for sign language speakers.
The ones available are either not free (as in freedom) or not compelling to use.&lt;/p&gt;

&lt;p&gt;Luckily, we had a native speaker of the German Sign Language on our team.
Our our domain expert (if you will) introduced us to the challenges involved in such an undertaking:
There are different languages (e.g. the German Sign Language, American Sign Language).
Furthermore a multitude of different dialects and regional variations lead to subtle but noticeable pronunciation differences.&lt;/p&gt;

&lt;p&gt;Our goal was to build a dictionary platform that is fun to use, with minimal friction, and flexible enough to handle ontologies for several languages.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/seemespeak/videos_show.png&quot; alt=&quot;Showing a video on rumble.seemespeak.org&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;features--technology-stack&quot;&gt;Features &amp;amp; Technology Stack&lt;/h2&gt;

&lt;p&gt;Like a wiki, SeeMeSpeak &lt;em&gt;doesn’t require an account&lt;/em&gt; to add content (there’s a review flag in order to prevent abuse of of the matter).
Instead of a fixed ontology, we want to enable &lt;em&gt;flexible categorization and search&lt;/em&gt; based on tags and text.
Modern technology and the capabilities of modern browsers to &lt;em&gt;record and play videos&lt;/em&gt; natively were drivers on the tech side.
Obviously, &lt;em&gt;internationalization&lt;/em&gt; plays a bigger part in this domain.
We localized the app to German and show translations for German transcriptions as a proof-of-concept.&lt;/p&gt;

&lt;!--Tech Stack--&gt;
&lt;p&gt;Our &lt;strong&gt;tech stack&lt;/strong&gt; looks as follows. On the frontend: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;getUserMedia / Video API&lt;/strong&gt; to record from a user’s webcam, plugin-less.
Unfortunately, we had issues with Firefox not supporting &lt;code&gt;video/webm&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MediaStreamRecorder&lt;/strong&gt;. Its a standardized but unimplemented API, so we used &lt;a href=&quot;https://github.com/streamproc/MediaStreamRecorder&quot;&gt;a polyfill with the same name&lt;/a&gt; for recording videos from &lt;code&gt;getUserMedia&lt;/code&gt;.
The API/polyfill library is a small abstraction of the recording process, which is generally “output the webcam image in a &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; and capture a frame every other millisecond”.
So instead of piling up BinaryArrays manually, you have a simple &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;stop&lt;/code&gt; API available.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;XHR2&lt;/strong&gt; to send JavaScript &lt;code&gt;Blob&lt;/code&gt;s via multipart forms.
By thus, it made no difference to our backend whether the video was live recorded or sent using a regular &lt;code&gt;&amp;lt;input type=&quot;file&quot;&amp;gt;&lt;/code&gt;.
The MediaStreamRecorder polyfill turned out the easiest and most future-proof way of recording from user media.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Popcorn.js&lt;/strong&gt; for cross-browser video playback.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the backend: &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Rails 4&lt;/strong&gt; (thanks, Captian Obvious)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Elasticsearch&lt;/strong&gt; for searching and metadata storage.
Thanks to its flexibility, we didn’t need an additional database.
For speaking to elasticsearch, we used the brand new &lt;a href=&quot;https://github.com/elasticsearch/elasticsearch-ruby&quot;&gt;elasticsearch gem&lt;/a&gt; instead of the retired Tire.&lt;br /&gt;
ElasticSearch to store ALL THE things is a refreshingly straight-forward approach.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Virtus&lt;/strong&gt; and ActiveRecord::Validations as DSLs in our models.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Torquebox&lt;/strong&gt; as an app server and background queuing system.
I had my doubts before, but the stack’s tooling was absolutely turn-key.
Installation via RubyGems and deployment works like a charm.
Queuing background jobs for video conversions were as easy as declaring a method as &lt;code&gt;always_background&lt;/code&gt;.
We benefit from all cores of our machine out of the box.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Nginx&lt;/strong&gt; for serving video files using pseudo streaming.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;libav&lt;/strong&gt; to shell out to &lt;code&gt;avconv&lt;/code&gt; for converting incoming video streams to multiple formats&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Bing Translator&lt;/strong&gt; API for translating transcriptions.
Fun fact: Since Google shut down it’s translation API, people built &lt;a href=&quot;http://stackoverflow.com/questions/6151668/alternative-to-google-translate-api/8543979#8543979&quot;&gt;hacks involving spreadsheets&lt;/a&gt; to use their service anyway.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel very free to check out the &lt;a href=&quot;https://github.com/seemespeak/seemespeak&quot;&gt;open sourced code on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/seemespeak/videos_new.png&quot; alt=&quot;Recording a video on rumble.seemespeak.org&quot; /&gt;
&lt;em&gt;That’s what you end up with on a work day after 48h of hacking&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Some key insights we gained during this event:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Not requiring user sessions. We require your name for CC licensing/attribution reasons only.&lt;/li&gt;
  &lt;li&gt;Unfortunately, we couldn’t convince Firefox to reveal the webcam image as &lt;code&gt;image/webp&lt;/code&gt; instead of png’s.
As we had to prioritize against handling necessary conversion on the server, Firefox users will currently kindly be asked to leave.
Despite those issues must be expected when using bleeding-edge browser features, the support should be given judging from feature matrices.&lt;/li&gt;
  &lt;li&gt;We integrated &lt;strong&gt;~800 videos&lt;/strong&gt; that were already available under a CC license. 
This allowed us to present an engaging first experience instead of a looking like a generic video platform.
If you’re German, you may find searching for &lt;a href=&quot;http://rumble.seemespeak.org/videos?transcription=Angela+Merkel&quot;&gt;Angela Merkel&lt;/a&gt; or &lt;a href=&quot;http://rumble.seemespeak.org/videos?transcription=Telekom+Taliban&quot;&gt;Telekom Taliban&lt;/a&gt; funny.&lt;/li&gt;
&lt;/ul&gt;

&lt;!--## RailsRumble--&gt;
&lt;p&gt;As for advice concerning the format of a RailsRumble, I’ll leave you with the words of &lt;a href=&quot;http://blog.railsrumble.com/2013/10/15/how-to-build-an-app-in-48-hours/&quot;&gt;How To Build an App in 48 Hours&lt;/a&gt;.
I was honored to rumble with veterans which probably was the reason we finished successfully, with almost all features as planned and without hacking night time or sleep deprivation.
Absolute prioritization, straightforward coding and avoiding to smart-ass complex solutions really is key here.&lt;/p&gt;

&lt;p&gt;I also liked how the competition system is fully automated.
As opposed to other hackathron I participated and which encourage and reward faking, I really enjoyed this format for being focussed solely on shipping.&lt;/p&gt;

&lt;!--## Next steps--&gt;
&lt;!--Variation comparison / Voting--&gt;
&lt;!--Open Source--&gt;
&lt;!--Deaf community--&gt;

&lt;p&gt;&lt;em&gt;About the logo: This is the which will reveal you as a sign language
speaker. It’s a combination of spelling ILU, which expands to “I love
you”. I really like that aspect.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Almost all I know about sign language and the deaf community was picked
up alongside hacking this weekend. I’d be glad if you’d point out any
concerns in this text and apologize in advance for any errors.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Discussions started on &lt;a href=&quot;https://news.ycombinator.com/item?id=6586259&quot;&gt;Hacker News&lt;/a&gt; and &lt;a href=&quot;http://www.reddit.com/r/asl/comments/1owwcq/seemespeak_a_crowdsourced_dictionary_for_sign/&quot;&gt;Reddit&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Using Bower with Rails</title>
   <link href="http://kaeff.net//posts/rails-bower-quick-and-dirty.html"/>
   <updated>2013-04-29T00:00:00+02:00</updated>
   <id>http://kaeff.net//posts/rails-bower-quick-and-dirty</id>
   <content type="html">
&lt;p&gt;&lt;em&gt;This post describes a quick and dirty approach to better package management for assets. For more rationale behind this, why not look at my post called &lt;a href=&quot;http://kaeff.net/posts/sprockets-bower-better-component-packaging-for-rails-asset-pipeline.html&quot;&gt;Better Component Packaging for Rails’ Asset Pipeline&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you order &lt;em&gt;omakase&lt;/em&gt;, the chef’s suggestion is dropping everything in &lt;code&gt;vendor/assets&lt;/code&gt;. But manually snatching up several repos is a tedious and unsustainable approach, and Asset Gems (like &lt;code&gt;jquery-rails&lt;/code&gt;) who do that for you aren’t available for the vast amount of front-end frameworks.&lt;/p&gt;

&lt;p&gt;Twitter Bower is perfectly suited for this use case. Think &lt;em&gt;RubyGems for the front-end&lt;/em&gt;. It let’s you resolve packages from a various places like its &lt;a href=&quot;http://sindresorhus.com/bower-components/&quot;&gt;central registry&lt;/a&gt;, github, or just a URL. &lt;a href=&quot;https://github.com/twitter/bower/blob/master/README.md#usage&quot;&gt;See the Bower Readme&lt;/a&gt; for more.&lt;/p&gt;

&lt;p&gt;Be sure you have node.js installed and check out the &lt;a href=&quot;https://github.com/kaeff/ruby-bower&quot;&gt;ruby-bower&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;First, download the files &lt;a href=&quot;https://gist.github.com/kaeff/5336060&quot;&gt;from this gist&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ wget https://gist.github.com/kaeff/5336060/raw/599415e00f2f53a1822b9a4fbfdaefcdbf0f8e00/.bowerrc
$ wget -P config/initializers https://gist.github.com/kaeff/5336060/raw/fbd035576e13d8d72d60294080b058765aa86267/add_bower_directive.rb
$ wget -P lib/ https://gist.github.com/kaeff/5336060/raw/7c33a18bf44111929b9570896c987ab544c5d890/bower_directive.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In your Gemfile, add&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &#39;ruby-bower&#39;, group: :assets
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Be sure your application’s &lt;code&gt;lib/&lt;/code&gt; directory gets loaded&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# In config/application.rb
config.autoload_paths += Dir[&quot;#{config.root}/lib/**/&quot;]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now choose where you want to include your Bower dependencies:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// e.g. in app/assets/javascripts/application.js

//= require_bower_dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, you’re able to use Bower to manage dependencies. They will be included in your scripts.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bower install --save angular
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice that some components don’t declare they dependencies or main files correctly. For these exeptions, you need to require the according file manually. Why not submit a pull request to the library while at it?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// e.g. in app/assets/javascripts/application.js

//= require_bower_dependencies
//= require underscore/underscore
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is basically the approach that &lt;a href=&quot;https://github.com/spagalloco/bower&quot;&gt;spagalloco’s bower gem&lt;/a&gt; uses. Check out its sources, they’re really insightful.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Why Rails and Node.js Folks should care about Project Nashorn</title>
   <link href="http://kaeff.net//posts/why-ruby-and-nodejs-folks-should-care-about-project-nashorn.html"/>
   <updated>2012-12-28T00:00:00+01:00</updated>
   <id>http://kaeff.net//posts/why-ruby-and-nodejs-folks-should-care-about-project-nashorn</id>
   <content type="html">
&lt;p&gt;&lt;em&gt;This post is geared towards web developers coming from Ruby on Rails, Node.js or both.
As a web developer with former experiences with Java and JEE, currently engaged with Rails during days and Node at nights, I want to share my perspective on an interesting recent peace of news with you.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote class=&quot;twitter-tweet&quot; lang=&quot;de&quot;&gt;&lt;p&gt;When does &#39;gem install therubynashorn&#39; work already? &lt;a href=&quot;https://twitter.com/search/%23openjdk&quot;&gt;#openjdk&lt;/a&gt; &lt;a href=&quot;https://twitter.com/search/%23nashorn&quot;&gt;#nashorn&lt;/a&gt; &lt;a href=&quot;https://twitter.com/search/%23jruby&quot;&gt;#jruby&lt;/a&gt;&lt;/p&gt;&amp;mdash; kaeff (&lt;a href=&quot;https://twitter.com/kaeff&quot; alt=&quot;kaeff on Twitter&quot;&gt;@kaeff&lt;/a&gt;) &lt;a href=&quot;https://twitter.com/kaeff/status/283577327215054848&quot; data-datetime=&quot;2012-12-25T14:17:58+00:00&quot;&gt;Dezember 25, 2012&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;You may know &lt;a href=&quot;https://github.com/cowboyd/therubyracer&quot;&gt;therubyracer&lt;/a&gt; gem for executing JavaScript sources in Ruby.
As I was fooling around with &lt;a href=&quot;https://github.com/sstephenson/execjs&quot;&gt;ExecJS&lt;/a&gt; lately.
Every person who has written CoffeeScript before, e.g. &lt;a href=&quot;https://github.com/rails/coffee-rails&quot;&gt;within Rails&lt;/a&gt;, &lt;a href=&quot;https://github.com/josh/ruby-coffee-script/commit/4a4bb56dca40b59bd61705ac47d31b072bec1458#L1R57&quot;&gt;has already used&lt;/a&gt; this overwhelmingly useful piece of software.
The recent news of a new JavaScript engine called &lt;strong&gt;Nashorn&lt;/strong&gt; entering the realm of FOSS &lt;a href=&quot;http://news.ycombinator.com/item?id=4954657&quot;&gt;did&lt;/a&gt; &lt;a href=&quot;http://news.ycombinator.com/item?id=4857638&quot;&gt;not&lt;/a&gt; &lt;a href=&quot;http://news.ycombinator.com/item?id=4834796&quot;&gt;create&lt;/a&gt; &lt;a href=&quot;http://news.ycombinator.com/item?id=4835367&quot;&gt;buzz&lt;/a&gt; on &lt;a href=&quot;http://news.ycombinator.com/&quot;&gt;everybody’s dearest news site&lt;/a&gt;.
That’s really a pity, and as you may have guessed, we’ll see why in this post.&lt;/p&gt;

&lt;h2 id=&quot;horned-homology&quot;&gt;Horned Homology&lt;/h2&gt;

&lt;p&gt;Project Nashorn is a greenfield implementation of &lt;a href=&quot;http://www.ecma-international.org/publications/standards/Ecma-262.htm&quot;&gt;ECMAScript-262-5&lt;/a&gt;, &lt;a href=&quot;https://www.infoworld.com/d/application-development/oracle-prepping-its-nashorn-javascript-engine-175159&quot;&gt;started in 2011&lt;/a&gt; by Oracle.
It replaces Rhino in OpenJDK 8, and is thus scheduled to ship publicly in 2013.
The main rationale behind Nashorn is benefiting from &lt;a href=&quot;http://jcp.org/en/jsr/detail?id=292&quot;&gt;JSR-292: Dynamic Languages on the JVM&lt;/a&gt; aka &lt;strong&gt;InvokeDynamic&lt;/strong&gt;.
Nashorn has some lifetime already: It used to be closed source but was recently released into the wild (heh).
The &lt;a href=&quot;http://hg.openjdk.java.net/nashorn/jdk8/nashorn&quot;&gt;source&lt;/a&gt; has been &lt;a href=&quot;https://www.infoworld.com/d/application-development/oracle-prepping-its-nashorn-javascript-engine-175159&quot;&gt;donated&lt;/a&gt; to the OpenJDK.&lt;/p&gt;

&lt;p&gt;Several reasons speak for retiring Rhino, the main one being a huge effort of using invokedynamic properly.
Rhino is old and slow: Its development started in 1997 (11 years ago!) at Netscape, even before the age of the now-standard HotSpot JIT compiler.
Thus, it relies on interpretation - unlike V8, whose speed benefits mainly rely on &lt;a href=&quot;https://developers.google.com/v8/design#mach_code&quot;&gt;just-in-time compilation of JS to machine code&lt;/a&gt;, which it does pretty memory-hungry.
Nashorn, however, is said to be quick already - Node with its V8 is still the performance champion, but Nashorn races to challenge the throne.&lt;/p&gt;

&lt;p&gt;These circumstances cry for a fresh overhaul - good to hear that Nashorn aims to be fully backwards compatible.&lt;/p&gt;

&lt;h2 id=&quot;nodejar&quot;&gt;Node.jar&lt;/h2&gt;

&lt;p&gt;Here comes the hot part: With Nashorn also comes Node.jar, a Nashorn-based implementation of Node’s evented API.
Currently based on Node v0.8.2, Node.jar is tested against the Node test suite for full compliance.&lt;/p&gt;

&lt;p&gt;Node.jar a mapping Node’s API to Java-native pendants, nothing more and nothing less.
This is quite feasible, as displayed by e.g. the often-cited file system example:
Java’s nio packages, which weren’t too common in plain old Java development, have been providing async file system access for some time now.
With &lt;a href=&quot;http://jcp.org/en/jsr/detail?id=203&quot;&gt;JSR-203&lt;/a&gt;, they have received an overhaul in Java 7, namely NIO.2.&lt;/p&gt;

&lt;p&gt;Unlike Nashorn, Node.jar has been hardly covered and seems to be in its infancies.
I’d assume that a npm pendant is crucial for Node.jar’s success, but there are no news on that yet.
But the promises are well enough for us to keep a close eye on it.&lt;/p&gt;

&lt;h2 id=&quot;runtime-redundancy-for-the-good&quot;&gt;Runtime redundancy for the good&lt;/h2&gt;

&lt;p&gt;But why another Node, you may ask?&lt;/p&gt;

&lt;p&gt;In my opinion, competition fosters and drives innovation.
See the close example of in-browser JavaScript runtimes: With Google entering the stage, the war on challenging 
A second implementation of Node will further drive its standardization and adoption&lt;/p&gt;

&lt;p&gt;The biggest benefits stem from running on the JVM.
This enables the deployment on already available Java-based infrastructure.
Especially on Windows, the pains that Node faces with its platform implementation, can be laid off to the JVM.
Using Java application servers, especially JBoss, for deploying Node apps (or Ruby apps with embedded JS!) sounds promising.
Their purpose  is to provide common services to user apps which are ready to be reused.
While Ruby did go the extra loops of reinventing database access, messaging, caching, replication, and Node has this obstacle still in front of it.
For Ruby, the Torquebox project demonstrated how often sneered at giants like JBoss can be used for good, even for modern, dynamic web apps.&lt;/p&gt;

&lt;p&gt;Finally, there is the “door opener” aspect.
Grassroot-like enterprise adoption by sneaking into the existing Java-based infrastructures was and is a main rationale behind JRuby. 
Also, the JVM currently moves towards embedded, as efforts of an modular and small core JRE show.
Having conquered the server already, embedded becomes the next area that JS developers can settle into.
For example, how would the Nodecopter people like a native Node.js on a Raspberry Pi?&lt;/p&gt;

&lt;h2 id=&quot;java--javascript--javajavascript-&quot;&gt;Java + JavaScript = JavaJavaScript ?&lt;/h2&gt;

&lt;p&gt;(Fun fact: Nashorn’s command line runner &lt;a href=&quot;http://hg.openjdk.java.net/nashorn/jdk8/nashorn/file/da1e581c933b/bin/jjs&quot;&gt;is in fact&lt;/a&gt; named &lt;code&gt;jjs&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Okay, but what’s in for Ruby developers? There’s ExecJS to integrate my runtime from Ruby, be it Node, V8, Rhino or Nashorn.&lt;/p&gt;

&lt;p&gt;With Node.jar and JRuby, there are implementations for both JavaScript and Ruby running on the JVM.
In an ideal state, application parts written in JavaScript could be called from parts written in Ruby without process boundaries, since both run on the same JVM instance.
This same-process interop is basically beneficial to all scenarios that involve ExecJS.
Consequently, the need for wrappers and shelling out disappears, in theory providing a speed up.&lt;/p&gt;

&lt;p&gt;Another aspect of Ruby and JavaScript playing nicely together on the JVM playground: Up to now, certain use cases require both runtimes, Ruby and JS.
Distribution barriers for applications that apply to this scenario are significantly lowered if the JVM is the only runtime and environment dependency. 
Even better that it has a high penetration among server environments already.&lt;/p&gt;

&lt;h2 id=&quot;what-could-possibly-go-wrong&quot;&gt;What could possibly go wrong?&lt;/h2&gt;

&lt;p&gt;As always, there are caveats.
Since Node’s strengths lie in the asynchronous, I see the main area of conflict in the re-use of common but synchronous Java APIs - e.g. JPA, JEE’s prominent database abstraction.&lt;/p&gt;

&lt;p&gt;If you are as fascinated about this topic as I am, be warned: This is explorative territory.
Keep an eye on the &lt;a href=&quot;http://openjdk.java.net/projects/jdk8/&quot;&gt;OpenJDK 8 project page&lt;/a&gt;.
Save the date for the developer preview on end of February and mark your calendars for Q3/2013, when it is due for General Availability.
And despite Nashorn being available rather soon, it should take some time for Node.jar to reach production readiness.&lt;/p&gt;

&lt;h2 id=&quot;moar&quot;&gt;Moar!&lt;/h2&gt;

&lt;p&gt;If you want to give Nashorn a spin, grab a JDK8 and check out the source.
The &lt;a href=&quot;http://hg.openjdk.java.net/nashorn/jdk8/nashorn/raw-diff/da1e581c933b/README&quot;&gt;README&lt;/a&gt; points to everything you need to get going.
Also check out the blog post &lt;a href=&quot;https://blogs.oracle.com/nashorn/entry/open_for_business&quot;&gt;‘Open for business’&lt;/a&gt;.
I went with a &lt;a href=&quot;http://jdk8.java.net/download.html&quot;&gt;precompiled JDK8 build&lt;/a&gt; and just the Nashorn source (requires Mercurial), since that was too easy.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;hg clone http://hg.openjdk.java.net/nashorn/jdk8/nashorn nashorn
cd nashorn
(cd make ; JAVA_HOME=/path/to/jdk8 ant)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Spin up the Nashorn console from the Nashorn directory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;JAVA_HOME=/path/to/jdk8 sh bin/jjs
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Happy hacking!&lt;/p&gt;

&lt;p&gt;Some additional Linkspam:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://blogs.oracle.com/javaspotlight/entry/java_spotlight_episode_92_jim&quot;&gt;Java Spotlight Episode 92: Jim Laskey on Project Nashorn&lt;/a&gt;. A recent episode of the Java Spotlight potcast has a feature interview on Nashorn and the open sourcing that was the move into OpenJDK.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://robilad.livejournal.com/104861.html&quot;&gt;Project Nashorn Slides &amp;amp; Talks&lt;/a&gt;. Dalibor Topic has a a collection of slides and talks on Nashorn internals. Care if you want to dig deeper.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://insin-notes.readthedocs.org/en/latest/JavaOne2012/nashorn_node_jpa_persistence_bof.html&quot;&gt;Nashorn, Node.jar and Java Persistence BOF&lt;/a&gt; (Session minutes)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blogs.oracle.com/nashorn/&quot;&gt;The Nashorn blog on Oracle Blogs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Better Component Packaging for Rails' Asset Pipeline</title>
   <link href="http://kaeff.net//posts/sprockets-bower-better-component-packaging-for-rails-asset-pipeline.html"/>
   <updated>2012-12-24T00:00:00+01:00</updated>
   <id>http://kaeff.net//posts/sprockets-bower-better-component-packaging-for-rails-asset-pipeline</id>
   <content type="html">
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; If you came for a practical tutorial, check out this piece on &lt;a href=&quot;&quot;&gt;how to use Bower with Rails&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When writing single-page apps with Rails and the framework of your choice, may it be &lt;a href=&quot;http://emberjs.com/&quot;&gt;Ember&lt;/a&gt;, &lt;a href=&quot;http://angularjs.org/&quot;&gt;Angular&lt;/a&gt; or &lt;a href=&quot;http://backbonejs.org/&quot;&gt;Backbone&lt;/a&gt;, there’s one huge pain:
Maintaining a large front-end codebase while delivering with respect to the request count and size.&lt;/p&gt;

&lt;p&gt;As with any important programming aspect in JavaScript (like DOM access or building SPAs), packet managing perfectly adheres to “XKCD’s Law of Standards”:&lt;/p&gt;

&lt;div class=&quot;pagination-centered&quot;&gt;
  &lt;a href=&quot;http://xkcd.com/927/&quot;&gt;&lt;img src=&quot;/assets/images/xkcd-927-standards.png&quot; alt=&quot;How standards proliferate&quot; width=&quot;500&quot; height=&quot;283&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;Sprockets recently and silently introduced a basic integration of &lt;a href=&quot;https://github.com/twitter/bower&quot;&gt;Bower&lt;/a&gt;, a new packet manager by Twitter that ranks among the &lt;a href=&quot;https://github.com/blog/1359-the-octoverse-in-2012&quot;&gt;Top 10 starred projects on GitHub in 2012&lt;/a&gt;.
The integration is a huge opportunity towards better maintainability, component orientation and, by thus, more efficient asset organization for single-page Rails apps.
We will see why in this article.&lt;/p&gt;

&lt;h2 id=&quot;asset-gems-for-external-dependencies&quot;&gt;Asset Gems for external dependencies&lt;/h2&gt;

&lt;p&gt;Without other tools than the plain asset pipeline, managing a set of external dependencies means downloading some archive files from a homepage and throwing the respective files in &lt;code&gt;vendor/assets&lt;/code&gt;.
This folder soon becomes an unmanageable pile of files.
Have you tried updating or removing some dependencies?
This approach also makes your app subject to what older folks know by the term &lt;em&gt;DLL hell&lt;/em&gt;:
A single source for external libraries that isn’t version-agnostic neglects the complexity of resolving dependencies and building a dependency graph.&lt;/p&gt;

&lt;p&gt;Asset gems are the first logical step for a Rails developer to think of for distributing front-end libraries in a feasible manner.
These are gems like &lt;a href=&quot;https://github.com/rails/jquery-rails&quot;&gt;jquery-rails&lt;/a&gt;, which expose the library’s assets according to the asset pipeline’s path conventions and hook into your Rails app (Further described in the &lt;a href=&quot;http://guides.rubyonrails.org/asset_pipeline.html#adding-assets-to-your-gems&quot;&gt;Asset Pipeline Guide&lt;/a&gt;).
This is approach is neat because we can centrally store all dependencies in the Gemfile und re-use bundler.
It is also more flexible in Rails-specific cases, such as in the case of jquery-rails.&lt;/p&gt;

&lt;p&gt;However all of the library’s assets still need to be &lt;code&gt;require&lt;/code&gt;d from within the application - a duplication, since a packet should know on its own which files it exposes to the parent app.
Also, since asset gems are an Rails Engine, they pull in major dependencies and can’t be used with Sprockets standalone.
Then also, apart from the most popular ones, there aren’t many libraries available as asset gems and still require repackaging.
If only there was a way to include versioned assets from both a central registry or individual Git repositories, in a way that is not specific to Rails or Sprockets, but still compatible to their conventions?&lt;/p&gt;

&lt;h2 id=&quot;introducing-bower&quot;&gt;Introducing Bower&lt;/h2&gt;

&lt;p&gt;Enter &lt;a href=&quot;https://github.com/twitter/bower&quot;&gt;Bower&lt;/a&gt; to the rescue.
At first, it looks like yet another packet management solution for scripts, images and stylesheets.
What differentiates Bower is it’s low-level approach: &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Bower is a generic tool which will resolve dependencies and lock packages down to a version. It runs over Git, and is package-agnostic. A package may contain JavaScript, CSS, images, etc., and doesn’t rely on any particular transport (AMD, CommonJS, etc.).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It provides a &lt;a href=&quot;http://sindresorhus.com/bower-components/&quot;&gt;central repository&lt;/a&gt; with a growing number of libraries available for use.
However, you are free to include components directly from Git, GitHub, a web url, the file system or even your &lt;a href=&quot;https://github.com/twitter/bower-server&quot;&gt;own component repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Components are declared using the &lt;code&gt;component.json&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;myProject&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;main&quot;: [&quot;./path/to/app.css&quot;, &quot;./path/to/app.js&quot;, &quot;./path/to/sprite.img&quot;],
  &quot;dependencies&quot;: {
    &quot;jquery&quot;: &quot;~1.7.2&quot;
    &quot;ember&quot;: &quot;latest&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The format of this manifest is pretty straight-forward.
Give it a try and fetch bower using Node’s packet manager, &lt;a href=&quot;https://npmjs.org/&quot;&gt;npm&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;npm install --global bower
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For diving further into bower, follow e.g. &lt;a href=&quot;http://net.tutsplus.com/tutorials/tools-and-tips/meet-bower-a-package-manager-for-the-web/&quot;&gt;this tutorial on NetTutsPlus&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;using-bower-in-rails&quot;&gt;Using Bower in Rails&lt;/h2&gt;

&lt;p&gt;Sprockets recently received &lt;a href=&quot;https://github.com/sstephenson/sprockets/pull/358&quot;&gt;a pull request&lt;/a&gt; that layed the groundwork for integrating Bower, from version 2.6.0 onwards.
Use &lt;code&gt;bower&lt;/code&gt; on the command line and the &lt;code&gt;component.json&lt;/code&gt; manifest to manage your dependencies.
Within your &lt;code&gt;application.js&lt;/code&gt; (or &lt;code&gt;vendor.js&lt;/code&gt; or wherever you like), you can &lt;code&gt;require&lt;/code&gt; dependant components by their name.&lt;/p&gt;

&lt;p&gt;Some tweaks need to be done to get this method to work.
We’ll use the beta of Rails 4 for this example since we need a newer version of Sprockets than Rails 3 currently allows us to.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Gemfile

gem &#39;rails&#39;, :git =&amp;gt; &#39;git://github.com/rails/rails.git&#39;
gem &#39;activerecord-deprecated_finders&#39;, github: &#39;rails/activerecord-deprecated_finders&#39;
gem &#39;sprockets-rails&#39;, github: &#39;rails/sprockets-rails&#39;, group: :assets
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With the upcoming Rails 4, &lt;a href=&quot;http://yetimedia.tumblr.com/post/33320732456/moving-forward-with-the-rails-asset-pipeline&quot;&gt;the Sprocket integration is extracted&lt;/a&gt; into the &lt;a href=&quot;https://github.com/rails/sprockets-rails&quot;&gt;sprocket-rails&lt;/a&gt; gem, so the necessary patch is already available in edge Rails.
Unfortunately, using the newer version of Sprockets in Rails 3 is a bit tricky.&lt;/p&gt;

&lt;p&gt;Then, we need to tell Bower where to find the component manifest and to put component files.
In order to run &lt;code&gt;bower&lt;/code&gt; from the app root, like &lt;code&gt;rake&lt;/code&gt; or &lt;code&gt;rails&lt;/code&gt;, we need to put a &lt;code&gt;.bowerrc&lt;/code&gt; to adjust bower to Rails’ path conventions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  &quot;directory&quot; : &quot;vendor/assets/components&quot;,
  &quot;json&quot;      : &quot;vendor/assets/component.json&quot;
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I suggest rooting components under &lt;code&gt;vendor&lt;/code&gt;, but you could also use &lt;code&gt;app&lt;/code&gt; or &lt;code&gt;lib&lt;/code&gt; accordingly.&lt;/p&gt;

&lt;p&gt;Next, we need to tell Sprockets to include the component folder by passing the name to the environment configuration. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;environment = Sprockets::Environment.new
environment.append_path &#39;components&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Rails, &lt;code&gt;config.assets&lt;/code&gt; aliases to the sprocket environment:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# config/environment.rb

config.assets.append_path &#39;components&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, you still need to require the your dependencies. For JavaScripts, that’s &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# e.g. app/assets/javascripts/application.js

//= require ember
//= require jquery
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Clone this &lt;a href=&quot;https://github.com/kaeff/bower-rails-sample&quot;&gt;small example application&lt;/a&gt; from GitHub to try it out live.
&lt;a href=&quot;https://github.com/kaeff/bower-rails-sample/commit/6c6bbc9f698be0e8834c2aa32152c6842d08d4f3&quot;&gt;This changeset&lt;/a&gt; applies the aforementioned alterations.&lt;/p&gt;

&lt;h2 id=&quot;outlook&quot;&gt;Outlook&lt;/h2&gt;

&lt;p&gt;This small example demonstrates the potential behind a proper management for internal and external asset components.&lt;/p&gt;

&lt;p&gt;However, a solid integration is yet to be developed, e.g. as a gem that handles the integration steps described above.
It should features a proper communication layer on top of Bower’s API, eliminating the need of having Node installed and running bower separately on the command line.
The integration part should eliminate the need to redundantly require all dependencies, e.g. by providing an additional directive (think &lt;code&gt;//= require dependencies&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Lastly, we should honor the great pioneering work of &lt;a href=&quot;https://github.com/josh&quot;&gt;Joshua Peek&lt;/a&gt; on Sprockets and laying the cornerstone for the Bower integration, as well as the team behind Bower.&lt;/p&gt;

&lt;h2 id=&quot;packages-and-modules&quot;&gt;Packages and modules&lt;/h2&gt;

&lt;p&gt;The ultimate goal should be a solution that goes even further by being agnostic to modules.&lt;/p&gt;

&lt;p&gt;Single-Page Apps are by their nature bundled in one or a few packages.
Bower components are a neat way to define these packages and their dependencies.
However, we still need to &lt;code&gt;require&lt;/code&gt; dependant components.&lt;/p&gt;

&lt;p&gt;For a more intelligent solution, &lt;code&gt;require&lt;/code&gt; should go away - or, put less baltant, decend into the background.
Sprockets should be able to determine the relevant source files:
By enforcing a one-module-per-file and module declaration convention, it should be able to graph module dependencies and resolve the inclusion order and include only necessary modules.
This has the large number of benefits: Only necessary code gets shipped over the wire, reducing request size and parsing time, and better isolation for focussed and faster tests to name a few.&lt;/p&gt;

&lt;p&gt;I’m planning to expand on this issue in a future post.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Guess I have a new blog</title>
   <link href="http://kaeff.net//posts/new-blog.html"/>
   <updated>2012-12-18T00:00:00+01:00</updated>
   <id>http://kaeff.net//posts/new-blog</id>
   <content type="html">
&lt;p&gt;Since I want to get going on blogging again, I set myself up with a
shiny new site. It’s as straight-forward as possible, since it’s just a means to get content on the internet. No fancy blogging engine, just static sites generated by &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;jekyll&lt;/a&gt;, a fancy gem by &lt;a href=&quot;http://tom.preston-werner.com/&quot;&gt;Tom Preston-Werner&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And oh, it’s in English. The former one was in German, but that didn’t
really made sense for me.&lt;/p&gt;

&lt;p&gt;Since I’m writing my master thesis on single-page web applications, I
aim to pre-publish some thoughts on single aspects of it here. We’ll see :D.&lt;/p&gt;

&lt;p&gt;Meanwhile, why not &lt;a href=&quot;https://twitter.com/kaeff&quot;&gt;follow me on Twitter&lt;/a&gt;?&lt;/p&gt;
</content>
 </entry>
 
 
</feed>
