Skip to content

Commit f587990

Browse files
committed
Merge pull request shakacode#203 from shakacode/rob/env-tag-helper-api-changes
Asset Tag Helpers API Change
2 parents 902228b + 2df524f commit f587990

15 files changed

+87
-59
lines changed

Procfile.dev

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44

55
# Development rails requires both rails and rails-assets
66
# (and rails-server-assets if server rendering)
7-
rails: rails s
7+
rails: REACT_ON_RAILS_ENV=HOT rails s
8+
89
# Run the hot reload server for client development
910
rails-assets: sh -c 'rm app/assets/webpack/* || true && HOT_RAILS_PORT=3500 npm run build:dev:client'
11+
1012
# Keep the JS fresh for server rendering. Remove if not server rendering
1113
rails-server-assets: sh -c 'npm run build:dev:server'
1214

1315
# If you don't keep this process going, you will rebuild the assets per spec run. This is configured
1416
# in rails_helper.rb.
15-
rails-spec: sh -c 'npm run build:test:client'
17+
rails-test: sh -c 'npm run build:test:client'
1618

1719
# Run an express server if you want to mock out your endpoints. No Rails involved!
1820
# Disable this if you are not using it.

Procfile.express

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# Basic procfile for express server dev work.
21
# Only run the express server!
32
# Use this if you want to mock out your endpoints.
43
# It's a great way to prototype UI especially with non-Rails developers!
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
# Basic procfile for dev work using Rails
1+
# Basic procfile for dev work.
2+
# Runs all processes. Development is faster if you pick one of the other Procfiles if you don't need
3+
# some of the processes: Procfile.rails or Procfile.express
4+
25
# Development rails requires both rails and rails-assets
36
# (and rails-server-assets if server rendering)
4-
# You can still run tests, and they will build the webpack file for each test run.
5-
# Start another shell and run the Procfile.spec to make test runs faster.
7+
rails: REACT_ON_RAILS_ENV=HOT rails s
68

7-
rails: rails s
89
# Run the hot reload server for client development
910
rails-assets: sh -c 'rm app/assets/webpack/* || true && HOT_RAILS_PORT=3500 npm run build:dev:client'
11+
1012
# Keep the JS fresh for server rendering. Remove if not server rendering
1113
rails-server-assets: sh -c 'npm run build:dev:server'

Procfile.spec

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
# Basic procfile running webpack to recreate the assets for tests with a watch process.
1+
# For keeping webpack bundles up-to-date during a testing workflow.
22
# If you don't keep this process going, you will rebuild the assets per spec run. This is configured
33
# in rails_helper.rb.
4-
5-
rails-spec: sh -c 'npm run build:test:client'
4+
rails-test: sh -c 'npm run build:test:client'

Procfile.static

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Run Rails without hot reloading (static assets)
2+
rails: rails s
3+
4+
# Keep the JS fresh for server rendering. Remove if not server rendering
5+
rails-server-assets: sh -c 'npm run build:dev:server'

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ See package.json and Gemfile for versions
7575
1. Open a browser tab to http://localhost:3000 for the Rails app example.
7676
1. Open a browser tab to http://localhost:4000 for the Hot Module Replacement Example.
7777
1. With the browser open to any JSX file, such as [client/app/bundles/comments/components/CommentBox/CommentBox.jsx](client/app/bundles/comments/components/CommentBox/CommentBox.jsx) and you can change the JSX code, hit save, and you will see the sceen update without refreshing the window. This applies to port 3000 and port 4000.
78-
1. Try changing a `.scss` file, such as a color in [client/app/bundles/comments/components/CommentBox/CommentList/Comment/Comment.scss](client/app/bundles/comments/components/CommentBox/CommentList/Comment/Comment.scss). You can see port 3000 or 4000 update automatically.
78+
1. Try changing a `.scss` file, such as a color in [client/app/bundles/comments/components/CommentBox/CommentList/Comment/Comment.scss](client/app/bundles/comments/components/CommentBox/CommentList/Comment/Comment.scss). You can see port 3000 or 4000 update automatically.
7979

8080
# KEY COMMANDS
8181
1. Run all linters and tests: `rake ci`
@@ -95,16 +95,17 @@ Save a change to a JSX file and see it update immediately in the browser! Note,
9595
# Rails integration
9696

9797
## JS and CSS assets
98-
We're now using Webpack for all Sass and JavaScript assets so we can do CSS Modules within Rails!
98+
We're now using Webpack for all Sass and JavaScript assets so we can do CSS Modules within Rails!
99+
100+
1. **Production Deployment**: See [assets.rake](lib/tasks/assets.rake) for we modify the Rails precompile task to deploy assets for production.
101+
1. **Development Mode**: We modify the URL in [application.html.erb](app/views/layouts/application.html.erb) based on whether or not we're in production mode using the helpers `env_stylesheet_link_tag` and `env_javascript_include_tag`. *Development mode* uses the Webpack Dev server running on port 3500. Other modes (production/test) uses precompiled files.
99102

