react_on_rails 2.0.0.rc.1 → 2.0.0.rc.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc +1 -1
  3. data/.rubocop.yml +1 -1
  4. data/.travis.yml +1 -2
  5. data/CHANGELOG.md +46 -0
  6. data/Gemfile +0 -7
  7. data/README.md +16 -2
  8. data/Rakefile +1 -1
  9. data/docs/additional_reading/manual_installation.md +3 -4
  10. data/lib/generators/react_on_rails/base_generator.rb +12 -6
  11. data/lib/generators/react_on_rails/bootstrap_generator.rb +5 -4
  12. data/lib/generators/react_on_rails/dev_tests_generator.rb +20 -2
  13. data/lib/generators/react_on_rails/generator_helper.rb +8 -5
  14. data/lib/generators/react_on_rails/generator_messages.rb +39 -0
  15. data/lib/generators/react_on_rails/heroku_deployment_generator.rb +3 -3
  16. data/lib/generators/react_on_rails/install_generator.rb +34 -14
  17. data/lib/generators/react_on_rails/js_linters_generator.rb +1 -1
  18. data/lib/generators/react_on_rails/react_no_redux_generator.rb +5 -7
  19. data/lib/generators/react_on_rails/react_with_redux_generator.rb +1 -2
  20. data/lib/generators/react_on_rails/ruby_linters_generator.rb +5 -3
  21. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev-hot.tt +4 -0
  22. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev.tt +0 -1
  23. data/lib/generators/react_on_rails/templates/base/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx.tt +66 -0
  24. data/lib/generators/react_on_rails/templates/base/base/client/package.json.tt +3 -2
  25. data/lib/generators/react_on_rails/templates/base/base/client/server.js +2 -2
  26. data/lib/generators/react_on_rails/templates/base/base/client/{webpack.client.base.config.js.tt → webpack.client.base.config.js} +4 -2
  27. data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.hot.config.js.tt +6 -6
  28. data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.rails.config.js +3 -3
  29. data/lib/generators/react_on_rails/templates/base/base/package.json +4 -1
  30. data/lib/generators/react_on_rails/templates/base/server_rendering/client/webpack.server.rails.config.js +3 -3
  31. data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_post-bootstrap.scss +1 -1
  32. data/lib/generators/react_on_rails/templates/js_linters/client/.eslintrc +1 -1
  33. data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +9 -7
  34. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +6 -1
  35. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/reducers/helloWorldReducer.jsx +4 -4
  36. data/lib/generators/react_on_rails/templates/ruby_linters/{ruby-lint.yml → ruby-lint.yml.tt} +6 -0
  37. data/lib/react_on_rails/version.rb +1 -1
  38. data/package.json +5 -3
  39. data/rakelib/example_type.rb +1 -1
  40. data/rakelib/lint.rake +4 -3
  41. data/react_on_rails.gemspec +12 -2
  42. data/ruby-lint.yml +1 -0
  43. metadata +153 -12
  44. data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx +0 -39
  45. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx +0 -50
@@ -3,7 +3,7 @@ require "rails/generators"
3
3
  module ReactOnRails
4
4
  module Generators
5
5
  class JsLintersGenerator < Rails::Generators::Base
6
- hide!
6
+ Rails::Generators.hide_namespace(namespace)
7
7
  source_root File.expand_path("../templates", __FILE__)
8
8
 
9
9
  # NOTE: linter modules are included via template in base/base/client/package.json.tt
@@ -1,11 +1,11 @@
1
1
  require "rails/generators"
2
- require File.expand_path("../generator_helper", __FILE__)
3
- include GeneratorHelper
2
+ require_relative "generator_helper"
4
3
 
5
4
  module ReactOnRails
6
5
  module Generators
7
6
  class ReactNoReduxGenerator < Rails::Generators::Base
8
- hide!
7
+ include GeneratorHelper
8
+ Rails::Generators.hide_namespace(namespace)
9
9
  source_root(File.expand_path("../templates", __FILE__))
10
10
 
11
11
  # --server-rendering
@@ -17,10 +17,8 @@ module ReactOnRails
17
17
 
18
18
  def copy_base_files
19
19
  base_path = "no_redux/base/"
20
- %w(client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx
21
- client/app/bundles/HelloWorld/containers/HelloWorld.jsx).each do |file|
22
- copy_file(base_path + file, file)
23
- end
20
+ file = "client/app/bundles/HelloWorld/containers/HelloWorld.jsx"
21
+ copy_file(base_path + file, file)
24
22
  end
