Good bye sprockets!

...almost

But what's wrong with it?

  • no module system - import everything in single file and order of 'require' matters!!
  • built for rails, not for javascript

Webpack

A bundler for javascript and friends. Packs many modules into a few bundled assets.

https://webpack.js.org/

Webpacker

  • let javascript tool deal with javascript
  • manage javascript dependencies with package manager (yarn / npm)
  • better code organization with module system
  • built-in support for css/sass/scss, fonts and images
  • live-reload server for javascript
  • highly configurable

Gem wrapper for webpack - https://github.com/rails/webpacker

Webpacker

// Gemfile

gem 'webpacker', '~> 3.0'
// you can add foreman and craete Procfile for this
bundle exec rails s
./bin/webpack-dev-server --inline true --hot false
// create webpack config files
./bin/rails webpacker:install
// add pack to layout
// name has to match with pack name
<%= javascript_pack_tag 'application' %>
<%= stylesheet_pack_tag 'application' %>

Own modules - sprockets

// application.js - manifest 

// require api.js
// require postsIndex.js
// postsIndex.js

window.myApp = window.myApp || {};

function postsIndex() {
    myApp.api.fetchPosts(); // access api module 
    // do stuff required on posts index view
}

window.myApp.postsIndex = postsIndex; // register view module in global scope
// api.js

window.myApp = window.myApp || {};

const apiMethods = {
    fetchPosts: () {
        // fetch posts logic here
    }
}

window.myApp.api = apiMethods; // register api module in global scope
// application.js - root application file 

import postsIndex from './posts/postsIndex';

window.myApp = {
    postsIndex: postsIndex
};
// posts/postsIndex.js
import api from './api';

function postsIndex() {
    api.fetchPosts(); // access api module 
    // do stuff required on posts index view
}

export default postsIndex;
// api.js

const apiMethods = {
    fetchPosts: () {
        // fetch posts logic here
    }
};

export default apiMethods;

Own modules - webpacker

Using jQuery & Bootstrap

// install jquery with package manager
yarn add jquery
// config/webpack/shared.js
// add jquery to global scope for webpack build

module.exports = {
...
    plugins: [
        ...
        new webpack.ProvidePlugin({
            jQuery: "jquery",
            $: "jquery",
            jquery: "jquery",
        }),
    ]
...
};

Using jQuery & Bootstrap

// install bootstrap with package manager
yarn add bootstrap
// main.js
// import all required dependencies

// bootstrap
import "bootstrap/dist/js/bootstrap.js";
import "bootstrap/dist/css/bootstrap.css";
// bootstrap-datetimepicker
import "eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js";
import "eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.css";

/***** NOTE ******/
You may need to dig through node_modules/ 
and lib directory to find what file you need to import

Where to put my code?

  • assets used inside rails views stays inside app/assets/images
  • all javascript code goes to app/javascript
    • root files (manifests) goes to packs/
    • other files needs to be placed outside of packs/

Production build

Webpacker hooks up a new webpacker:compile task to assets:precompile, which gets run whenever you run assets:precompile

Made with Slides.com