Slide 1

Slide 1 text

gem ‘webpack-rails' 2015-09-12 Ruby Conf Taiwan

Slide 2

Slide 2 text

The guy here 何澤清 Tse-Ching Ho @tsechingho ⿈黃碼科技 Goldenio Technology Bioinformatics Infographics

Slide 3

Slide 3 text

Javascript Modules

Slide 4

Slide 4 text

Factory function module // my_module.js var myModule = (function (my, $) { my.publicMethod = function () { $('.events').fadeIn(); }; return my; }(myModule || {}, jQuery)); window.myModule = myModule; // app.js myModule.publicMethod();

Slide 5

Slide 5 text

CommonJS module // my_module.js var $ = require(‘jquery'); exports.myModule = function () { var my = {}; my.publicMethod = function () { $('.events').fadeIn(); }; return my; }; // app.js var myModule = require(‘my_module'); myModule.publicMethod();

Slide 6

Slide 6 text

RequireJS module // my_module.js define(['jquery'] , function ($) { var my = {}; my.publicMethod = function () { $('.events').fadeIn(); }; return my; }); // app.js var myModule = require('my_module'); myModule.publicMethod();

Slide 7

Slide 7 text

ECMAScript 6 module // my_module.js module myModule { import $ from 'jquery'; export var my = { publicMethod: function () { $('.events').fadeIn(); } } } // app.js import myModule from ‘my_module'; myModule.publicMethod();

Slide 8

Slide 8 text

Webpack

Slide 9

Slide 9 text

Features Webpack Dev Server Hot Module Replacement (HMR) webpack.config.js & CLI Multiple entry points Loaders & Transpiler (ES6, React JSX, CoffeeScript, Sass) Plugins

Slide 10

Slide 10 text

Module style of webpack require('../component.less'); var Foo = require('app/shared/foo'); var template = require('raw!./tmpl.mustache'); module.exports = Foo.extend({ template: template, ... });

Slide 11

Slide 11 text

webpack.config.js // client/webpack.rails.config.js const path = require('path'); module.exports = { context: __dirname, entry: ['./assets/javascripts/App', './scripts/rails_only'], output = { filename: 'client-bundle.js', // '[name].bundle.js' path: '../app/assets/javascripts/generated' }, externals: { jquery: 'var jQuery' }, resolve: { root: [path.join(__dirname, 'scripts'), path.join(__dirname, 'assets/javascripts'), path.join(__dirname, 'assets/stylesheets')], extensions: ['', '.js', '.jsx', '.coffee', '.scss', '.css', '.webpack.js', '.web.js', ‘config.js'] }, module: { loaders: [ { test: /\.coffee$/, exclude: /node_modules/, loader: 'coffee-loader' }, { test: /\.jsx$/, exclude: /node_modules/, loader: ‘babel-loader' }, { test: /\.js$/, exclude: /node_modules/, loader: ‘babel-loader' }, { test: require.resolve('jquery'), loader: ‘expose?jQuery' }, { test: require.resolve('jquery'), loader: ‘expose?$' } ] } }; http://webpack.github.io/docs/configuration.html

Slide 12

Slide 12 text

Entry point script // App.jsx import $ from 'jquery'; import React from 'react'; import CommentBox from './components/CommentBox'; $(function onLoad() { function render() { if ($('#content').length > 0) { React.render( , document.getElementById('content') ); } } render(); $(document).on('page:change', () => { render(); }); // turblolinks });

Slide 13

Slide 13 text

Sprockets

Slide 14

Slide 14 text

Assets Management download from source into vendor/assets use a ruby gem including a rails engine use bower and configure rails use the bower-rails gem use rails-assets.org http://www.codefellows.org/blog/5-ways-to-manage-front-end-assets-in-rails

Slide 15

Slide 15 text

Rails Asset Pipeline Module Definition Factory function module CommonJS module RequireJS module Transpiler: coffeescript package bundler: sprockets

Slide 16

Slide 16 text

Sprockets long lives Hybrid is good webpack for modularity sprockets for integration (replaced by webpack?) Assets caching/fingerprinting is easy for non-js views helpers are still helpful: asset_path, javascript_include_tag jquery_ujs is still powerful assets:webpack task works well for deploy

Slide 17

Slide 17 text

Bad ways for Sprockets only app/views/layouts/application.html.slim the layout applies only compiled application.js file the compiled application.js bundles all files under 
 app/assets/javascripts/**/**.js.coffee dependencies describe in every files javascript_include_tag would be used in each views for vendor libraries only

Slide 18

Slide 18 text

Good ways for Sprockets many app/views/layouts/xxx.html.slim each layout applies a compiled xxx.js file each compiled xxx.js file bundles folders under 
 app/assets/javascripts/xxx/**/**.js.coffee dependencies describe in xxx.js file javascript_include_tag would be used in each views for home brewed bundles

Slide 19

Slide 19 text

webpack-rails

Slide 20

Slide 20 text

I want ES6 & React.js npm + package.json + webpack no more bower, grunt, gulp and browserify

Slide 21

Slide 21 text

Package manager http://forum.railsonmaui.com/t/fast-rich-client-rails-development-with-webpack-and-the-es6-transpiler/327

Slide 22

Slide 22 text

Hybridization mode Make peace with sprockets

Slide 23

Slide 23 text

Assets bundle http://forum.railsonmaui.com/t/fast-rich-client-rails-development-with-webpack-and-the-es6-transpiler/327

Slide 24

Slide 24 text

File Structure client/ assets/ images/ javascripts/ stylesheets/ public/ index.html client/ config/ webpack/ common.js hot.js rails.js
 node_modules/ scripts/ rails_only.jsx webpack_only.jsx package.json server.js / .gitignore Procfile Procfile.dev

Slide 25

Slide 25 text

Images & Fonts Symbolic links client/assets/fonts -> app/assets/fonts client/assets/images -> app/assets/images ……

Slide 26

Slide 26 text

Stylesheets Sass & Compass are awesome Add client/assets/stylesheets to asset pipeline's search path config.assets.paths << Rails.root.join('client', 'assets', 'stylesheets') @import Sass files of webpack in
 app/assets/stylesheets/applications.sass https://github.com/jtangelder/sass-loader

Slide 27

Slide 27 text

Javascripts webpack compile client-bundler.js for sprockets in app/assets/javascripts/generated only need to require webpack generated js file in 
 app/assets/javascripts/applications.js //= require generated/client-bundler.js import js modules, no more require js files

Slide 28

Slide 28 text

Client Side Development foreman start as rails@3000, webpack-dev@4000 adjust client/server.js for json api of webpack modify js and sass files under client/assets save files and watch realtime replacement @4000 create json api of rails and verify @3000 deploy with Sprockets

Slide 29

Slide 29 text

https://github.com/ goldenio/webpack-rails

Slide 30

Slide 30 text

END