Skip to content

Commit 410bac6

Browse files
committed
Fix testing issues with Rails hot reloading setup
Configured testing so that: * If we're not running a webpack process to watch the client JS files, then we build the client or server files. * Test will let you know if it's skipping building. Expression used to see if a watch process is running: `pgrep -fl '\\-w \\-\\-config webpack\\.#{type}\\.rails\\.build\\.config\\.js'` * Renamed asset helpers so usage is like this: <%= env_stylesheet_link_tag 'application_prod', 'application_dev', media: 'all', 'data-turbolinks-track' => true %> <%= env_javascript_include_tag nil, 'http://localhost:3500/vendor-bundle.js' %> <%= env_javascript_include_tag nil, 'http://localhost:3500/app-bundle.js' %> <%= env_javascript_include_tag 'application_prod', 'application_dev', 'data-turbolinks-track' => true %> TODO: Should we consider having tests use the Rails hot reload server?
1 parent 5396a79 commit 410bac6

File tree

19 files changed

+103
-30
lines changed

19 files changed

+103
-30
lines changed

Procfile.dev

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
web: rails s
2+
3+
# Run the hot reload server for client development
24
client: sh -c 'rm app/assets/webpack/* || true && cd client && HOT_RAILS_PORT=3500 npm run build:dev:client'
5+
6+
# Keep the JS fresh for specs
7+
client-spec: sh -c 'cd client && npm run build:test:client'
8+
9+
# Keep the JS fresh for server rendering
310
server: sh -c 'cd client && npm run build:dev:server'
411
hot: sh -c 'cd client && HOT_PORT=4000 npm start'

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,14 @@ Note that it's important to run the Rails server on a different port than the no
127127

128128
# Webpack configuration
129129
## Config Files
130+
130131
- `webpack.client.base.config.js`: Common configuration file to minimize code duplication for client.rails and client.hot.
131-
- `webpack.client.rails.config.js`: Used to generate the Rails bundles for Rails use.
132-
- `webpack.client.hot.config.js`: Used by server.js to run the Webpack Dev server.
133-
- `webpack.server.rails.config.js`: Common configuration file to minimize code duplication
134-
between the HMR and Rails configurations.
132+
- `webpack.client.rails.build.config.js`: Client side js bundle.
133+
- `webpack.server.rails.build.config.js`: Server side js bundle
134+
135+
These are used for hot reloading (Webpack Dev Server):
136+
- `webpack.client.rails.hot.config.js`: Used to generate the Rails bundles for Rails use so you get hot reloading within your Rails app.
137+
- `webpack.client.hot.config.js`: Used by server.js to run the Webpack Dev server for stubbing the api end points
135138

136139
## Webpack Resources
137140
- Good overview: [Pete Hunt's Webpack Howto](https://github.com/petehunt/webpack-howto)

app/assets/javascripts/application_dev.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// This one depend on jQuery
1818
//= require turbolinks
1919

20+
// This will soon be removed as it will be in vendor-bundle with react_on_rails 2.0
2021
//= require react_on_rails
2122

2223
//= require rails_startup

app/helpers/application_helper.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
module ApplicationHelper
2-
def javascript_include_env_tag(asset, dev_asset, params = {})
3-
asset_file = Rails.env.production? ? asset : dev_asset
2+
# TODO: MOVE TO helper in react_on_rails
3+
# 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
46
return javascript_include_tag(asset_file, params) if asset_file
57
end
68

7-
def stylesheet_link_env_tag(asset, dev_asset, params = {})
8-
asset_file = Rails.env.production? ? asset : dev_asset
9+
# 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
912
return stylesheet_link_tag(asset_file, params) if asset_file
1013
end
1114
end

app/views/comments/show.html.erb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<div class="comment">
22
<p id="notice"><%= notice %></p>
33

4-
<p>
4+
<p class="js-comment-author">
55
<strong>Author:</strong>
66
<%= @comment.author %>
77
</p>
88

9-
<p>
9+
<p class="js-comment-text">
1010
<strong>Text:</strong>
1111
<%= @comment.text %>
1212
</p>

app/views/layouts/application.html.erb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
<html>
33
<head>
44
<title>RailsReactTutorial</title>
5-
<%= stylesheet_link_env_tag 'application_prod', 'application_dev', media: 'all', 'data-turbolinks-track' => true %>
6-
<%= javascript_include_env_tag nil, 'http://localhost:3500/vendor-bundle.js' %>
7-
<%= javascript_include_env_tag nil, 'http://localhost:3500/app-bundle.js' %>
8-
<%= javascript_include_env_tag 'application_prod', 'application_dev', 'data-turbolinks-track' => true %>
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 %>
99
<%= csrf_meta_tags %>
1010
</head>
1111
<body>

app/views/pages/no_router.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
<%= render "header" %>
44

55
<%= react_component('App', render(template: "/comments/index.json.jbuilder"),
6-
generator_function: true, prerender: true) %>
6+
generator_function: true, prerender: false) %>

