Rails + Webpack

Post on 22-Jan-2018

609 views 0 download

transcript

Rails/WebpackKhor, @neth_6, re:Culture, Xenon Ventures

2017-03-08

Goal● Rubyists be comfortable with Javascript

○ Installing webpack onto Rails app○ Directory structure conventions○ Configuration options○ Simple javascript web app

Agenda● Rails & Javascript History● Why Webpack● ‘Live-coding’ from scratch to simple app

# Gemfilegem 'jquery-rails'

The gem Way

The gem Way - Noooo!

● gem creation● gem updated

The cowboy Way ● app/assets/javascripts● lib/assets/javascripts● vendor/assets/javascripts

The cowboy way - sidekickvendorer gem

Dependencies

The cowboy way - Noooo!

JS package names

Can require JS, CSS, etc.

The rails-assets Way

JS packages

RubyGem

Manage dependencies Convert JS into Gem

The rails-assets Way - Future● Will bower be around?● Will rails-assets be around?● Tested in JS but not tested in Rails assets?

Browserify, Webpack, etc.

Rails+Relay+GraphQL+React+Browserify

https://medium.com/react-weekly/relay-facebook-on-rails-8b4af2057152

Rails/Webpack

Javascript as First-class Citizen

First-class Citizen

Javascript tools do packaging, manage dependencies, etc.

What You Already Know> curl -sSL https://get.rvm.io | bash -s stable --ruby

> rvm install 2.3.0

> rvm use 2.3.0@global

> gem install bundle

> rvm use 2.3.0

> rvm gemset create rails_webpack

> rvm gemset use rails_webpack

> gem install rails

rvm

bundler

gem

Live Coding> rails new rails_webpack

> echo 2.3.0 > rails_webpack/.ruby-version

> echo rails_webpack > rails_webpack/.ruby-gemset

> cd rails_webpack

> echo “gem ‘webpacker’, github: ‘rails/webpacker’” >> Gemfile

> echo “gem ‘foreman’” >> Gemfile

> bundle install

> rails webpack:install

rails app

webpack

rails env

rails webpack:install

Webpack config

Webpack config

config/webpack/shared.js entry: glob.sync(path.join('app', 'javascript', 'packs', '*.js*')).reduce( (map, entry) => { const basename = path.basename(entry, extname(entry)) const localMap = map localMap[basename] = path.resolve(entry) return localMap }, {} ),

output: { filename: '[name].js', path: path.resolve('public', ‘packs’) },

Bundle entry points

Generated bundles

config/webpack/production.jsmodule.exports = merge(sharedConfig.config, { output: { filename: '[name]-[chunkhash].js' },

plugins: [ new webpack.LoaderOptionsPlugin({ minimize: true }), new webpack.optimize.UglifyJsPlugin(), new CompressionPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: /\.js$/ })

Do stuff required for production

Javascript Code

Where JS code lives

Webpack config

app/javascriptCommon structure:

+-- app/javascript/ | +-- <app name>/ | +-- components/ +-- index.js

app/javascript/simple/index.jsimport _ from 'lodash';

function component () { var element = document.createElement('div');

/* lodash is required for the next line to work */ element.innerHTML = _.join(['Woohoo','webpack'], ' ');

return element;}

document.body.appendChild(component());

Bundle Entry Points

Where JS code livesBundle entry points

Refers to code

Webpack config

app/javascript/packs/simple.js// Refers to code in app/javascript

import ‘../simple’

Bundle Output

Where JS code livesBundle entry points

Refers to code

/public/packsOutputs to

Webpack config

public/packs/simple.js/******/ (function(modules) { // webpackBootstrap/******/ // The module cache/******/ var installedModules = {};....

function component() { var element = document.createElement('div'); /* lodash is required for the next line to work */ element.innerHTML = __WEBPACK_IMPORTED_MODULE_0_lodash___default.a.join(['Woohoo', 'webpack'], ' '); return element;}

Live Coding (cont.)> rails g controller page index rails view

app/views/pages/index.html.erb<%= javascript_pack_tag 'simple' %>

Tada….the most meaningless web app

Tada….the most meaningless web app

<%= javascript_pack_tag 'simple' %> <html> <body>

…. < assets stuff > ...

<script src="/packs/simple.js"></script>

</body></html>

Webpack Wrappers

Where JS code livesBundle entry points

Refers to code

/public/packsOutputs to

Webpack config

WebpackWrappers

Webpack Wrapper (cont.)● bin/webpack

○ Compiling bundles

● bin/webpack-watcher○ Watch for bundle changes and re-compile with Webpack into public/packs

● bin/webpack-dev-server○ Live-reloading

■ Watch for bundle changes, re-compile with Webpack, and refresh■ Can serve pages from public/packs

Manual compile (e.g., production deploy): rails webpack:compile

Procfile

# Run Rails & Webpack concurrentlyrails: bundle exec puma -p $PORTwpwatcher: ./bin/webpack-watcher

Procfile (webpack-dev-server)# Run Rails & Webpack concurrentlyrails: bundle exec puma -p $PORTwebpack-dev-server: ./bin/webpack-dev-server

# config/environments/development.rb

# For webpack-dev-serverconfig.x.webpacker[:dev_server_host] = "http://localhost:8080"

Other webpacker commands

rails webpack:install - Compile assetsrails webpack:install:react - Install react

Is CoffeeScript Gone?// config/webpack/shared.js

module: { rules: [ { test: /\.coffee(\.erb)?$/, loader: 'coffee-loader' }, ... },}

Accessing Assets from Javascript// config/webpack/shared.js

module: { rules: [ { test: /\.js(\.erb)?$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: [ ['env', { modules: false }] ] } },

Accessing Assets from Javascript (cont.)// app/javascript/simple/index.js.erb

<% helpers = ActionController::Base.helpers %>var railsImagePath = "<%= helpers.image_path('rails.png') %>";

References● Unholy Javascript:

○ http://railsapps.github.io/rails-javascript-include-external.html

● Webpacker: ○ https://medium.com/statuscode/introducing-webpacker-7136d66cddfb

Thank You!

Convox Tokyo Meetup 23 Mar 2017https://www.meetup.com/Convox-Meetup/events/237726139/