Skip to content

Commit

Permalink
Fix symlink issues
Browse files Browse the repository at this point in the history
  • Loading branch information
robwise committed Nov 3, 2015
1 parent c20dfcc commit 3224d05
Show file tree
Hide file tree
Showing 24 changed files with 148 additions and 67 deletions.
31 changes: 31 additions & 0 deletions docs/gen-notes/reducers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Reducers
Documentation of generated Redux code for reducers.

## Example
The `helloWorld/reducers/index.jsx` example that results from running the generator with the Redux option may be slightly confusing because of its simplicity. For clarity, what follows is a more fleshed-out example of what a reducer might look like:

```javascript
import usersReducer from './usersReducer';
import blogPostsReducer from './blogPostsReducer';
import commentsReducer from './commentsReducer';
// ...

import { $$initialState as $$usersState } from './usersReducer';
import { $$initialState as $$blogPostsState } from './blogPostsReducer';
import { $$initialState as $$commentsState } from './commentsReducer';
// ...

export default {
$$usersStore: usersReducer,
$$blogPostsStore: blogPostsReducer,
$$commentsStore: commentsReducer,
// ...
};

export const initalStates = {
$$usersState,
$$blogPostsState,
$$commentsState,
// ...
};
```
18 changes: 9 additions & 9 deletions lib/generators/react_on_rails/base_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ def update_git_ignore

def update_application_js
data = <<-DATA.strip_heredoc
// DO NOT REQUIRE jQuery or jQuery-ujs in this file!
// DO NOT REQUIRE TREE!
// It is important that generated/vendor-bundle must be before bootstrap-sprockets
// and turbolinks since it is exposing jQuery and jQuery-ujs.
// DO NOT REQUIRE jQuery or jQuery-ujs in this file!
// DO NOT REQUIRE TREE!
//= require react_on_rails
// CRITICAL that generated/vendor-bundle must be BEFORE bootstrap-sprockets and turbolinks
// since it is exposing jQuery and jQuery-ujs
//= require react_on_rails
//= require generated/vendor-bundle
//= require generated/app-bundle
//= require generated/vendor-bundle
//= require generated/app-bundle
// bootstrap-sprockets depends on generated/vendor-bundle for jQuery.
//= require bootstrap-sprockets
// bootstrap-sprockets depends on generated/vendor-bundle for jQuery.
//= require bootstrap-sprockets
DATA

application_js_path = "app/assets/javascripts/application.js"
Expand Down
14 changes: 6 additions & 8 deletions lib/generators/react_on_rails/bootstrap_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@ class BootstrapGenerator < Rails::Generators::Base
hide!
source_root(File.expand_path("../templates", __FILE__))

def append_to_application_config
config_data = "\n# Add client/assets/stylesheets to asset pipeline's search path.\n"
config_data << 'config.assets.paths << Rails.root.join("client", "assets", "stylesheets")'
config_data << "\n"
application(config_data)
end

def append_to_assets_initializer
data = "Rails.application.config.assets.precompile += %w( generated/server-bundle.js )"
data = <<-DATA.strip_heredoc
# Add client/assets/stylesheets to asset pipeline's search path.
Rails.application.config.assets.paths << Rails.root.join("client", "assets", "stylesheets")
Rails.application.config.assets.precompile += %w( generated/server-bundle.js )
DATA
append_to_file("config/initializers/assets.rb", data)
end

Expand Down
25 changes: 24 additions & 1 deletion lib/generators/react_on_rails/generator_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,30 @@ def keep_file(destination)
# source_root, this symlinks a file in destination_root to a file also in
# destination_root.
def symlink_dest_file_to_dest_file(target, link)
File.symlink(File.join(destination_root, target), File.join(destination_root, link))
# target = "app/assets/fonts"
# link = "client/assets/fonts"
target_pathname = Pathname.new(File.join(destination_root, target))
link_pathname = Pathname.new(File.join(destination_root, link))

link_directory = link_pathname.dirname
link_basename = link_pathname.basename
target_relative_path = target_pathname.relative_path_from(link_directory)

puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
# puts "link: #{link}"
# puts "target: #{target}"
# puts "destination_root: #{destination_root}"
# puts "target_pathname: #{target_pathname}"
# puts "link_pathname: #{link_pathname}"
# puts "link_diretory: #{link_directory}"
# puts "target_basename: #{target_basename}"
# puts "link_basename: #{link_basename}"
# puts "target_directory: #{target_directory}"
# puts "link_relative_path: #{link_relative_path}"
# puts "target_relative_path: #{target_relative_path}"
puts "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"

`cd #{link_directory} && ln -s #{target_relative_path} #{link_basename}`
end

