Skip to content

Commit

Permalink
Numerous fixes, some with deprecations
Browse files Browse the repository at this point in the history
* Change generators to use app/assets/webpack as the generation
  directory might contain CSS.
* Numerous improvements in the verification that the webpack created
  assets are up to date before running tests.
* Several new configuration options and changes to the configuration:
  # Directory where your generated assets go
  config.generated_assets_dir = File.join(%w(app assets webpack))

  # Define the files for we need to check for webpack compilation when running tests
  config.webpack_generated_files = %w( app-bundle.js vendor-bundle.js server-bundle.js )

* config.server_bundle_js_file no longer uses a path, as it can only
  exist in the generated_assets_dir.
* redux_store view helper now requires the props to be specified as a
  named parameter, an it takes an option `defer` to allow rendering at
  the bottom of the layout.
  • Loading branch information
justin808 committed Mar 14, 2016
1 parent 2483309 commit 07054c8
Show file tree
Hide file tree
Showing 55 changed files with 674 additions and 271 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
*.gem
/vendor/

/spec/examples.txt
/spec/dummy/client/node_modules
/spec/dummy/app/assets/javascripts/generated/
/spec/dummy/app/assets/webpack/
/spec/dummy/coverage/
/spec/react_on_rails/dummy-for-generators/

Expand Down
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
# Check out: https://github.com/bbatsov/rubocop

AllCops:
TargetRubyVersion: 2.1

Include:
- '**/Rakefile'
- '**/config.ru'

