react_on_rails 1.0.0.pre → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +2 -0
  3. data/.eslintignore +2 -0
  4. data/.eslintrc +1 -0
  5. data/.gitignore +4 -0
  6. data/.jscsrc +2 -2
  7. data/.rubocop.yml +2 -0
  8. data/.scss-lint.yml +3 -3
  9. data/.travis.yml +31 -18
  10. data/Dockerfile_ci +12 -0
  11. data/Dockerfile_tests +12 -0
  12. data/{LICENSE.txt → LICENSE} +0 -0
  13. data/README.md +170 -290
  14. data/Rakefile +20 -7
  15. data/app/helpers/react_on_rails_helper.rb +5 -5
  16. data/docker-compose.yml +12 -0
  17. data/docs/Contributing.md +26 -2
  18. data/docs/gen-notes/react_syntax.md +3 -0
  19. data/docs/gen-notes/reducers.md +31 -0
  20. data/docs/generator_testing_script.md +50 -0
  21. data/docs/linters.md +8 -0
  22. data/docs/manual_configuration.md +202 -0
  23. data/docs/node_dependencies_and_npm.md +29 -0
  24. data/lib/generators/react_on_rails/base_generator.rb +116 -0
  25. data/lib/generators/react_on_rails/bootstrap_generator.rb +84 -0
  26. data/lib/generators/react_on_rails/generator_helper.rb +48 -0
  27. data/lib/generators/react_on_rails/heroku_deployment_generator.rb +22 -0
  28. data/lib/generators/react_on_rails/install_generator.rb +86 -0
  29. data/lib/generators/react_on_rails/linters_generator.rb +38 -0
  30. data/lib/generators/react_on_rails/react_no_redux_generator.rb +37 -0
  31. data/lib/generators/react_on_rails/react_with_redux_generator.rb +61 -0
  32. data/lib/generators/react_on_rails/templates/base/base/Procfile.dev.tt +4 -0
  33. data/lib/generators/react_on_rails/templates/base/base/REACT_ON_RAILS.md +16 -0
  34. data/lib/generators/react_on_rails/templates/base/base/app/controllers/hello_world_controller.rb +5 -0
  35. data/lib/generators/react_on_rails/templates/base/base/app/views/hello_world/index.html.erb.tt +6 -0
  36. data/lib/generators/react_on_rails/templates/base/base/client/.babelrc +3 -0
  37. data/lib/generators/react_on_rails/templates/base/base/client/REACT_ON_RAILS_CLIENT_README.md +3 -0
  38. data/lib/generators/react_on_rails/templates/base/base/client/app/bundles/HelloWorld/startup/clientGlobals.jsx +4 -0
  39. data/lib/generators/react_on_rails/templates/base/base/client/index.jade +15 -0
  40. data/lib/generators/react_on_rails/templates/base/base/client/npm-shrinkwrap.json +2907 -0
  41. data/lib/generators/react_on_rails/templates/base/base/client/server.js +58 -0
  42. data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.base.config.js +58 -0
  43. data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.hot.config.js +65 -0
  44. data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.rails.config.js +45 -0
  45. data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +30 -0
  46. data/lib/generators/react_on_rails/templates/base/base/lib/tasks/assets.rake +26 -0
  47. data/lib/generators/react_on_rails/templates/base/base/package.json +31 -0
  48. data/lib/generators/react_on_rails/templates/base/server_rendering/client/app/bundles/HelloWorld/startup/serverGlobals.jsx +3 -0
  49. data/lib/generators/react_on_rails/templates/base/server_rendering/client/webpack.server.rails.config.js +37 -0
  50. data/lib/generators/react_on_rails/templates/bootstrap/app/assets/stylesheets/_bootstrap-custom.scss +63 -0
  51. data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_post-bootstrap.scss +10 -0
  52. data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_pre-bootstrap.scss +8 -0
  53. data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_react-on-rails-sass-helper.scss +19 -0
  54. data/lib/generators/react_on_rails/templates/bootstrap/client/bootstrap-sass.config.js +89 -0
  55. data/lib/generators/react_on_rails/templates/client/README.md +97 -0
  56. data/lib/generators/react_on_rails/templates/heroku_deployment/.buildpacks +2 -0
  57. data/lib/generators/react_on_rails/templates/heroku_deployment/Procfile +1 -0
  58. data/lib/generators/react_on_rails/templates/linters/client/.eslintignore +1 -0
  59. data/lib/generators/react_on_rails/templates/linters/client/.eslintrc +17 -0
  60. data/lib/generators/react_on_rails/templates/linters/client/.jscsrc +7 -0
  61. data/lib/generators/react_on_rails/templates/linters/lib/tasks/brakeman.rake +17 -0
  62. data/lib/generators/react_on_rails/templates/linters/lib/tasks/ci.rake +33 -0
  63. data/lib/generators/react_on_rails/templates/linters/lib/tasks/linters.rake +81 -0
  64. data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx +39 -0
  65. data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +33 -0
  66. data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/startup/HelloWorldAppClient.jsx +11 -0
  67. data/lib/generators/react_on_rails/templates/no_redux/base/client/package.json.tt +75 -0
  68. data/lib/generators/react_on_rails/templates/no_redux/server_rendering/client/app/bundles/HelloWorld/startup/HelloWorldAppServer.jsx +11 -0
  69. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/actions/helloWorldActionCreators.jsx +8 -0
  70. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx +48 -0
  71. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/constants/helloWorldConstants.jsx +8 -0
  72. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +43 -0
  73. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/reducers/helloWorldReducer.jsx +21 -0
  74. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/reducers/index.jsx +14 -0
  75. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldAppClient.jsx +20 -0
  76. data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/store/helloWorldStore.jsx +35 -0
  77. data/lib/generators/react_on_rails/templates/redux/base/client/app/lib/middlewares/loggerMiddleware.js +25 -0
  78. data/lib/generators/react_on_rails/templates/redux/base/client/package.json.tt +82 -0
  79. data/lib/generators/react_on_rails/templates/redux/server_rendering/client/app/bundles/HelloWorld/startup/HelloWorldAppServer.jsx +21 -0
  80. data/lib/react_on_rails.rb +1 -7
  81. data/lib/react_on_rails/configuration.rb +14 -5
  82. data/lib/react_on_rails/engine.rb +7 -0
  83. data/lib/react_on_rails/server_rendering_pool.rb +14 -1
  84. data/lib/react_on_rails/version.rb +1 -1
  85. data/react_on_rails.gemspec +2 -2
  86. data/ruby-lint.yml +1 -0
  87. metadata +75 -11
  88. data/Dockerfile +0 -14
  89. data/docs/README.md +0 -1
