Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ gem 'rails_12factor'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0.0.beta1'
gem 'bootstrap-sass', '~> 3.3.1'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
Expand All @@ -37,6 +38,8 @@ gem 'rails-html-sanitizer', '~> 1.0'
# Use Unicorn as the app server
gem 'unicorn'

gem 'autoprefixer-rails'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

Expand All @@ -49,9 +52,7 @@ group :development, :test do

# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
end


gem 'bootstrap-sass', '~> 3.2.0'
gem 'autoprefixer-rails'

# Manage application processes
gem 'foreman'
end
9 changes: 7 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ GEM
execjs
binding_of_caller (0.7.3.pre1)
debug_inspector (>= 0.0.1)
bootstrap-sass (3.2.0.1)
bootstrap-sass (3.3.1.0)
sass (~> 3.2)
builder (3.2.2)
byebug (3.2.0)
Expand All @@ -55,8 +55,12 @@ GEM
columnize (0.8.9)
debug_inspector (0.0.2)
debugger-linecache (1.2.0)
dotenv (1.0.2)
erubis (2.7.0)
execjs (2.2.1)
foreman (0.76.0)
dotenv (~> 1.0.2)
thor (~> 0.19.1)
globalid (0.2.3)
activesupport (>= 4.1.0)
hike (1.2.3)
Expand Down Expand Up @@ -161,9 +165,10 @@ PLATFORMS