def copy_file_and_missing_parent_directories(source_file, destination_file = nil)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class HelloWorldController < ApplicationController
def index
@hello_world_props = { initialName: "Stranger" }
@hello_world_props = { name: "Stranger" }
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ html
script(src="vendor-bundle.js")
script(src="app-bundle.js")
script.
ReactDOM.render(React.createElement(HelloWorldApp, {initialName: "Stranger"}), document.getElementById('app'))
ReactDOM.render(React.createElement(HelloWorldApp, {name: "Stranger"}), document.getElementById('app'))
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// This config file setups up the Webpack Dev Server: https://webpack.github.io/docs/webpack-dev-server.html
// Run like this:
// cd client && node server.js

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@
ReactOnRails.configure do |config|
# Client bundles are configured in application.js

# Server rendering:
# Server bundle is a single file for all server rendering of components.
# If you wish to use render_js in your views without any file, set this to "" to avoid warnings.
config.server_bundle_js_file = "app/assets/javascripts/generated/server-bundle.js" # This is the default
config.server_renderer_pool_size = 1 # increase if you're on JRuby
config.server_renderer_timeout = 20 # seconds

# For server rendering. This can be set to false so that server side messages are discarded.
config.replay_console = true # Default is true. Be cautious about turning this off.
config.logging_on_server = true # Default is true. Logs server rendering messags to Rails.logger.info

# Below options can be overriden by passing to the helper method.
config.prerender = false # default is false
config.generator_function = false # default is false, meaning that you expose ReactComponents directly
config.trace = Rails.env.development? # default is true for development, off otherwise
config.reload_server_js_every_request = Rails.env.development? # Forces server loaded bundle to reload every js request

# For server rendering. This can be set to false so that server side messages are discarded.
config.replay_console = true # Default is true. Be cautious about turning this off.
config.logging_on_server = true # Default is true. Logs server rendering messags to Rails.logger.info

# Server rendering:
config.server_renderer_pool_size = 1 # increase if you're on JRuby
config.server_renderer_timeout = 20 # seconds
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// The Rails server imports this file via app/assets/stylesheets/application.css.scss
// THe webpack HMR dev server loads this file via client/bootstrap-sass.config.js
// The webpack HMR dev server loads this file via client/bootstrap-sass.config.js

// In either case, this file is loaded AFTER bootstrap has been loaded.
// Use it to apply styles that need to go AFTER bootstrap has loaded

// This is where you can add your own styles and override bootstrap styles
// utilizing bootstrap variables and mixins.
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
// THe webpack HMR dev server loads this file via client/bootstrap-sass.config.js

// In either case, this file is loaded BEFORE bootstrap has been loaded.
// Use it to add your own styles and override bootstrap styles.
// Use it to define variables BEFORE bootstrap loads. See http://getbootstrap.com/customize/
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// The Rails server imports this file via app/assets/stylesheets/application.css.scss
// THe webpack HMR dev server loads this file via client/bootstrap-sass.config.js

// This file is used to facilitate the proper integration of Sass with Rails.
// This file allows the same sass code with Rails and node-sass for the Webpack Dev Server.
// It is CRTICAL that this file is loaded first.

$rails: false !default; // defaults to false (e.g. webpack environment)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,10 @@ module.exports = {
labels: true,
badges: true,

// excluding as an example
jumbotron: true,
thumbnails: true,
alerts: true,

// excluding as an example
'progress-bars': true,
media: true,
'list-group': true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// HelloWorldWidget is an arbitrary name for any "dumb" component. We do not recommend suffixing all your
// dump component names with Widget.

import React, { PropTypes } from 'react';
import Immutable from 'immutable';