@@ -0,0 +1,19 @@
1
+ // The Rails server imports this file via app/assets/stylesheets/application.css.scss
2
+ // The webpack HMR dev server loads this file via client/bootstrap-sass.config.js
3
+
4
+ // This file allows the same sass code with Rails and node-sass for the Webpack Dev Server.
5
+ // It is CRTICAL that this file is loaded first.
6
+
7
+ $rails: false !default; // defaults to false (e.g. webpack environment)
8
+
9
+ // Sass 3 removes image-url helper
10
+ // https://github.com/sass/libsass/issues/489
11
+ $image-url-path: '/assets/images/' !default;
12
+
13
+ @function img-url($image) {
14
+ @if $rails {
15
+ @return image-url($image);
16
+ } @else {
17
+ @return url('#{$image-url-path}#{$image}');
18
+ }
19
+ }
@@ -0,0 +1,89 @@
1
+ // See https://github.com/shakacode/bootstrap-sass-loader for more information
2
+
3
+ // IMPORTANT: Make sure to keep the customizations defined in this file
4
+ // in-sync with the ones defined in app/assets/stylesheets/_bootstrap-custom.scss.
5
+
6
+ // For a reference on customizations,refer to:
7
+ // https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/_bootstrap.scss
8
+
9
+ module.exports = {
10
+ bootstrapCustomizations: './assets/stylesheets/_pre-bootstrap.scss',
11
+ mainSass: './assets/stylesheets/_post-bootstrap.scss',
12
+
13
+ // Default for the style loading is to put in your js files
14
+ // styleLoader: 'style-loader!css-loader!sass-loader',
15
+
16
+ // See: https://github.com/sass/node-sass#outputstyle
17
+ // https://github.com/sass/node-sass#imagepath
18
+ styleLoader: 'style-loader!css-loader!sass-loader?imagePath=/assets/images',
19
+
20
+ // ### Scripts
21
+ // Any scripts here set to false will never make it to the client,
22
+ // i.e. it's not packaged by webpack.
23
+ scripts: {
24
+ transition: true,
25
+ alert: true,
26
+ button: true,
27
+
28
+ carousel: true,
29
+ collapse: true,
30
+ dropdown: true,
31
+
32
+ modal: true,
33
+ tooltip: true,
34
+ popover: true,
35
+ scrollspy: true,
36
+ tab: true,
37
+ affix: true,
38
+ },
39
+
40
+ // ### Styles
41
+ // Enable or disable certain less components and thus remove
42
+ // the css for them from the build.
43
+ styles: {
44
+ mixins: true,
45
+
46
+ normalize: true,
47
+ print: true,
48
+
49
+ scaffolding: true,
50
+ type: true,
51
+ code: true,
52
+ grid: true,
53
+ tables: true,
54
+ forms: true,
55
+ buttons: true,
56
+
57
+ 'component-animations': true,
58
+ glyphicons: true,
59
+ dropdowns: true,
60
+ 'button-groups': true,
61
+ 'input-groups': true,
62
+ navs: true,
63
+ navbar: true,
64
+ breadcrumbs: true,
65
+ pagination: true,
66
+ pager: true,
67
+ labels: true,
68
+ badges: true,
69
+
70
+ jumbotron: true,
71
+ thumbnails: true,
72
+ alerts: true,
73
+
74
+ 'progress-bars': true,
75
+ media: true,
76
+ 'list-group': true,
77
+ panels: true,
78
+ wells: true,
79
+ close: true,
80
+
81
+ modals: true,
82
+ tooltip: true,
83
+ popovers: true,
84
+ carousel: true,
85
+
86
+ utilities: true,
87
+ 'responsive-utilities': true,
88
+ },
89
+ };
@@ -0,0 +1,97 @@
1
+ Example NPM Package
2
+ ===========================
3
+ We've included an example package.json from https://github.com/shakacode/react-webpack-rails-tutorial which should get you started with your React project.
4
+
5
+ Starting the node.js server:
6
+ ```
7
+ npm start
8
+ ```
9
+
10
+ Building client javascript files for production:
11
+ ```
12
+ npm run build:client
13
+ ```
14
+
15
+ Building server javascript files for production:
16
+ ```
17
+ npm run build:server
18
+ ```
19
+
20
+ Building client javascript files for development:
21
+ ```
22
+ npm run build:dev:client
23
+ ```
24
+
25
+ Building server javascript files for development:
26
+ ```
27
+ npm run build:dev:server
28
+ ```
29
+
30
+ Running all linters:
31
+ ```
32
+ npm run lint
33
+ ```
34
+
35
+ Running eslint:
36
+ ```
37
+ npm run eslint
38
+ ```
39
+
40
+ Running jscs:
41
+ ```
42
+ npm run jscs
43
+ ```
44
+
45
+ dependencies vs devDependencies
46
+ ===========================
47
+ Anything needed for heroku deployment needs to go in "dependencies", and anything not needed for heroku deployment should go in "devDependencies".
48
+
49
+
50
+ Updating Node Dependencies
51
+ ===========================
52
+
53
+ ```
54
+ npm install -g npm-check-updates
55
+ ```
56
+
57
+ Then run this to update the dependencies (starting at the top level).
58
+
59
+ ```
60
+ # Make sure you are in the top directory, then run:
61
+ cd client
62
+ rm npm-shrinkwrap.json
63
+ npm-check-updates -u
64
+ npm install
65
+ npm prune
66
+ npm shrinkwrap
67
+ ```
68
+
69
+ Then confirm that the hot reload server and the rails server both work fine. You
70
+ may have to delete `node_modules` and `npm-shrinkwrap.json` and then run `npm
71
+ shrinkwrap`.
72
+
73
+ Note: `npm prune` is required before running `npm shrinkwrap` to remove dependencies that are no longer needed after doing updates.
74
+
75
+
76
+ Adding Node Modules
77
+ =====================================
78
+ Suppose you want to add a dependency to "module_name"....
79
+
80
+ Before you do so, consider:
81
+
82
+ 1. Do we really need the module and the extra JS code?
83
+ 2. Is the module well maintained?
84
+
85
+ ```bash
86
+ cd client
87
+ npm install --save module_name@version
88
+ # or
89
+ # npm install --save_dev module_name@version
90
+ rm npm-shrinkwrap.json
91
+ npm shrinkwrap
92
+ ```
93
+
94
+ Setting Up a Basic REST API
95
+ =====================================
96
+ See server.js in our tutorial at
97
+ https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/client/server.js
@@ -0,0 +1,2 @@
1
+ https://github.com/heroku/heroku-buildpack-nodejs.git
2
+ https://github.com/heroku/heroku-buildpack-ruby.git
@@ -0,0 +1 @@
1
+ web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
@@ -0,0 +1,17 @@
1
+ ---
2
+ parser: babel-eslint
3
+
4
+ extends: eslint-config-airbnb
5
+
6
+ plugins:
7
+ - react
8
+
9
+ env:
10
+ browser: true
11
+ node: true
12
+
13
+ rules:
14
+ indent: [1, 2, { SwitchCase: 1, VariableDeclarator: 2 }]
15
+ react/sort-comp: 0
16
+ react/jsx-quotes: 1
17
+ id-length: [2, {"exceptions": ["e", "i"]}]
@@ -0,0 +1,7 @@
1
+ {
2
+ "preset": "airbnb",
3
+ "fileExtensions": [".js", ".jsx"],
4
+ "excludeFiles": ["build/**", "node_modules/**"],
5
+
6
+ "validateQuoteMarks": null // Issue with JSX quotemarks: https://github.com/jscs-dev/babel-jscs/issues/12
7
+ }
@@ -0,0 +1,17 @@
1
+ namespace :brakeman do
2
+
3
+ desc "Run Brakeman"
4
+ task :run, :output_files do |t, args|
5
+ require 'brakeman'
6
+
7
+ files = args[:output_files].split(' ') if args[:output_files]
8
+ Brakeman.run :app_path => ".", :output_files => files, :print_report => true
9
+ end
10
+
11
+ desc "Check your code with Brakeman"
12
+ task :check do
13
+ require 'brakeman'
14
+ result = Brakeman.run app_path: '.', print_report: true
15
+ exit Brakeman::Warnings_Found_Exit_Code unless result.filtered_warnings.empty?
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ if Rails.env.development?
2
+ # See tasks/linters.rake
3
+
4
+ task :bundle_audit do
5
+ puts Rainbow("Running security audit on gems (bundle_audit)").green
6
+ Rake::Task["bundle_audit"].invoke
7
+ end
8
+
9
+ task :security_audit do
10
+ puts Rainbow("Running security audit on code (brakeman)").green
11
+
12
+ sh "brakeman --exit-on-warn --quiet -A -z"
13
+ end
14
+
15
+ namespace :ci do
16
+ desc "Run all audits and tests"
17
+ task all: [:environment, :lint, :spec, :bundle_audit, :security_audit] do
18
+ begin
19
+ puts Rainbow("PASSED").green
20
+ puts ""
21
+ rescue Exception => e
22
+ puts "#{e}"
23
+ puts Rainbow("FAILED").red
24
+ puts ""
25
+ raise(e)
26
+ end
27
+ end
28
+ end
29
+
30
+ task ci: "ci:all"
31
+
32
+ task(:default).clear.enhance([:ci])
33
+ end
@@ -0,0 +1,81 @@
1
+ if %w(development test).include? Rails.env
2
+ namespace :lint do
3
+ # This fails: https://github.com/bbatsov/rubocop/issues/1840
4
+ # RuboCop::RakeTask.new
5
+ # require "rubocop/rake_task"
6
+ desc "Run Rubocop lint in shell. Specify option fix to auto-correct (and don't have uncommitted files!)."
7
+ task :rubocop, [:fix] => [] do |_t, args|
8
+ def to_bool(str)
9
+ return true if str =~ (/^(true|t|yes|y|1)$/i)
10
+ return false if str.blank? || str =~ (/^(false|f|no|n|0)$/i)
11
+ fail ArgumentError, "invalid value for Boolean: \"#{str}\""
12
+ end
13
+
14
+ fix = (args.fix == "fix") || to_bool(args.fix)
15
+ cmd = "rubocop -S -D#{fix ? ' -a' : ''} ."
16
+ puts "Running Rubocop Linters via `#{cmd}`#{fix ? ' auto-correct is turned on!' : ''}"
17
+ sh cmd
18
+ end
19
+
20
+ desc "Run ruby-lint as shell"
21
+ task :ruby do
22
+ cmd = "ruby-lint app config spec lib"
23
+ puts "Running ruby-lint Linters via `#{cmd}`"
24
+ sh cmd
25
+ end
26
+
27
+ desc "eslint"
28
+ task :eslint do
29
+ cmd = "cd client && npm run eslint . -- --ext .jsx,.js"
30
+ puts "Running eslint via `#{cmd}`"
31
+ sh cmd
32
+ end
33
+
34
+ desc "jscs"
35
+ task :jscs do
36
+ cmd = "cd client && npm run jscs ."
37
+ puts "Running jscs via `#{cmd}`"
38
+ sh cmd
39
+ end
40
+
41
+ desc "JS Linting"
42
+ task js: [:eslint, :jscs] do
43
+ puts "Completed running all JavaScript Linters"
44
+ end
45
+
46
+ # desc "haml_lint"
47
+ # task :haml_lint do
48
+ # require 'haml_lint/rake_task'
49
+
50
+ # HamlLint::RakeTask.new do |t|
51
+ # t.files = ["app/views"]
52
+ # end
53
+ # end
54
+
55
+ # desc "See docs for task 'slim_lint'"
56
+ # task slim: :slim_lint
57
+ # SlimLint::RakeTask.new do |t|
58
+ # t.files = ["app/views"]
59
+ # end
60
+
61
+ desc "See docs for task 'scss_lint'"
62
+ task :scss do
63
+ begin
64
+ require 'scss_lint/rake_task'
65
+ SCSSLint::RakeTask.new do |t|
66
+ t.files = ["app/assets/stylesheets/", "client/assets/stylesheets/"]
67
+ end
68
+ Rake::Task[:scss_lint].invoke
69
+ rescue LoadError
70
+ puts "** add gem 'scss_lint' to your Gemfile for scss linting."
71
+ end
72
+ end
73
+
74
+ task lint: [:rubocop, :ruby, :js, :scss] do
75
+ puts "Completed all linting"
76
+ end
77
+ end
78
+
79
+ desc "Runs all linters. Run `rake -D lint` to see all available lint options"
80
+ task lint: ["lint:lint"]
81
+ end
@@ -0,0 +1,39 @@
1
+ import React, { PropTypes } from 'react';
2
+ import _ from 'lodash';
3
+
4
+ // Simple example of a React "dumb" component
5
+ export default class HelloWorldWidget extends React.Component {
6
+ constructor(props, context) {
7
+ super(props, context);
8
+
9
+ // Uses lodash to bind all methods to the context of the object instance, otherwise
10
+ // the methods defined here would not refer to the component's class, not the component
11
+ // instance itself.
12
+ _.bindAll(this, '_handleChange');
13
+ }
14
+
15
+ static propTypes = {
16
+ name: PropTypes.string.isRequired,
17
+ _updateName: PropTypes.func.isRequired,
18
+ };
19
+
20
+ // React will automatically provide us with the event `e`
21
+ _handleChange(e) {
22
+ const name = e.target.value;
23
+ this.props._updateName(name);
24
+ }
25
+
26
+ render() {
27
+ return (
28
+ <div>
29
+ <h3>
30
+ Hello, {this.props.name}!
31
+ </h3>
32
+ <p>
33
+ Say hello to:
34
+ <input type="text" ref="name" value={this.props.name} onChange={this._handleChange} />
35
+ </p>
36
+ </div>
37
+ );
38
+ }
39
+ }
@@ -0,0 +1,33 @@
1
+ import React, { PropTypes } from 'react';
2
+ import HelloWorldWidget from '../components/HelloWorldWidget';
3
+ import _ from 'lodash';
4
+
5
+ // Simple example of a React "smart" component
6
+ export default class HelloWorld extends React.Component {
7
+ constructor(props, context) {
8
+ super(props, context);
9
+
10
+ // Uses lodash to bind all methods to the context of the object instance, otherwise
11
+ // the methods defined here would not refer to the component's class, not the component
12
+ // instance itself.
13
+ _.bindAll(this, '_updateName');
14
+ }
15
+
16
+ static propTypes = {
17
+ name: PropTypes.string.isRequired, // this is passed from the Rails view
18
+ }
19
+
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
+ }
25
+
26
+ render() {
27
+ return (
28
+ <div>
29
+ <HelloWorldWidget name={this.state.name} _updateName={this._updateName} />
30
+ </div>
31
+ );
32
+ }
33
+ }