client/app/bundles/comments/components/CommentBox/CommentList/Comment/Comment.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ export default class Comment extends React.Component {
1616

1717
return (
1818
<div className={css.comment}>
19-
<h2 className={css.commentAuthor}>
19+
<h2 className={`${css.commentAuthor} js-comment-author`}>
2020
{author}
2121
</h2>
2222
<span
2323
dangerouslySetInnerHTML={{ __html: rawMarkup }}
24-
className="comment-text"
24+
className="js-comment-text"
2525
/>
2626
</div>
2727
);

client/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@
2828
"test:debug": "npm run test -- --debug-brk",
2929
"start": "node server.js",
3030
"build:client": "NODE_ENV=production webpack --config webpack.client.rails.build.config.js",
31-
"build:server": "NODE_ENV=production webpack --config webpack.server.rails.config.js",
31+
"build:server": "NODE_ENV=production webpack --config webpack.server.rails.build.config.js",
3232
"build:dev:client": "babel-node server.rails.hot.js",
33-
"build:dev:server": "webpack -w --config webpack.server.rails.config.js",
33+
"build:dev:server": "webpack -w --config webpack.server.rails.build.config.js",
34+
"build:test:client": "webpack -w --config webpack.client.rails.build.config.js",
3435
"lint": "npm run eslint && npm run jscs",
3536
"eslint": "eslint --ext .js,.jsx .",
3637
"jscs": "jscs --verbose ."

client/webpack.client.base.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ module.exports = {
6262
// React is necessary for the client rendering
6363
{ test: require.resolve('react'), loader: 'expose?React' },
6464
{ test: require.resolve('react-dom'), loader: 'expose?ReactDOM' },
65+
{ test: require.resolve('jquery-ujs'), loader: 'imports?jQuery=jquery' },
6566
{ test: require.resolve('jquery'), loader: 'expose?jQuery' },
6667
{ test: require.resolve('jquery'), loader: 'expose?$' },
6768

config/application.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ class Application < Rails::Application
2020
# config.i18n.load_path += Dir[Rails.root.join("my", "locales", "*.{rb,yml}").to_s]
2121
# config.i18n.default_locale = :de
2222

23-
# Add folder with webpack generated assets to assets.paths
24-
config.assets.paths << Rails.root.join("app", "assets", "webpack")
25-
2623
# For not swallow errors in after_commit/after_rollback callbacks.
2724
config.active_record.raise_in_transactional_callbacks = true
2825
end

config/initializers/assets.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
# Version of your assets, change this if you want to expire all your assets.
44
Rails.application.config.assets.version = "1.0"
55

6-
# Add additional assets to the asset load path
7-
# Rails.application.config.assets.paths << Emoji.images_path
6+
# Add folder with webpack generated assets to assets.paths
7+
Rails.application.config.assets.paths << Rails.root.join("app", "assets", "webpack")
88

99
# Precompile additional assets.
1010
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
11-
Rails.application.config.assets.precompile += %w( application_*.* )
11+
Rails.application.config.assets.precompile += %w(
12+
application_*.*
13+
server-bundle.js
14+
)

docs/testing-deployment.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Testing
2+
3+
1. `rake` runs the test suite
4+
2. To test production with precompiled assets:
5+
6+
```sh
7+
export SECRET_KEY_BASE=`rake secret`
8+
alias test-prod='rake assets:clobber && RAILS_ENV=production bin/rake assets:precompile \
9+
&& rails s -e production'
10+
```

lib/tasks/assets.rake

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@ namespace :assets do
1515
task :webpack do
1616
sh "cd client && npm run build:client"
1717
sh "cd client && npm run build:server"
18+
sh "mkdir -p public/assets"
19+
20+
# Critical to manually copy non js/css assets to public/assets as we don't want to fingerprint them
21+
sh "cp -rf app/assets/webpack/*.woff* app/assets/webpack/*.svg app/assets/webpack/*.ttf "\
22+
"app/assets/webpack/*.eot* public/assets"
23+
24+
# TODO: We should be gzipping these
1825
end
1926

2027
task :clobber do
21-
rm_rf "#{Rails.application.config.root}/app/assets/javascripts/generated/client-bundle.js"
22-
rm_rf "#{Rails.application.config.root}/app/assets/javascripts/generated/server-bundle.js"
28+
rm_rf "#{Rails.application.config.root}/app/assets/webpack"
2329
end
2430
end

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@
1111
"postinstall": "cd client && npm install",
1212
"test": "rspec && npm run test:client && npm run lint",
1313
"test:client": "(cd client && npm run test --silent)",
14-
"lint": "(cd client && npm run lint --silent)"
14+
"lint": "(cd client && npm run lint --silent)",
15+
"build:clean": "rm app/assets/webpack/*",
16+
"build:client": "(cd client && npm run build:client --silent)",
17+
"build:server": "(cd client && npm run build:server --silent)",
18+
"build:dev:client": "(cd client && npm run build:dev:client --silent)",
19+
"build:dev:server": "(cd client && npm run build:dev:server --silent)",
20+
"build:test:client": "(cd client && npm run build:test:client --silent)"
1521
},
1622
"repository": {
1723
"type": "git",

spec/features/shared/examples.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
include_context "Form Submitted", name: :name, text: :text
99

1010
scenario "comment is added" do
11-
expect(page).to have_css(".comment", text: name)
12-
expect(page).to have_css(".comment", text: text)
11+
expect(page).to have_css(".js-comment-author", text: name)
12+
expect(page).to have_css(".js-comment-text", text: text)
1313
end
1414
end
1515

spec/rails_helper.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
config.before(:suite) do
3838
DatabaseCleaner.strategy = :transaction
3939
DatabaseCleaner.clean_with :truncation
40+
41+
# Next line will ensure that assets are built if webpack -w is not running
42+
EnsureAssetsCompiled.check_built_assets
4043
end
4144

4245
config.around(:each) do |example|
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# 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
7+
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
13+
end
14+
end
15+
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."
23+
end
24+
end
25+
end
26+
27+
def self.build_all_assets
28+
build_assets_for_type("client")
29+
build_assets_for_type("server")
30+
@checked_built_assets = true
31+
end
32+
end

0 commit comments

Comments
 (0)