Pro Yearly is on sale from $80 to $50! »

Rails: beyond the asset pipeline (RubyC)

Rails: beyond the asset pipeline (RubyC)

9b1a71682de14fc6fc2b944a9c4814a0?s=128

Alex Coles

May 31, 2015
Tweet

Transcript

  1. Rails: beyond the asset pipeline RubyC, Київ, Україна | 31

    May 2015
  2. Frontend has changed

  3. asana

  4. typecast

  5. blocs

  6. So how can Rails keep up?

  7. psst… ditch the asset pipeline

  8. Привіт RubyC! Привет RubyC!

  9. Привіт Київ! Привет Киев!

  10. About me @myabc github.com/myabc alexbcoles.com

  11. Де я живу Где я живу

  12. Де я працюю Где я работаю

  13. Те, що я працюю на То, что я работаю на

  14. 31 August 2011 Hello Rails 3.1

  15. gem wrappers

  16. $ gem list --remote jquery | wc -l 300

  17. Bower

  18. Three different ways to use Bower 1. gem Using an

    integration like bower-rails or bower gem gem install bower-rails source 'https://rubygems.org' gem 'bower-rails'
  19. Three different ways to use Bower 2. Load path config.assets.paths

    << File.join(Rails.root, 'bower_components') requires Rails 4 (Sprockets 2+)
  20. Three different ways to use Bower 3. rails-assets.org source 'https://rubygems.org'

    gem 'rails' source 'https://rails-assets.org' do gem 'rails-assets-bootstrap' gem 'rails-assets-angular' gem 'rails-assets-leaflet' end requires Bundler >= 1.8.4
  21. Torba torba-rb/Torba

  22. Bower only helps solve dependency management

  23. Things you might need Dependency management Pre and post-processing Code

    loading Code bundling
  24. Sprockets plugins alexspeller/non-stupid-digest-assets

  25. Sprockets plugins Post-processing JS/CSS ai/autoprefixer-rails uses PostCSS project autoprefixer TannerRogalsky/sprockets-es6

    uses Babel (formerly 6to5), requires Sprockets 3
  26. Problem with Sprockets No standard plugin configuration style Cannot control

    pre/post-processing order Asset dependencies
  27. Things you might need Dependency management Pre and post-processing Code

    loading Code bundling
  28. Webpack

  29. Webpack configuration + entry point // webpack.config.js module.exports = {

    context: __dirname + '/app', entry: 'rubyc-app.js', output: { filename: '[name].js', path: path.join(__dirname, '..', 'app', 'assets', 'javascripts', 'bundles'), publicPath: '/assets/bundles' } }
  30. Requiring JS single files and dependencies require('./another-file'); //= require ./another-file

    (Sprockets) var angular = require('angular'); var jQuery = require('jquery'); require('jquery-ui');
  31. Requiring JS a tree var requireTemplate = require.context('./app/controllers', true, /\.js$/);

    requireTemplate.keys().forEach(requireTemplate); //= require_tree ./app/controllers (Sprockets)
  32. Requiring assets require('jquery-ui/ui/jquery-ui'); // .js (default) require('jquery-ui/themes/base/jquery.ui.core.css'); require('jquery-ui/themes/base/jquery.ui.datepicker.css'); require('select2/select2'); //

    .js (default) require('select2/select2.css');
  33. Requiring assets quick start require('jquery-ui/ui/jquery-ui'); // .js (default) require('!style-loader!css-loader!jquery-ui/themes/base/jquery.ui.core.css'); require('!style-loader!css-loader!jquery-ui/themes/base/jquery.ui.datepicker.css');

  34. Requiring assets with a bit of config // webpack.config.js module.exports

    = { context: __dirname + '/app', entry: 'rubyc-app.js', module: { loaders: [ { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.png$/, loader: 'url-loader?limit=100000&mimetype=image/png' }, { test: /\.gif$/, loader: 'file-loader' }, { test: /\.jpg$/, loader: 'file-loader' } ]} } require('jquery-ui/ui/jquery-ui'); // .js (default) require('jquery-ui/themes/base/jquery.ui.core.css'); require('jquery-ui/themes/base/jquery.ui.datepicker.css');
  35. Requiring assets body { background: url(file:///Users/alexbcoles/git-repos/talk-rails-beyond-asset-pipeline//assets/bundles/backgroun } /* border-image: url(file:///Users/alexbcoles/git-repos/talk-rails-beyond-asset-pipeline/border-image.png);

    */ .box { border-image: url(file:///Users/alexbcoles/git-repos/talk-rails-beyond-asset-pipeline/data:image/png;base64,i }
  36. Loaders and plugins Webpack is built on the concept of

    loaders and plugins
  37. Loaders

  38. Loaders Loaders are transformations that are applied on files. They

    preprocess files. I. e. they can transform CoffeeScript to JavaScript.
  39. Chaining Loaders eslint ← coffee json ← yaml style ←

    postcss ← css ← sass ngtemplate-loader ← markdown
  40. None
  41. Requiring Rails-style translation files $ npm install --save-dev json-loader yaml-loader

    I18n.translations = I18n.translations || {}; I18n.translations.en = require('!json!yaml!config/locales/en_US.yml').en; I18n.translations.de = require('!json!yaml!config/locales/en_DE.yml').de;
  42. Transpiling (ES6 → ES5) $ npm install --save-dev babel-loader module:

    { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'} ] }
  43. Transpiling (ES6 → ES5) // app-defaults.js export default { favouriteConf:

    'Ruby C' }; // app.js import appDefaults from './app-defaults.js'; class ExampleApp { constructor() { console.log(appDefaults.favouriteConf); } } export default ExampleApp;
  44. Legacy code support $ npm install --save-dev exports-loader module: {

    loaders: [ { test: /[\/]angular\.js$/, loader: 'exports?angular' } ] }
  45. How to integrate with Rails rake webpack – or –

    rake assets:precompile
  46. Rails integration /// manifest-84b43dda218a2c29ce11f4f7b9ca4e5f.json { "assets": { "1downarrow.png": "1downarrow-d2055955ce2927de07f2e33abdbfdc1b.png", "1uparrow.png":

    "1uparrow-a4eef1942dd999e6a16e84c1c8122b8a.png", "2downarrow.png": "2downarrow-e8bc5b59fa922f68637dc22b4a467f5c.png" } }
  47. Rails integration # app/helpers/application_helper.rb def webpack_bundle_tag(bundle) src = if Rails.configuration.webpack[:use_manifest]

    manifest = Rails.configuration.webpack[:asset_manifest] filename = manifest[bundle] "#{compute_asset_host}/assets/#{filename}" else "#{compute_asset_host}/assets/#{bundle}-bundle" end javascript_include_tag(src) end http://clarkdave.net/2015/01/how-to-use-webpack-with-rails/
  48. Rails integration Running everything together foreman start # Procfile web:

    bundle exec rails server -e ${RAILS_ENV:="development"} assets: $(npm bin)/webpack --colors --watch --progress
  49. How does CSS fit into the picture?

  50. Core application CSS 1. Stick with the Rails asset pipeline

    for CSS 2. Using gulp rather than Webpack
  51. Gulp for Sass/CSS $ npm install -g gulp $ gulp

    sass gulp.task('sass', function() { return gulp.src('app/assets/css/default.css.sass') .pipe(sass({ loadPath: [ './bower_components/bourbon/app/assets/stylesheets' ] })) .pipe(autoprefixer({ cascade: false })) .on('error', function(err) { console.log(err.message); }) .pipe(gulp.dest('public/assets/css')); });
  52. One more thing…

  53. http://xkcd.com/303/

  54. Hot reloading

  55. Hot reloading colektivo/song-song-song gaearon/react-hot-loader

  56. Conclusion

  57. Alternatives (why not Ruby?)

  58. Ruby alternatives lotus/assets livingsocial/rake-pipeline (including wycats/rake-pipeline-web-filters)

  59. Спасибі Спасибо

  60. Questions?