25
23
 
26
24
  def copy_server_rendering_files_if_appropriate
@@ -3,7 +3,7 @@ require "rails/generators"
3
3
  module ReactOnRails
4
4
  module Generators
5
5
  class ReactWithReduxGenerator < Rails::Generators::Base
6
- hide!
6
+ Rails::Generators.hide_namespace(namespace)
7
7
  source_root(File.expand_path("../templates", __FILE__))
8
8
 
9
9
  # --server-rendering
@@ -23,7 +23,6 @@ module ReactOnRails
23
23
  def copy_base_redux_files
24
24
  base_path = "redux/base/"
25
25
  %w(client/app/bundles/HelloWorld/actions/helloWorldActionCreators.jsx
26
- client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx
27
26
  client/app/bundles/HelloWorld/containers/HelloWorld.jsx
28
27
  client/app/bundles/HelloWorld/constants/helloWorldConstants.jsx
29
28
  client/app/bundles/HelloWorld/reducers/helloWorldReducer.jsx
@@ -1,9 +1,11 @@
1
1
  require "rails/generators"
2
+ require_relative "generator_helper"
2
3
 
3
4
  module ReactOnRails
4
5
  module Generators
5
6
  class RubyLintersGenerator < Rails::Generators::Base
6
- hide!
7
+ include GeneratorHelper
8
+ Rails::Generators.hide_namespace(namespace)
7
9
  source_root File.expand_path("../templates", __FILE__)
8
10
 
9
11
  def add_ruby_linter_gems_to_gemfile
@@ -25,8 +27,8 @@ module ReactOnRails
25
27
  %w(lib/tasks/brakeman.rake
26
28
  lib/tasks/ci.rake
27
29
  .rubocop.yml
28
- .scss-lint.yml
29
- ruby-lint.yml).each { |file| copy_file(base_path + file, file) }
30
+ .scss-lint.yml).each { |file| copy_file(base_path + file, file) }
31
+ template("ruby_linters/ruby-lint.yml.tt", "ruby-lint.yml")
30
32
  end
31
33
  end
32
34
  end
@@ -0,0 +1,4 @@
1
+ web: rails s
2
+ # TODO: MIGRATE from tutorial
3
+ client: sh -c 'rm app/assets/javascripts/generated/* || true && cd client && npm run build:dev:client'
4
+ <%- if options.server_rendering? %>server: sh -c 'cd client && npm run build:dev:server'<%- end %>
@@ -1,4 +1,3 @@
1
1
  web: rails s
2
- hot: sh -c 'cd client && npm start'
3
2
  client: sh -c 'rm app/assets/javascripts/generated/* || true && cd client && npm run build:dev:client'
4
3
  <%- if options.server_rendering? %>server: sh -c 'cd client && npm run build:dev:server'<%- end %>
@@ -0,0 +1,66 @@
1
+ // HelloWorldWidget is an arbitrary name for any "dumb" component. We do not recommend suffixing
2
+ // all your dump component names with Widget.
3
+
4
+ import React, { PropTypes } from 'react';
5
+ import _ from 'lodash';
6
+ <%- unless options.skip_bootstrap? -%>
7
+ import { Input } from 'react-bootstrap';
8
+ <%- end -%>
9
+
10
+ // Simple example of a React "dumb" component
11
+ export default class HelloWorldWidget extends React.Component {
12
+ static propTypes = {
13
+ // If you have lots of data or action properties, you should consider grouping them by
14
+ // passing two properties: "data" and "actions".
15
+ updateName: PropTypes.func.isRequired,
16
+ name: PropTypes.string.isRequired,
17
+ };
18
+
19
+ constructor(props, context) {
20
+ super(props, context);
21
+
22
+ // Uses lodash to bind all methods to the context of the object instance, otherwise
23
+ // the methods defined here would not refer to the component's class, not the component
24
+ // instance itself.
25
+ _.bindAll(this, 'handleChange');
26
+ }
27
+
28
+ // React will automatically provide us with the event `e`
29
+ handleChange(e) {
30
+ const name = e.target.value;
31
+ this.props.updateName(name);
32
+ }
33
+
34
+ render() {
35
+ const { name } = this.props;
36
+ return (
37
+ <div className="container">
38
+ <h3>
39
+ Hello, {name}!
40
+ </h3>
41
+ <hr/>
42
+ <form className="form-horizontal">
43
+ <%- if options.skip_bootstrap? -%>
44
+ <label>
45
+ Say hello to:
46
+ </label>
47
+ <input
48
+ type="text"
49
+ value={name}
50
+ onChange={this.handleChange}
51
+ />
52
+ <%- else -%>
53
+ <Input
54
+ type="text"
55
+ labelClassName="col-sm-2"
56
+ wrapperClassName="col-sm-10"
57
+ label="Say hello to:"
58
+ value={name}
59
+ onChange={this.handleChange}
60
+ />
61
+ <%- end -%>
62
+ </form>
63
+ </div>
64
+ );
65
+ }
66
+ }
@@ -55,8 +55,8 @@
55
55
  "jquery": "^2.1.4",