100-
1. **Production Deployment**: See [assets.rake](lib/tasks/assets.rake) for we modify the Rails precompile task to deploy assets for production.
101-
2. **Development mode**: We modify the URL in [application.html.erb](app/views/layouts/application.html.erb) based on whether or not we're in production mode using the helpers `env_stylesheet_link_tag` and `env_javascript_include_tag`. *Development mode* uses the Webpack Dev server running on port 3500. Other modes (production/test) uses precompiled files.
102103
```erb
103-
<%= env_stylesheet_link_tag 'application_prod', 'application_dev', media: 'all', 'data-turbolinks-track' => true %>
104-
<%= env_javascript_include_tag nil, 'http://localhost:3500/vendor-bundle.js' %>
105-
<%= env_javascript_include_tag nil, 'http://localhost:3500/app-bundle.js' %>
106-
<%= env_javascript_include_tag 'application_prod', 'application_dev', 'data-turbolinks-track' => true %>
104+
<%= env_stylesheet_link_tag(static: 'application_static', hot: 'application_non_webpack', options: { media: 'all', 'data-turbolinks-track' => true }) %>
105+
<%= env_javascript_include_tag(hot: ['http://localhost:3500/vendor-bundle.js', 'http://localhost:3500/app-bundle.js']) %>
106+
<%= env_javascript_include_tag(static: 'application_static', hot: 'application_non_webpack', options: { 'data-turbolinks-track' => true }) %>
107107
```
108+
1. **Testing Mode**: When running tests, it is useful to run `foreman start -f Procfile.spec` in order to have webpack automatically recompile the static bundles. Rspec is configured to automatically check whether or not this process is running. If it is not, it will automatically rebuild the webpack bundle to ensure you are not running tests on stale client code. This is achieved via the ` config.include ReactOnRails::EnsureAssetsCompiled, type: :feature` line in the `rails_helper.rb` file. If you are using this project as an example and are not using RSpec, you may want to implement similar logic in your own project.
108109