// Super simple example of the simplest possible React component
export default class HelloWorldWidget extends React.Component {
static propTypes = {
// We prefix all property and variable names pointing to Immutable.js objects with '$$'.
// This allows us to immediately know we don't call $$helloWorldStore['someProperty'], but instead use
// the Immutable.js `get` API for Immutable.Map
actions: PropTypes.object.isRequired,
$$helloWorldStore: PropTypes.instanceOf(Immutable.Map).isRequired,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// See https://www.npmjs.com/package/mirror-creator
// Allows us to easily setup constants inside of
// client/app/bundles/HelloWorld/actions/helloWorldActionCreators.jsx
import mirrorCreator from 'mirror-creator';

export default mirrorCreator([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,30 @@ import * as helloWorldActionCreators from '../actions/helloWorldActionCreators';

function select(state) {
// Which part of the Redux global state does our component want to receive as props?
// Note the use of `$$`` to prefix the property name because the value is of type Immutable.js
return { $$helloWorldStore: state.$$helloWorldStore };
}

class HelloWorld extends React.Component {
static propTypes = {
dispatch: PropTypes.func.isRequired,

// This corresponds to the value used in function select above.
$$helloWorldStore: PropTypes.instanceOf(Immutable.Map).isRequired,
}

render() {
const { dispatch, $$helloWorldStore } = this.props;
const actions = bindActionCreators(helloWorldActionCreators, dispatch);
return (
<HelloWorldWidget $$helloWorldStore={$$helloWorldStore} actions={actions} />
// This uses the ES2015 spread operator to pass properties
// See http://alexfedoseev.com/post/61/react-component-props-definition-with-es2015-spread-operator
<HelloWorldWidget {...{$$helloWorldStore, actions}} />
);
}
}

// Don't forget to actually use connect!
// Note that we don't export HelloWorld, but the redux "connected" version of it.
// See https://github.com/rackt/react-redux/blob/master/docs/api.md#examples
export default connect(select)(HelloWorld);
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Immutable from 'immutable';
import * as actionTypes from '../constants/helloWorldConstants';

export const $$initialState = Immutable.fromJS({
name: 'CHANGE ME',
name: '', // this is the default state that would be used if one were not passed into the store
});

export default function helloWorldReducer($$state = $$initialState, action) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// This file is our manifest of all reducers for the app.
// See /client/app/bundles/HelloWorld/store/helloWorldStore.jsx
import helloWorldReducer from './helloWorldReducer';
import { $$initialState as $$helloWorldState } from './helloWorldReducer';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ const helloWorldAppClient = props => {
return reactComponent;
};

// Export is needed for the hot reload server
export default helloWorldAppClient;
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { compose, createStore, applyMiddleware, combineReducers } from 'redux';

// See https://github.com/gaearon/redux-thunk and http://redux.js.org/docs/advanced/AsyncActions.html
// This is not actually used for this simple example, but you'd probably want to use this once your app has
// asynchronous actions.
import thunkMiddleware from 'redux-thunk';

// This provides an example of logging redux actions to the console.
// You'd want to disable this for production.
import loggerMiddleware from 'lib/middlewares/loggerMiddleware';

import reducers from '../reducers';
import { initalStates } from '../reducers';

export default props => {
const initialName = props.initialName;
// This is how we get initial props Rails into redux.
const { name } = props;
const { $$helloWorldState } = initalStates;

// Redux expects to initialize the store using an Object, not an Immutable.Map
const initialState = {
$$helloWorldStore: $$helloWorldState.merge({
name: initialName,
name: name,
}),
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint no-console: 0 */
import reduce from 'lodash/collection/reduce';

export default function logger({ getState }) {
return next => action => {
Expand All @@ -9,12 +10,9 @@ export default function logger({ getState }) {

// We can't _read_ immutable objects in console out-of-the-box.
const immutableState = getState();
const readableState = {};
for (const storeItem in immutableState) {
if (immutableState.hasOwnProperty(storeItem)) {
readableState[storeItem] = immutableState[storeItem].toJS();
}
}
const readableState = reduce(immutableState, (result, immutable, key) => {
result[key] = immutable.toJS();
}, {});

console.log('state after dispatch', readableState);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"imports-loader": "^0.6.4",
"jquery": "^2.1.4",
"jquery-ujs": "^1.1.0-1",
"lodash": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"loader-utils": "^0.2.11",
"marked": "^0.3.5",
"mirror-creator": "0.0.1",
Expand Down
2 changes: 1 addition & 1 deletion spec/react_on_rails/support/generator_spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def expect_to_be_symlink(args)
link = File.join(destination_root, args[:link])
expect(File.exist?(link)).to eq true
expect(File.lstat(link).symlink?).to eq true
expect(File.readlink(link)).to eq target
expect(File.readlink(link)).to eq args[:link_value]
end

def assert_directory_with_keep_file(dir)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@
it "symlinks client assets to app assets" do
assert_directory "app/assets/fonts"
assert_directory "app/assets/images"
expect_to_be_symlink(link: "client/assets/fonts", target: "app/assets/fonts")
expect_to_be_symlink(link: "client/assets/images", target: "app/assets/images")
expect_to_be_symlink(link: "client/assets/fonts",
target: "app/assets/fonts",
link_value: "../../app/assets/fonts")
expect_to_be_symlink(link: "client/assets/images",
target: "app/assets/images",
link_value: "../../app/assets/images")
end

it "updates the .gitignore file" do
Expand All @@ -30,20 +34,20 @@

it "updates application.js" do
match = <<-MATCH.strip_heredoc
// DO NOT REQUIRE jQuery or jQuery-ujs in this file!
// DO NOT REQUIRE TREE!
// It is important that generated/vendor-bundle must be before bootstrap-sprockets
// and turbolinks since it is exposing jQuery and jQuery-ujs.
// DO NOT REQUIRE jQuery or jQuery-ujs in this file!
// DO NOT REQUIRE TREE!
//= require react_on_rails
// CRITICAL that generated/vendor-bundle must be BEFORE bootstrap-sprockets and turbolinks
// since it is exposing jQuery and jQuery-ujs
//= require react_on_rails
//= require generated/vendor-bundle
//= require generated/app-bundle
//= require generated/vendor-bundle
//= require generated/app-bundle
// bootstrap-sprockets depends on generated/vendor-bundle for jQuery.
//= require bootstrap-sprockets
// bootstrap-sprockets depends on generated/vendor-bundle for jQuery.
//= require bootstrap-sprockets
//= require turbolinks
//= require turbolinks
MATCH
assert_file("app/assets/javascripts/application.js", match)
Expand Down
Loading

0 comments on commit 3224d05

Please sign in to comment.