56
56
  "jquery-ujs": "^1.1.0-1",
57
57
  "loader-utils": "^0.2.11",
58
- <%- if options.redux? -%>
59
58
  "lodash": "^3.10.1",
59
+ <%- if options.redux? -%>
60
60
  "mirror-creator": "0.0.1",
61
61
  <%- end -%>
62
62
  "react": "^0.14.3",
@@ -86,13 +86,14 @@
86
86
  <%- unless options.skip_js_linters? -%>
87
87
  "eslint": "^1.10.3",
88
88
  "eslint-config-airbnb": "^2.0.0",
89
+ "eslint-config-shakacode": "^0.0.1",
89
90
  "eslint-plugin-react": "^3.11.3",
90
91
  <%- end -%>
91
92
  "express": "^4.13.3",
92
93
  "file-loader": "^0.8.4",
93
94
  "jade": "^1.11.0",
94
95
  <%- unless options.skip_js_linters? -%>
95
- "jscs": "^2.7.0",
96
+ "jscs": "^2.8.0",
96
97
  <%- end -%>
97
98
  "node-sass": "^3.4.2",
98
99
  "react-transform-hmr": "^1.0.1",
@@ -49,7 +49,7 @@ var server = new WebpackDevServer(webpack(config), {
49
49
 
50
50
  var initialName = 'Stranger';
51
51
 
52
- server.app.use('/', function(req, res) {
52
+ server.app.use('/', function routePath(req, res) {
53
53
  var locals = {
54
54
  props: JSON.stringify(initialName),
55
55
  };
@@ -58,7 +58,7 @@ server.app.use('/', function(req, res) {
58
58
  res.send(html);
59
59
  });
60
60
 
61
- server.listen(4000, 'localhost', function(err) {
61
+ server.listen(4000, 'localhost', function onListen(err) {
62
62
  if (err) console.log(err);
63
63
  console.log('Listening at localhost:4000...');
64
64
  });
@@ -16,6 +16,8 @@ module.exports = {
16
16
  vendor: [
17
17
  'babel-polyfill',
18
18
  'jquery',
19
+ 'react',
20
+ 'react-dom',
19
21
  ],
20
22
 
21
23
  // This will contain the app entry points defined by webpack.hot.config and webpack.rails.config
@@ -57,8 +59,8 @@ module.exports = {
57
59
  loaders: [
58
60
 
59
61
  // Not all apps require jQuery. Many Rails apps do, such as those using TurboLinks or bootstrap js
60
- {test: require.resolve('jquery'), loader: 'expose?jQuery'},
61
- {test: require.resolve('jquery'), loader: 'expose?$'},
62
+ { test: require.resolve('jquery'), loader: 'expose?jQuery' },
63
+ { test: require.resolve('jquery'), loader: 'expose?$' },
62
64
  ],
63
65
  },
64
66
  };
@@ -51,7 +51,7 @@ config.module.loaders.push(
51
51
  ],
52
52
  },
53
53
  },
54
- {test: /\.css$/, loader: 'style-loader!css-loader'},
54
+ { test: /\.css$/, loader: 'style-loader!css-loader' },
55
55
  {
56
56
  test: /\.scss$/,
57
57
  loader: 'style!css!sass?outputStyle=expanded&imagePath=/assets/images&includePaths[]=' +
@@ -59,11 +59,11 @@ config.module.loaders.push(
59
59
  },
60
60
 
61
61
  // The url-loader uses DataUrls. The file-loader emits files.
62
- {test: /\.woff$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'},
63
- {test: /\.woff2$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff'},
64
- {test: /\.ttf$/, loader: 'file-loader'},
65
- {test: /\.eot$/, loader: 'file-loader'},
66
- {test: /\.svg$/, loader: 'file-loader'}
62
+ { test: /\.woff$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
63
+ { test: /\.woff2$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
64
+ { test: /\.ttf$/, loader: 'file-loader' },
65
+ { test: /\.eot$/, loader: 'file-loader' },
66
+ { test: /\.svg$/, loader: 'file-loader' }
67
67
  );
68
68
 
69
69
  module.exports = config;
@@ -20,13 +20,13 @@ config.entry.vendor.unshift(
20
20
  'es5-shim/es5-sham'
21
21
  );
22
22
 
23
+ // jquery-ujs MUST GO AFTER jquery, so must use 'push'
23
24
  config.entry.vendor.push('jquery-ujs');
24
25
 
25
26
  // See webpack.common.config for adding modules common to both the webpack dev server and rails
26
-
27
27
  config.module.loaders.push(
28
- {test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/},
29
- {test: require.resolve('react'), loader: 'imports?shim=es5-shim/es5-shim&sham=es5-shim/es5-sham'}
28
+ { test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/ },
29
+ { test: require.resolve('react'), loader: 'imports?shim=es5-shim/es5-shim&sham=es5-shim/es5-sham' }
30
30
  );
31
31
 
32
32
  module.exports = config;
@@ -9,7 +9,10 @@
9
9
  },
10
10
  "scripts": {
11
11
  "postinstall": "cd client && npm install",
12
- "test": "rspec && (cd client && npm run lint)"
12
+ "test": "rspec && (cd client && npm run lint)",
13
+ "node-server-hot": "cd client && npm start",
14
+ "rails-server-hot": "foreman start -f Procfile.dev-hot",
15
+ "rails-server": "foreman start -f Procfile.dev"
13
16
  },
14
17
  "repository": {
15
18
  "type": "git",
@@ -12,7 +12,7 @@ module.exports = {
12
12
  context: __dirname,
13
13
  entry: [
14
14
  'babel-polyfill',
15
- './app/bundles/HelloWorld/startup/serverRegistration'
15
+ './app/bundles/HelloWorld/startup/serverRegistration',
16
16
  ],
17
17
  output: {
18
18
  filename: 'server-bundle.js',
@@ -27,13 +27,13 @@ module.exports = {
27
27
  plugins: [
28
28
  new webpack.DefinePlugin({
29
29
  'process.env': {
30
- NODE_ENV: JSON.stringify('production'),
30
+ NODE_ENV: JSON.stringify(nodeEnv),
31
31
  },
32
32
  }),
33
33
  ],
34
34
  module: {
35
35
  loaders: [
36
- {test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/},
36
+ { test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/ },
37
37
  ],
38
38
  },
39
39
  };
@@ -6,5 +6,5 @@
6
6
  // utilizing bootstrap variables and mixins.
7
7
 
8
8
  .this-works {
9
- color: orange !important;
9
+ color: orange;
10
10
  }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  parser: babel-eslint
3
3
 
4
- extends: eslint-config-airbnb
4
+ extends: eslint-config-shakacode
5
5
 
6
6
  plugins:
7
7
  - react
@@ -6,27 +6,29 @@ import _ from 'lodash';
6
6
  export default class HelloWorld extends React.Component {
7
7
  static propTypes = {
8
8
  name: PropTypes.string.isRequired, // this is passed from the Rails view
9
- }
9
+ };
10
10
 
11
11
  constructor(props, context) {
12
12
  super(props, context);
13
13
 
14
+ // How to set initial state in ES6 class syntax
15
+ // https://facebook.github.io/react/docs/reusable-components.html#es6-classes
16
+ this.state = { name: this.props.name };
17
+
14
18
  // Uses lodash to bind all methods to the context of the object instance, otherwise
15
19
  // the methods defined here would not refer to the component's class, not the component
16
20
  // instance itself.
17
- _.bindAll(this, '_updateName');
21
+ _.bindAll(this, 'updateName');
18
22
  }
19
23
 
20
- state = {name: this.props.name} // how to set initial state in es2015 class syntax
21
-
22
- _updateName(name) {
23
- this.setState({name: name});
24
+ updateName(name) {
25
+ this.setState({ name });
24
26
  }
25
27
 
26
28
  render() {
27
29
  return (
28
30
  <div>
29
- <HelloWorldWidget name={this.state.name} _updateName={this._updateName} />
31
+ <HelloWorldWidget name={this.state.name} updateName={this.updateName} />
30
32
  </div>
31
33
  );
32
34
  }
@@ -17,6 +17,9 @@ class HelloWorld extends React.Component {
17
17
  dispatch: PropTypes.func.isRequired,
18
18
 
19
19
  // This corresponds to the value used in function select above.
20
+ // We prefix all property and variable names pointing to Immutable.js objects with '$$'.
21
+ // This allows us to immediately know we don't call $$helloWorldStore['someProperty'], but
22
+ // instead use the Immutable.js `get` API for Immutable.Map
20
23
  $$helloWorldStore: PropTypes.instanceOf(Immutable.Map).isRequired,
21
24
  };
22
25
 
@@ -27,12 +30,14 @@ class HelloWorld extends React.Component {
27
30
  render() {
28
31
  const { dispatch, $$helloWorldStore } = this.props;
29
32
  const actions = bindActionCreators(helloWorldActionCreators, dispatch);
33
+ const { updateName } = actions;
34
+ const name = $$helloWorldStore.get('name');
30
35
 
31
36
  // This uses the ES2015 spread operator to pass properties as it is more DRY
32
37
  // This is equivalent to:
33
38
  // <HelloWorldWidget $$helloWorldStore={$$helloWorldStore} actions={actions} />
34
39
  return (
35
- <HelloWorldWidget {...{ $$helloWorldStore, actions }} />
40
+ <HelloWorldWidget {...{ updateName, name }} />
36
41
  );
37
42
  }
38
43
  }
@@ -10,10 +10,10 @@ export default function helloWorldReducer($$state = $$initialState, action) {
10
10
  const { type, name } = action;
11
11
 
12
12
  switch (type) {
13
- case actionTypes.HELLO_WORLD_NAME_UPDATE:
14
- return $$state.set('name', name);
13
+ case actionTypes.HELLO_WORLD_NAME_UPDATE:
14
+ return $$state.set('name', name);
15
15
 
16
- default:
17
- return $$state;
16
+ default:
17
+ return $$state;
18
18
  }
19
19
  }
@@ -1,9 +1,15 @@
1
+ # Not currently using ruby-lint
2
+ ---
1
3
  presenter: syntastic
2
4
 
5
+ # Be sure to edit this per your project!
3
6
  directories:
4
7
  - app
5
8
  - config
9
+ - lib
10
+ <%- if dest_dir_exists?("spec") -%>
6
11
  - spec
12
+ <%- end -%>
7
13
 
8
14
  ignore_paths:
9
15
  - client
@@ -1,3 +1,3 @@
1
1
  module ReactOnRails
2
- VERSION = "2.0.0.rc.1"
2
+ VERSION = "2.0.0.rc.3"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-on-rails",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-rc.1",
4
4
  "description": "react-on-rails JavaScript for react_on_rails Ruby gem",
5
5
  "main": "node_package/lib/ReactOnRails.js",
6
6
  "directories": {
@@ -11,7 +11,7 @@
11
11
  "babel": "^6.3.13",
12
12
  "babel-cli": "^6.3.17",
13
13
  "babel-core": "^6.3.17",
14
- "babel-eslint": "^5.0.0-beta4",
14
+ "babel-eslint": "^5.0.0-beta6",
15
15
  "babel-loader": "^6.2.0",
16
16
  "babel-plugin-transform-runtime": "^6.3.13",
17
17
  "babel-preset-es2015": "^6.3.13",
@@ -22,12 +22,14 @@
22
22
  "babelify": "^7.2.0",
23
23
  "blue-tape": "^0.1.11",
24
24
  "eslint": "^1.10.3",
25
- "eslint-config-airbnb": "^2.0.0",
25
+ "eslint-config-airbnb": "^2.1.1",
26
+ "eslint-config-shakacode": "0.0.1",
26
27
  "eslint-plugin-babel": "^3.0.0",
27
28
  "eslint-plugin-react": "^3.11.3",
28
29
  "jscs": "^2.6.0",
29
30
  "react": "^0.14.3",
30
31
  "react-dom": "^0.14.3",
32
+ "react-transform-hmr": "^1.0.1",
31
33
  "tap-spec": "^4.1.1",
32
34
  "tape": "^4.4.0",
33
35
  "webpack": "^1.12.9"