Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Taking Rails beyond the asset pipeline (Worksho...
Search
Alex Coles
December 06, 2016
Technology
97
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Taking Rails beyond the asset pipeline (Workshop at RubyDay Italia)
Alex Coles
December 06, 2016
More Decks by Alex Coles
See All by Alex Coles
How a language reflects its people (Brighton Ruby)
myabc
0
130
How a language reflects its people
myabc
0
110
Rails: beyond the asset pipeline (RubyC)
myabc
0
160
Frontend Choices (Tropical Ruby)
myabc
1
820
Frontend Choices (RubyConf Portugal)
myabc
1
490
Frontend Choices
myabc
0
74
Frontend Choices
myabc
0
320
Putting the Hype back in Hypermedia
myabc
1
250
DataMapper
myabc
2
250
Other Decks in Technology
See All in Technology
JAWSUG TOHOKU 青森支部 「LoGoチャット」のAWS移行で 乗り越えたこと
taketakekaho
0
350
Kiro Crewで「みのるん式」仕事術やってみた
minorun365
PRO
3
890
Conditional PED-ANOVA: Hyperparameter Importance in Hierarchical & Dynamic Search Spaces
pfn
PRO
0
140
Active Record Connection Adaptersにおける長年の課題に再び取り組む
yahonda
0
300
DGX Spark でどこまでハッキングができるのか?
kash1064
3
1.4k
[JAWS-UG彩の国埼玉#12]そろそろ準備する?re:Invent2026をやさしく解説 / reinvent2026-sainokuni
sh_fk2
1
360
実践!Cloud Run ハンズオン!! / Cloud Run handson
y0hgi
2
300
Benchmarking Disaggregated Serving on vLLM + Dynamo with a Real Coding-Agent Workload
nttcom
1
200
NDIでApple Vision Proにリアルタイム映像送信
jyouryuusui
0
130
日本語に強いオープンな大規模言語モデル「LLM-jp」
odashi
5
1.2k
『SAR衛星データ解析入門』のご紹介とその応用
syuchimu
0
130
QA4AI 2026-Oct 生成AI時代の品質保証
tokuty
1
900
Featured
See All Featured
Practical Orchestrator
shlominoach
192
12k
A Tale of Four Properties
chriscoyier
163
24k
30 Presentation Tips
portentint
PRO
1
430
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
640
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Scaling GitHub
holman
464
140k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.3k
Skip the Path - Find Your Career Trail
mkilby
1
260
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
330
Transcript
Taking Rails beyond the asset pipeline a workshop RubyDay Italia,
Firenze | Novembre 2016
Benvenuto
prima di iniziare
Pre-requisites recent Ruby (2.2+) recent Node (6.9.1+) an existing Rails
app (4.2/5.0) – or example app
Node on macOS brew update brew install yarn
Node on Windows & Linux https://yarnpkg.com/en/docs/install
Frontend has changed
asana
typecast
blocs
So how can Rails keep up?
psst… ditch the asset pipeline
buon pomeriggio RubyDay Italia!
About me @myabc github.com/myabc alexbcoles.com
where I work
what I work on
31 August 2011 Ciao Rails 3.1!
gem wrappers
$ gem list --remote jquery | wc -l 349
Bower
1. gem Using an integration like or gem bower-rails bower
gem install bower-rails source 'https://rubygems.org' gem 'bower-rails'
2. Load path config.assets.paths << File.join(Rails.root, 'bower_components')
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
Bower only solves dependency management
Things you might need Dependency management Pre and post-processing Code
loading Code bundling Tree shaking
Sprockets plugins alexspeller/non-stupid-digest-assets
Sprockets plugins Post-processing JS/CSS uses PostCSS project autopre xer uses
(formerly 6to5), requires Sprockets 3 ai/autopre xer-rails TannerRogalsky/sprockets-es6 Babel
Problem with Sprockets No standard plugin con guration style Cannot
control pre/post-processing order Asset dependencies
Things you might need Dependency management Pre and post-processing Code
loading Code bundling
Webpack
Webpack configuration + entry point // webpack.config.js module.exports = {
context: __dirname + '/app', entry: 'rubydayit-app.js', output: { filename: '[name].js', path: path.join(__dirname, '..', 'app', 'assets', 'javascripts', 'bundles'), publicPath: '/assets/bundles' } }
Requiring JS single files and dependencies require('./another-file'); //= require ./another-file
(Sprockets) var angular = require('angular'); var jQuery = require('jquery'); require('jquery-ui');
Requiring JS a tree var requireTemplate = require.context('./app/controllers', true, /\.js$/);
requireTemplate.keys().forEach(requireTemplate); //= require_tree ./app/controllers (Sprockets)
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');
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');
Requiring assets with a bit of config // webpack.config.js module.exports
= { context: __dirname + '/app', entry: 'rubydayit-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');
Requiring assets body { background: url(/assets/bundles/background-texture.jpg) } /* border-image: url(border-image.png);
*/ .box { border-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAA…'); }
Loaders and plugins Webpack is built on the concept of
loaders and plugins
Loaders
Loaders Loaders are transformations that are applied on les. They
preprocess les. I. e. they can transform Co eeScript to JavaScript.
Chaining Loaders eslint ← co ee json ← yaml style
← postcss ← css ← sass ngtemplate-loader ← markdown
Requiring Rails- style translation files $ yarn add --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;
Transpiling (ES6 → ES5) $ yarn add --dev babel-loader module:
{ loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'} ] }
Transpiling (ES6 → ES5) // app-defaults.js export default { favouriteConf:
'RubyDay Italia' }; // app.js import appDefaults from './app-defaults.js'; class ExampleApp { constructor() { console.log(appDefaults.favouriteConf); } } export default ExampleApp;
Legacy code support $ yarn add --dev exports-loader module: {
loaders: [ { test: /[\/]angular\.js$/, loader: 'exports?angular' } ] }
One more thing…
http://xkcd.com/303/
Hot reloading
Hot reloading colektivo/song-song-song gaearon/react-hot-loader
Instructions Building a vanilla Rails 5 application
Generate a new Rails app rails new TimeTracker git init
and git commit after each step.
Generate Rails scaffolding
Project ./bin/rails generate scaffold Project name:string:required colour:string TimeEntry ./bin/rails generate
scaffold TimeEntry project:references begin_at:datetime end_at:datetime note ./bin/rake db:migrate
Add materialize-sass and spruce up the application
Example application https://github.com/myabc/webpack-rails-rubydayit
Transforming the application with Webpack 2.0
Webpack 2 yarn add --dev
[email protected]
In webpack.config.js const webpack
= require('webpack'); const path = require('path'); module.exports = { entry: './app/assets/javascripts/application.js', output: { filename: 'application.js', path: path.join(__dirname, 'public', 'javascripts') } }
Babel yarn add --dev babel-loader babel-core yarn add --dev babel-preset-es2015
module.exports = { // ... module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: ['es2015'] } } ] } }
Sass/CSS Support yarn add --dev sass-loader css-loader node-sass yarn add
--dev
[email protected]
const ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { // ... module: { loaders: [ // ... { test: /\.scss$/, loader: ExtractTextPlugin.extract({loader: "css-loader!sass-loader"}) } ] }, plugins: [ new ExtractTextPlugin("../stylesheets/application.css") ] }
jQuery yarn add --dev jquery yarn add --dev expose-loader module.exports
= { // ... module: { loaders: [ { test: require.resolve("jquery"), loader: "expose-loader?$!expose-loader?jQuery" } ] } }
Materialize Framework yarn add --dev materialize-css
Rails libraries (asset pipeline analogues) yarn add --dev jquery-ujs yarn
add --dev turbolinks
Adapt application.js //= require jquery import jQuery from 'jquery'; //=
require jquery_ujs import 'jquery-ujs'; //= require turbolinks import Turbolinks from 'turbolinks'; Turbolinks.start(); //= require materialize-sprockets import 'materialize-css'; import './../stylesheets/application.scss';
Adapt application.css -@import "materialize/components/color"; +@import "~materialize-css/sass/components/color"; $primary-color: #5d4ca0 !default; $secondary-color:
#38d59c !default; -@import "materialize" +$roboto-font-path: "~materialize-css/fonts/roboto/"; +@import "~materialize-css/sass/materialize"; module.exports = { // ... module: { loaders: [ { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader" }, { test: /\.(woff|woff2)$/, loader: "url-loader?prefix=font/&limit=5000" { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/ { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=image/svg+xm ] } }
Run yarn run webpack
Integrate with Rails rake webpack – or – rake assets:precompile
Foreman gem install foreman foreman start # Procfile rails: bundle
exec rails server -e ${RAILS_ENV:="development"} -p 3000 webpack: yarn webpack -- --watch --progress
Disabling the Rails asset pipeline
in a new app rails new app --skip-sprockets rails new
app --skip-javascript --skip-turbolinks --skip-action-cable
in an existing app # config/application.rb -require 'rails/all' +require 'rails'
+require 'active_model/railtie' +require 'active_job/railtie' +require 'active_record/railtie' +require 'action_controller/railtie' +require 'action_mailer/railtie' +require 'action_view/railtie' +require 'action_cable/engine' +require 'rails/test_unit/railtie' - config.assets.debug = true - config.assets.quiet = true rm config/initializers/assets.rb
Rails integration /// manifest-84b43dda218a2c29ce11f4f7b9ca4e5f.json { "assets": { "1downarrow.png": "1downarrow-d2055955ce2927de07f2e33abdbfdc1b.png", "1uparrow.png":
"1uparrow-a4eef1942dd999e6a16e84c1c8122b8a.png", "2downarrow.png": "2downarrow-e8bc5b59fa922f68637dc22b4a467f5c.png" } }
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/
Conclusion
Grazie!
Domande?