109110
# Webpack configuration
110111
## Config Files
@@ -142,7 +143,7 @@ export default class CommentBox extends React.Component {
142143
```
143144

144145
## Sass and fonts
145-
The tutorial makes use of a custom font OpenSans-Light. We're doing this to show how to add assets for the CSS processing. The font files are located under [client/app/assets/fonts](client/app/assets/fonts) and are loaded by both the Rails asset pipeline and the Webpack HMR server.
146+
The tutorial makes use of a custom font OpenSans-Light. We're doing this to show how to add assets for the CSS processing. The font files are located under [client/app/assets/fonts](client/app/assets/fonts) and are loaded by both the Rails asset pipeline and the Webpack HMR server.
146147

147148
# Process management
148149
Run the following command in your development environment to invoke both Webpack and Rails.
@@ -155,7 +156,7 @@ bundle exec foreman start -f Procfile.dev
155156

156157
Notable contributions include (please submit PR if I miss any!):
157158

158-
* [Justin Gordon](https://github.com/justin808/): Started this, leads this
159+
* [Justin Gordon](https://github.com/justin808/): Started this, leads this
159160
* [Alex Fedoseev](https://github.com/alexfedoseev): Added integration of Rails hot loading and CSS modules, plus much more
160161
* [Martin Breining](https://github.com/mbreining): For adding flux at first
161162
* [Dylan Grafmyre](https://github.com/Dgrafmyre): For ci setup

app/assets/javascripts/application_prod.js renamed to app/assets/javascripts/application_static.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
//= require app-bundle
1111

1212
// Non-webpack assets incl turbolinks
13-
//= require application_dev
13+
//= require application_non_webpack

app/assets/stylesheets/application_prod.css.scss renamed to app/assets/stylesheets/application_static.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
@import 'app-bundle';
44

55
// Non-webpack assets
6-
@import 'application_dev';
6+
@import 'application_non_webpack';

app/helpers/application_helper.rb

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
module ApplicationHelper
22
# TODO: MOVE TO helper in react_on_rails
33
# See application.html.erb for usage example
4-
def env_javascript_include_tag(prod_asset, dev_asset, params = {})
5-
asset_file = !Rails.env.development? ? prod_asset : dev_asset
6-
return javascript_include_tag(asset_file, params) if asset_file
4+
def env_javascript_include_tag(args = {})
5+
send_tag_method(:javascript_include_tag, args)
76
end
87

98
# TODO: MOVE TO helper in react_on_rails
10-
def env_stylesheet_link_tag(prod_asset, dev_asset, params = {})
11-
asset_file = !Rails.env.development? ? prod_asset : dev_asset
12-
return stylesheet_link_tag(asset_file, params) if asset_file
9+
def env_stylesheet_link_tag(args = {})
10+
send_tag_method(:stylesheet_link_tag, args)
11+
end
12+
13+
def use_hot_reloading?
14+
ENV["REACT_ON_RAILS_ENV"] == "HOT"
15+
end
16+
17+
private
18+
19+
def send_tag_method(tag_method_name, args)
20+
asset_type = use_hot_reloading? ? :hot : :static
21+
assets = Array(args[asset_type])
22+
options = args.delete_if { |key, _value| %i(hot static).include?(key) }
23+
send(tag_method_name, *assets, options) unless assets.empty?
1324
end
1425
end

app/views/layouts/application.html.erb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
<html>
33
<head>
44
<title>RailsReactTutorial</title>
5-
<%= env_stylesheet_link_tag 'application_prod', 'application_dev', media: 'all', 'data-turbolinks-track' => true %>
6-
<%= env_javascript_include_tag nil, 'http://localhost:3500/vendor-bundle.js' %>
7-
<%= env_javascript_include_tag nil, 'http://localhost:3500/app-bundle.js' %>
8-
<%= env_javascript_include_tag 'application_prod', 'application_dev', 'data-turbolinks-track' => true %>
5+
<%= env_stylesheet_link_tag(static: 'application_static',
6+
hot: 'application_non_webpack',
7+
media: 'all',
8+
'data-turbolinks-track' => true) %>
9+
<!-- These do not use turbolinks -->
10+
<%= env_javascript_include_tag(hot: ['http://localhost:3500/vendor-bundle.js',
11+
'http://localhost:3500/app-bundle.js']) %>
12+
<!-- These do use turbolinks -->
13+
<%= env_javascript_include_tag(static: 'application_static',
14+
hot: 'application_non_webpack',
15+
'data-turbolinks-track' => true) %>
916
<%= csrf_meta_tags %>
1017
</head>
1118
<body>

docs/jquery-with-react-on-rails.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
jQuery and jQuery-ujs are not required within `app/assets/javascript/application.js` and have been moved under`/client` and are managed by npm. The modules are exposed via entry point by [client/webpack.client.base.config.js](client/webpack.client.base.config.js) and, for `jquery-ujs`, in the [client/webpack.client.rails.build.config.js](client/webpack.client.rails.build.config.js) and the [client/webpack.client.rails.hot.config.js](client/webpack.client.rails.hot.config.js).
44

5-
In `application_dev.js` and `application_prod.js`, it's critical that any libraries that depend on jQuery come after the inclusion
5+
In `application_non_webpack.js` and `application_static.js`, it's critical that any libraries that depend on jQuery come after the inclusion
66
of the Webpack bundle.
77

88
Please refer to [Considerations for jQuery with Rails and Webpack](http://forum.shakacode.com/t/considerations-for-jquery-with-rails-and-webpack/344) for further info.

spec/rails_helper.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@
3939
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
4040

4141
RSpec.configure do |config|
42+
# Next line will ensure that assets are built if webpack -w is not running
43+
config.include ReactOnRails::EnsureAssetsCompiled, type: :feature
44+
4245
# config taken directly from RSpec example in the DatabaseCleaner README
4346
config.before(:suite) do
4447
DatabaseCleaner.strategy = :transaction
4548
DatabaseCleaner.clean_with :truncation
46-
47-
# Next line will ensure that assets are built if webpack -w is not running
48-
EnsureAssetsCompiled.check_built_assets
4949
end
5050

5151
config.around(:each) do |example|
Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,34 @@
11
# TODO: Move to react_on_rails
2-
class EnsureAssetsCompiled
3-
def self.check_built_assets
4-
return if @checked_built_assets
5-
build_all_assets
6-
end
72

8-
def self.running_webpack_watch?(type)
9-
running = `pgrep -fl '\\-w \\-\\-config webpack\\.#{type}\\.rails\\.build\\.config\\.js'`
10-
if running.present?
11-
puts "Found process, so skipping rebuild => #{running.ai}"
12-
return true
3+
module ReactOnRails
4+
module EnsureAssetsCompiled
5+
def self.check_built_assets
6+
return if @checked_built_assets
7+
build_assets_for_type("client")
8+
build_assets_for_type("server")
9+
@checked_built_assets = true
1310
end
14-
end
1511

16-
def self.build_assets_for_type(type)
17-
unless running_webpack_watch?(type)
18-
build_output = `cd client && npm run build:#{type}`
19-
if build_output =~ /error/i
20-
fail "Error in building assets!\n#{build_output}"
21-
else
22-
puts "Webpack build completed."
12+
def self.build_assets_for_type(type)
13+
unless running_webpack_watch?(type)
14+
build_output = `cd client && npm run build:#{type}`
15+
if build_output =~ /error/i
16+
fail "Error in building assets!\n#{build_output}"
17+
else
18+
puts "Webpack build completed."
19+
end
20+
end
21+
end
22+
23+
def self.running_webpack_watch?(type)
24+
running = `pgrep -fl '\\-w \\-\\-config webpack\\.#{type}\\.rails\\.build\\.config\\.js'`
25+
if running.present?
26+
puts "Found process, so skipping rebuild => #{running.ai}"
27+
return true
2328
end
2429
end
25-
end
2630

27-
def self.build_all_assets
28-
build_assets_for_type("client")
29-
build_assets_for_type("server")
30-
@checked_built_assets = true
31+
# Runs on require
32+
check_built_assets
3133
end
3234
end

0 commit comments

Comments
 (0)