DEPENDENCIES
autoprefixer-rails
bootstrap-sass (~> 3.2.0)
bootstrap-sass (~> 3.3.1)
byebug
coffee-rails (~> 4.0.0)
foreman
jbuilder (~> 2.0)
jquery-rails
pg
Expand Down
2 changes: 1 addition & 1 deletion Procfile.dev
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
web: rails s -p 4000
webpack: cd webpack && webpack -w --config webpack.rails.config.js
webpack: cd webpack && $(npm bin)/webpack -w --config webpack.bundle.config.js
135 changes: 100 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,88 +8,153 @@ Full tutorial can be found at: [Fast Rich Client Rails Development With Webpack

# Motivation

1. Enable development of a JS client separate from Rails.
2. Enable easily retrofitting such a JS framework into an existing Rails app.
3. Enable the use of the JavaScript es6 transpiler.
4. Enable easily using npm modules with a Rails application.
In no particular order:
- Enable development of a JS client independently from Rails.
- Easily enable use of npm modules with a Rails application.
- Easily enable retrofitting such a JS framework into an existing Rails app.
- Enable the use of the JavaScript ES6 transpiler.

# Example of the following technologies:
# Technologies involved

1. react
2. react-bootstrap
3. webpack with hot-reload
4. es6-loader (es6 transpiler)
5. Simultaneously working with Rails 4.2
6. Deployable to Heroku
1. React 0.11 (for front-end app)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we will change this shortly, but this can be the next PR

2. React-bootstrap 0.12
3. Webpack with hot-reload 1.4 (for local dev)
4. ES6 transpiler (es6-loader) 0.2
5. Rails 4.2 (for backend app)
6. Heroku (for deployment)

# Running without Rails using Hot Reload
# Javascript development without Rails using Hot Module Replacement (HMR)

Setup node and run the node server.

```
npm install
cd webpack && node server.js
```

Point browser to [http://0.0.0.0:3000]().
Point your browser to [http://0.0.0.0:3000]().


Save a change to a JSX file and see it update immediately in the browser! Note,
any browser state still exists, such as what you've typed in the comments box.
That's totally different than "Live Reload" which refreshes the browser.
That's totally different than [Live Reload](http://livereload.com/) which refreshes
the browser.

# Rails integration

## Build JS/CSS bundles
Run this command to have webpack build the JS/CSS bundles and have them saved in the Rails
asset pipeline (app/assets).
The Webpack ExtractTextPlugin can optionally be used to extract the CSS out of
the JS bundle. The following bundles would then be generated:
- rails-bundle.js which gets saved to app/assets/javascripts
- bootstrap-and-customizations.css which gets saved in app/assets/stylesheets
Observe how the bundles are automatically re-generated whenever your JSX changes.

# Rails
```
cd webpack
webpack -w --config webpack.rails.config.js
```

Make sure to invoke your local copy of the webpack executable as opposed
to any globally installed webpack.
See https://github.com/webpack/extract-text-webpack-plugin/blob/master/example/webpack.config.js
If in doubt, run the following command:
```
$(npm bin)/webpack -w --config webpack.rails.config.js
```

## Run Rails server

Once the JS/CSS bundled have been generated into the Rails asset pipeline, you can start
the Rails server.

```
cd <rails_project_name>
bundle install
rake db:setup
rails s -p 4000
```
Point browser to [http://0.0.0.0:4000]().
Point your browser to [http://0.0.0.0:4000]().

It's important to run the rails server on different port than the node server.
It's important to run the Rails server on a different port than the node server.

## Automatically Building the rails-bundle.js
Run this command to automatically build the rails-bundle.js file in the
javascript directory whenever your jsx files change.
# Webpack configuration
- `webpack.hot.config.js`: Used by server.js to run the demo express server.
- `webpack.rails.config.js`: Used to generate the Rails bundles.
- `webpack.common.config.js`: Common configuration file to minimize code duplication.

```
cd webpack
webpack -w --config webpack.rails.config.js
```
# Bootstrap integration
Notice that Bootstrap Sass is installed as both a gem and an npm package.
When running the Rails app, the bootstrap-sass gem assets are loaded directly
through the asset pipeline without passing through Webpack.
See app/assets/application.css.scss.
On the other hand when running the Webpack dev server, the bootrap-sass npm
assets are loaded through Webpack (with help of the bootstrap-sass-loader).
See webpack/webpack.hot.config.js.


Bootstrap can be customized by hand-picking which modules to load and/or overwriting
some of the Sass variables defined by the frameworks.

## Bootstrap modules customization

If you are not using all the Bootstrap modules then you'll likely want to customize
it to avoid loading unused assets. This customization is done in separate files
for the Rails app versus the Webpack dev server so it's important to keep these
in-sync as you develop your app in parallel using the Rails and the Webpack HMR
environments.

- Rails Bootstrap customization file: app/assets/stylesheets/_bootstrap-custom.scss
- Webpack HMR Bootstrap customization file: webpack/bootstrap-sass.config.js

## Bootstrap variables customization

# Webpack Configuration
`webpack.hot.config.js`: Used by server.js to run the demo server.
`webpack.rails.config.js`: Used to generate the rails-bundle.js file
If you need to customize some of the Sass variables defined in Bootstrap you
can do so by overwriting these variables in a separate file and have it loaded
before other Bootstrap modules.

# Notes on Rails Assets
To avoid duplicating this customization between Rails and Webpack HMR,
this custom code has been consolidated under Webpack in
webpack/assets/stylesheets/_bootstrap-variables-customization.scss and the
webpack/assets/stylesheets directory added to the Rails asset pipeline
search path. See config config/application.rb. Keep that in mind as you
customize the Bootstrap Sass variables.

# Notes on Rails assets
## Javascript
The `webpack.rails.config.js` file generates rails-bundle.js which is included
The `webpack.rails.config.js` file generates rails-bundle.js which is then included
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may consider changing the name of this file to webpack-bundle.js, just so it's totally clear where it's coming from...rails doesn't really have much meaning in this context.

by the Rails asset pipeline.

## Sass and images
1. The Webpack server loads the images from the **symlink** of of the
1. The Webpack server loads the images from the **symlink** of the
app/assets/images directory.
2. Since the images are not moved, Rails loads images via the normal asset
pipeline features.
3. The `image-url` sass helper takes care of mapping the correct directories for
images. The image directory for the webpack server is configured by this
line:

```
{ test: /\.scss$/, loader: "style!css!sass?outputStyle=expanded&imagePath=/assets/images"}
```

# Process management
Run the following command in your development environment to invoke both Webpack and Rails.
```
bundle exec foreman start -f Procfile.dev
```

# Source Maps
They work for both Rails and the Webpack Server!

# Deploying to Heroku

In order to deploy to heroku, you'll need run this command once to set a custom
In order to deploy to heroku, you'll need to run this command once to set a custom
buildpack:

```
heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git
```

This runs the two buildpacks in the `.buildpacks` directory.

# TO DO
1. (Optionally) integrate twitter bootstrap assets into webpack build with way
to configure same options for Rails and Webpack.
5 changes: 3 additions & 2 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
//= require jquery
//= require jquery_ujs

//= require bootstrap-sprockets

// Important to import jquery_ujs before rails-bundle as that patches jquery xhr to use the authenticity token!

//= require rails-bundle
//= require webpack-bundle
//= require turbolinks
//= require bootstrap-sprockets
53 changes: 53 additions & 0 deletions app/assets/stylesheets/_bootstrap-custom.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Customizations - needs to be imported first!
@import "bootstrap-variables-customization";

// Core variables and mixins
@import "bootstrap/variables";
@import "bootstrap/mixins";

// Reset and dependencies
@import "bootstrap/normalize";
@import "bootstrap/print";
@import "bootstrap/glyphicons";

// Core CSS
@import "bootstrap/scaffolding";
@import "bootstrap/type";
@import "bootstrap/code";
@import "bootstrap/grid";
@import "bootstrap/tables";
@import "bootstrap/forms";
@import "bootstrap/buttons";

// Components
@import "bootstrap/component-animations";
@import "bootstrap/dropdowns";
@import "bootstrap/button-groups";
@import "bootstrap/input-groups";
@import "bootstrap/navs";
@import "bootstrap/navbar";
@import "bootstrap/breadcrumbs";
@import "bootstrap/pagination";
@import "bootstrap/pager";
@import "bootstrap/labels";
@import "bootstrap/badges";
//@import "bootstrap/jumbotron"; // excluding as an example
@import "bootstrap/thumbnails";
@import "bootstrap/alerts";
//@import "bootstrap/progress-bars"; // excluding as an example
@import "bootstrap/media";
@import "bootstrap/list-group";
@import "bootstrap/panels";
@import "bootstrap/responsive-embed";
@import "bootstrap/wells";
@import "bootstrap/close";

// Components w/ JavaScript
@import "bootstrap/modals"; // excluding as an example
@import "bootstrap/tooltip";
@import "bootstrap/popovers";
@import "bootstrap/carousel"; // excluding as an example

// Utility classes
@import "bootstrap/utilities";
@import "bootstrap/responsive-utilities";
5 changes: 3 additions & 2 deletions app/assets/stylesheets/application.css.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import "bootstrap-sprockets";
@import "bootstrap";
@import "../../../webpack/assets/stylesheets/test-stylesheet";
@import "../../../webpack/assets/stylesheets/test-sass-stylesheet";

@import "bootstrap-sprockets";
@import "bootstrap-custom";
3 changes: 3 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,8 @@ class Application < Rails::Application

# For not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true

# Add webpack/assets/stylesheets to asset pipeline's search path.
config.assets.paths << Rails.root.join("webpack", "assets" ,"stylesheets")
end
end
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"node": "0.10.32"
},
"dependencies": {
"bootstrap-sass": "~3.3.1",
"bootstrap-sass-loader": "~0.0.4",
"imports-loader": "^0.6.3",
"body-parser": "^1.9.0",
"bootstrap-webpack": "*",
"es6-loader": "^0.2.0",
Expand Down
Loading