Exclude:
- 'vendor/**/*'
- 'spec/fixtures/**/*'
Expand Down
14 changes: 10 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@ Contributors: please follow the recommendations outlined at [keepachangelog.com]
## [4.0.0.rc.1] - 2016-03-06
##### Added
- Added controller `module ReactOnRails::Controller`. Adds method `redux_store` to setup redux stores in the view.
- Added option `defer: true` for view helper `redux_store`. This allows the view helper to specify the props for store hydration, yet still render the props at the bottom of the view.
- Added view helper `redux_store_hydration_data` to render the props on the application's layout, near the bottom. This allows for the client hydration data to be parsed after the server rendering, which may result in a faster load time.
- Added helpers `env_stylesheet_link_tag` and `env_javascript_include_tag` to support hot reloading Rails. See the [README.md](./README.md) for more details and see the example application in `spec/dummy`.
- The checker for outdated bundles before running tests will default to including the directory with `server_bundle_js_file`.
- Better support for Turbolinks 5!
- Fixed generator check of uncommitted code for foreign languages. See [#303](https://github.com/shakacode/react_on_rails/pull/303) by [nmatyukov](https://github.com/nmatyukov).

- Added several parameters used for ensuring webpack assets are built for running tests:
- `config.generated_assets_dir`: Directory where your generated webpack assets go. You can have only **one** directory for this.
- `config.webpack_generated_files`: List of files that will get created in the `generated_assets_dir`. The test runner helper will ensure these generated files are newer than any of the files in the client directory.
##### Changed
- Generator default for webpack generated assets is now `app/assets/webpack` as we use this for both JavaScript and CSS generated assets.
##### Fixed
- The test runner assets up to date checker might see only the server rendering file, and assume that all assets are up to date.
- The test runner assets up to date checker is greatly improved.
- Lots of doc updates!
- Improved the **spec/dummy** sample app so that it supports CSS modules, hot reloading, etc, and it can server as a template for a new ReactOnRails installation.

##### Breaking Changes
- Deprecated `redux_store` called from views. Call this method from your controller actions and place `redux_store_hydration_data` on your layout, near the bottom.
- Removed the config default of the `config.server_bundle_js_file`. The default is blank, meaning no server rendering.
- Deprecated calling `redux_store(store_name, props)`. The API has changed. Use `redux_store(store_name, props: props, defer: false)` A new option called `defer` allows the rendering of store hydration at the bottom of the your layout. Place `redux_store_hydration_data` on your layout.
- `config.server_bundle_js_file` has changed. The default value is now blank, meaning no server rendering. Addtionally, if you specify the file name, you should not include the path, as that should be specified in the `config.generated_assets_dir`.
- `config.generated_assets_dirs` has been renamed to `config.generated_assets_dir` (singular) and it only takes one directory.


## [3.0.6] - 2016-03-01
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ cd client && npm i --saveDev react-on-rails
That will install the latest version and update your package.json.
## How it Works
The generator installs your webpack files in the `client` folder. Foreman uses webpack to compile your code and output the bundled results to `app/assets/javascripts/generated`, which are then loaded by sprockets. These generated bundle files have been added to your `.gitignore` for your convenience.
The generator installs your webpack files in the `client` folder. Foreman uses webpack to compile your code and output the bundled results to `app/assets/webpack`, which are then loaded by sprockets. These generated bundle files have been added to your `.gitignore` for your convenience.
Inside your Rails views, you can now use the `react_component` helper method provided by React on Rails. You can pass props directly to the react component helper. You can also initialize a Redux store with view helper `redux_store` so that the store can be shared amongst multiple React components. Your best bet is to scan the code inside of the [/spec/dummy](spec/dummy) sample app.
Expand Down Expand Up @@ -224,7 +224,7 @@ Place your JavaScript code inside of the provided `client/app` folder. Use modul
In general, you may want different initialization for your server rendered components.
## ReactOnRails View Helpers API
Once the bundled files have been generated in your `app/assets/javascripts/generated` folder and you have exposed your components globally, you will want to run your code in your Rails views using the included helper method.
Once the bundled files have been generated in your `app/assets/webpack` folder and you have exposed your components globally, you will want to run your code in your Rails views using the included helper method.
This is how you actually render the React components you exposed to `window` inside of `clientRegistration` (and `global` inside of `serverRegistration` if you are server rendering).
Expand Down Expand Up @@ -576,6 +576,11 @@ Note: If you have components from react-rails you want to use, then you will nee
foreman start
```
## Dependencies
+ Ruby 2.1 or greater
+ Rails 3.2 or greater
+ Node 5.5 or great
## Contributing
Bug reports and pull requests are welcome. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to our version of the [Contributor Covenant Code of Conduct](docs/code_of_conduct.md)).
Expand Down
3 changes: 3 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ Coveralls::RakeTask.new

desc "Run all tests and linting"
task default: ["run_rspec", "lint", "coveralls:push"]

desc "All actions but no examples. Good for local developer run."
task all_but_examples: ["run_rspec:all_but_examples", "lint"]
31 changes: 17 additions & 14 deletions app/helpers/react_on_rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,27 @@ def react_component(component_name, options = {}, other_options = nil)
HTML
end

# Deprecated: Use `redux_store` via including ReactOnRails::Controller in your controller and calling
# redux_store.
#
# Separate initialization of store from react_component allows multiple react_component calls to
# use the same Redux store.
#
# store_name: name of the store, corresponding to your call to ReactOnRails.registerStores in your
# JavaScript code.
# props: Ruby Hash or JSON string which contains the properties to pass to the redux store.
def redux_store(store_name, props = {})
warn "[DEPRECATION] `redux_store` within a view is deprecated. Please move to call "\
"to redux store to your controller action."
# Options
# defer: false -- pass as true if you wish to render this below your component.
def redux_store(store_name, props: {}, defer: false)
redux_store_data = { store_name: store_name,
props: props }
@registered_stores ||= []
@registered_stores << redux_store_data

render_redux_store_data(redux_store_data)
if defer
@registered_stores_defer_render ||= []
@registered_stores_defer_render << redux_store_data
"YOU SHOULD NOT SEE THIS ON YOUR VIEW -- Uses as a code block, like <% redux_store %> "\
"and not <%= redux store %>"
else
@registered_stores ||= []
@registered_stores << redux_store_data
render_redux_store_data(redux_store_data)
end
end

# Place this view helper (no parameters) at the end of your shared layout. This tell
Expand All @@ -172,8 +175,8 @@ def redux_store(store_name, props = {})
# client side rendering of this hydration data, which is a hidden div with a matching class
# that contains a data props.
def redux_store_hydration_data
return if @registered_stores_via_controller.blank?
@registered_stores_via_controller.reduce("") do |accum, redux_store_data|
return if @registered_stores_defer_render.blank?
@registered_stores_defer_render.reduce("") do |accum, redux_store_data|
accum << render_redux_store_data(redux_store_data)
end.html_safe
end
Expand Down Expand Up @@ -300,10 +303,10 @@ def server_rendered_react_component_html(options, props, react_component_name, d
end

def initialize_redux_stores
return "" unless @registered_stores.present? || @registered_stores_via_controller.present?
return "" unless @registered_stores.present? || @registered_stores_defer_render.present?
declarations = "var reduxProps, store, storeGenerator;\n"

all_stores = (@registered_stores || []) + (@registered_stores_via_controller || [])
all_stores = (@registered_stores || []) + (@registered_stores_defer_render || [])

result = all_stores.each_with_object(declarations) do |redux_store_data, memo|
store_name = redux_store_data[:store_name]
Expand Down
4 changes: 2 additions & 2 deletions docs/additional_reading/manual_installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ See the next section for a sample webpack.server.rails.config.js.
```javascript
entry: ['./app/startup/serverRegistration'],
```
3. Ensure the name of your ouput file (shown [here](https://github.com/shakacode/react-webpack-rails-tutorial/blob/537c985dc82faee333d80509343ca32a3965f9dd/client/webpack.server.rails.config.js#L9)) of your server bundle corresponds to the configuration of the gem. The default path is `app/assets/javascripts/generated`. See below for customization of configuration variables.
3. Ensure the name of your ouput file (shown [here](https://github.com/shakacode/react-webpack-rails-tutorial/blob/537c985dc82faee333d80509343ca32a3965f9dd/client/webpack.server.rails.config.js#L9)) of your server bundle corresponds to the configuration of the gem. The default path is `app/assets/webpack`. See below for customization of configuration variables.
4. Expose `React` in your webpack config, like [this](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/webpack.server.rails.build.config.js#L54-L55)
```javascript
Expand All @@ -65,7 +65,7 @@ module.exports = {
entry: ['./app/startup/serverRegistration'],
output: {
filename: 'server-bundle.js',
path: '../app/assets/javascripts/generated',
path: '../app/assets/webpack',

// CRITICAL to set libraryTarget: 'this' for enabling Rails to find the exposed modules IF you
// use the "expose" webpackfunctionality. See startup/serverRegistration.jsx.
Expand Down
2 changes: 1 addition & 1 deletion docs/additional_reading/optional_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ReactOnRails.configure do |config|
# Client bundles are configured in application.js
# Server bundle is a single file for all server rendering of components.
# Set the server_bundle_js_file to "" if you know that you will not be server rendering.
config.server_bundle_js_file = "app/assets/javascripts/generated/server.js" # This is the default
config.server_bundle_js_file = "server-bundle.js" # This is the default

# Below options can be overriden by passing to the helper method.
config.prerender = false # default is false
Expand Down
4 changes: 3 additions & 1 deletion docs/additional_reading/rspec_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ You can pass an RSpec metatag as an optional second parameter to this helper met

Please take note of the following:
- This utility assumes your build tasks for the static generated files are `npm run build:client` and `npm run build:server` and do not have the `--watch` option enabled.
- By default, the webpack processes look for the `app/assets/javascripts/generated` and `app/assets/stylesheets/generated` folders. If these folders are missing, are empty, or contain files with `mtime`s older than any of the files in your `client` folder, the helper will recompile your assets. You can override this inside of `config/initializers/react_on_rails.rb` by passing an array of filepaths (relative to the root of the app) to the `generated_assets_dirs` configuration option.
- By default, the webpack processes look for the `app/assets/webpack` folders. If this folder is missing, is empty, or contains files with `mtime`s older than any of the files in your `client` folder, the helper will recompile your assets. You can override this inside of `config/initializers/react_on_rails.rb` by passing a filepath (relative to the root of the app) to the `generated_assets_dir` configuration option.

If you want to speed up the re-compiling process, you can call `npm run build:dev:client` (and `npm run build:dev:server` if doing server rendering) to have webpack run in "watch" mode and recompile these files in the background, which will be much faster when making incremental changes than compiling from scratch.

[spec/dummy](../../spec/dummy) contains examples of how to set the proc files for this purpose.

If you want to use a testing framework other than RSpec, please submit let us know on the changes you need to do and we'll update the docs.

![2016-01-27_02-36-43](https://cloud.githubusercontent.com/assets/1118459/12611951/7c56d070-c4a4-11e5-8a80-9615f99960d9.png)
Expand Down
2 changes: 1 addition & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ It's critical to configure your IDE/editor to ignore certain directories. Otherw
* /gen-examples
* /node_package/lib
* /node_modules
* /spec/dummy/app/assets/javascripts/generated
* /spec/dummy/app/assets/webpack
* /spec/dummy/log
* /spec/dummy/node_modules
* /spec/dummy/tmp
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Completed all linting

It's super important to exclude certain directories from RubyMine or else it will slow to a crawl as it tries to parse all the npm files.

* `app/assets/javascripts/generated`
* `app/assets/webpack`
* `client/node_modules`

<img src="http://forum.shakacode.com/uploads/default/original/1X/a1b3e1146d86915f7d5d1c89548e81ec208458cc.png" width="338" height="500">
Expand Down
11 changes: 7 additions & 4 deletions lib/generators/react_on_rails/base_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def update_git_ignore
node_modules
# Generated js bundles
/app/assets/javascripts/generated/*
/app/assets/webpack/*
DATA

if dest_file_exists?(".gitignore")
Expand All @@ -74,11 +74,11 @@ def update_application_js
// DO NOT REQUIRE jQuery or jQuery-ujs in this file!
// DO NOT REQUIRE TREE!
// CRITICAL that generated/vendor-bundle must be BEFORE bootstrap-sprockets and turbolinks
// CRITICAL that vendor-bundle must be BEFORE bootstrap-sprockets and turbolinks
// since it is exposing jQuery and jQuery-ujs
//= require generated/vendor-bundle
//= require generated/app-bundle
//= require vendor-bundle
//= require app-bundle
DATA

Expand Down Expand Up @@ -171,6 +171,9 @@ def append_to_assets_initializer
Rails.application.config.assets.paths << Rails.root.join("client", "assets", "images")
Rails.application.config.assets.paths << Rails.root.join("client", "assets", "fonts")
Rails.application.config.assets.precompile += %w( generated/server-bundle.js )
# Add folder with webpack generated assets to assets.paths
Rails.application.config.assets.paths << Rails.root.join("app", "assets", "webpack")
DATA
assets_intializer = File.join(destination_root, "config/initializers/assets.rb")
if File.exist?(assets_intializer)
Expand Down
2 changes: 1 addition & 1 deletion lib/generators/react_on_rails/bootstrap_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def add_bootstrap_sprockets_to_gemfile
def add_bootstrap_sprockets_to_application_js
data = <<-DATA.strip_heredoc
// bootstrap-sprockets depends on generated/vendor-bundle for jQuery.
// bootstrap-sprockets depends on vendor-bundle for jQuery.
//= require bootstrap-sprockets
DATA
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
web: rails s
# TODO: MIGRATE from tutorial
client: sh -c 'rm app/assets/javascripts/generated/* || true && cd client && npm run build:dev:client'
client: sh -c 'rm app/assets/webpack/* || true && cd client && npm run build:dev:client'
<%- if options.server_rendering? %>server: sh -c 'cd client && npm run build:dev:server'<%- end %>
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
web: rails s
client: sh -c 'rm app/assets/javascripts/generated/* || true && cd client && npm run build:dev:client'
client: sh -c 'rm app/assets/webpack/* || true && cd client && npm run build:dev:client'
<%- if options.server_rendering? %>server: sh -c 'cd client && npm run build:dev:server'<%- end %>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const devBuild = process.env.NODE_ENV !== 'production';

config.output = {
filename: '[name]-bundle.js',
path: '../app/assets/javascripts/generated',
path: '../app/assets/webpack',
};

// You can add entry points specific to rails here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@
ReactOnRails.configure do |config|
# Client bundles are configured in application.js

# Directory where your generated assets go
config.generated_assets_dir = File.join(%w(app assets webpack))

# Define the files for we need to check for webpack compilation when running tests
<%- if options.server_rendering? %>
config.webpack_generated_files = %w( client-bundle.js server-bundle.js )
<% else %>
config.webpack_generated_files = %w( client-bundle.js )
<%- end %>

# Server rendering:
# Server bundle is a single file for all server rendering of components.
# Set the server_bundle_js_file to "" if you know that you will not be server rendering.
<%- if options.server_rendering? %>
config.server_bundle_js_file = "app/assets/javascripts/generated/server-bundle.js"
config.server_bundle_js_file = "server-bundle.js"
<% else %>
config.server_bundle_js_file = ""
<%- end %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ namespace :assets do
end

task :clobber do
rm_r Dir.glob(Rails.root.join("app/assets/javascripts/generated/*"))
rm_r Dir.glob(Rails.root.join("app/assets/webpack/*"))
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports = {
],
output: {
filename: 'server-bundle.js',
path: '../app/assets/javascripts/generated',
path: '../app/assets/webpack',
},
resolve: {
extensions: ['', '.js', '.jsx'],
Expand Down
Loading

0 comments on commit 07054c8

Please sign in to comment.