react_on_rails 2.0.0.beta.1 → 2.0.0.beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.dockerignore +2 -0
- data/.eslintignore +7 -0
- data/.eslintrc +19 -0
- data/.gitignore +28 -0
- data/.jscsrc +27 -0
- data/.npmignore +20 -0
- data/.rspec +2 -0
- data/.rubocop.yml +70 -0
- data/.scss-lint.yml +205 -0
- data/.travis.yml +43 -0
- data/CHANGELOG.md +34 -0
- data/Dockerfile_tests +12 -0
- data/Gemfile +40 -0
- data/README.md +365 -0
- data/Rakefile +5 -0
- data/app/helpers/react_on_rails_helper.rb +215 -0
- data/docker-compose.yml +11 -0
- data/docs/LICENSE +21 -0
- data/docs/additional_reading/heroku_deployment.md +23 -0
- data/docs/additional_reading/manual_installation.md +118 -0
- data/docs/additional_reading/node_dependencies_and_npm.md +29 -0
- data/docs/additional_reading/optional_configuration.md +33 -0
- data/docs/additional_reading/react-and-redux.md +36 -0
- data/docs/additional_reading/react_router.md +45 -0
- data/docs/additional_reading/server_rendering_tips.md +11 -0
- data/docs/additional_reading/tips.md +10 -0
- data/docs/additional_reading/webpack.md +46 -0
- data/docs/code_of_conduct.md +13 -0
- data/docs/coding-style/linters.md +64 -0
- data/docs/coding-style/style.md +42 -0
- data/docs/contributing.md +157 -0
- data/docs/generator_testing.md +20 -0
- data/docs/releasing.md +29 -0
- data/lib/generators/USAGE +99 -0
- data/lib/generators/react_on_rails/base_generator.rb +191 -0
- data/lib/generators/react_on_rails/bootstrap_generator.rb +89 -0
- data/lib/generators/react_on_rails/dev_tests_generator.rb +39 -0
- data/lib/generators/react_on_rails/generator_helper.rb +50 -0
- data/lib/generators/react_on_rails/heroku_deployment_generator.rb +30 -0
- data/lib/generators/react_on_rails/install_generator.rb +99 -0
- data/lib/generators/react_on_rails/js_linters_generator.rb +19 -0
- data/lib/generators/react_on_rails/react_no_redux_generator.rb +40 -0
- data/lib/generators/react_on_rails/react_with_redux_generator.rb +51 -0
- data/lib/generators/react_on_rails/ruby_linters_generator.rb +33 -0
- data/lib/generators/react_on_rails/templates/base/base/Procfile.dev.tt +4 -0
- data/lib/generators/react_on_rails/templates/base/base/REACT_ON_RAILS.md +16 -0
- data/lib/generators/react_on_rails/templates/base/base/app/controllers/hello_world_controller.rb +5 -0
- data/lib/generators/react_on_rails/templates/base/base/app/views/hello_world/index.html.erb.tt +4 -0
- data/lib/generators/react_on_rails/templates/base/base/client/.babelrc +3 -0
- data/lib/generators/react_on_rails/templates/base/base/client/REACT_ON_RAILS_CLIENT_README.md +3 -0
- data/lib/generators/react_on_rails/templates/base/base/client/app/bundles/HelloWorld/startup/clientRegistration.jsx.tt +5 -0
- data/lib/generators/react_on_rails/templates/base/base/client/index.jade +15 -0
- data/lib/generators/react_on_rails/templates/base/base/client/package.json.tt +104 -0
- data/lib/generators/react_on_rails/templates/base/base/client/server.js +64 -0
- data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.base.config.js.tt +62 -0
- data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.hot.config.js.tt +69 -0
- data/lib/generators/react_on_rails/templates/base/base/client/webpack.client.rails.config.js +42 -0
- data/lib/generators/react_on_rails/templates/base/base/config/initializers/react_on_rails.rb +26 -0
- data/lib/generators/react_on_rails/templates/base/base/lib/tasks/assets.rake.tt +26 -0
- data/lib/generators/react_on_rails/templates/base/base/lib/tasks/linters.rake.tt +88 -0
- data/lib/generators/react_on_rails/templates/base/base/package.json +31 -0
- data/lib/generators/react_on_rails/templates/base/server_rendering/client/app/bundles/HelloWorld/startup/serverRegistration.jsx +4 -0
- data/lib/generators/react_on_rails/templates/base/server_rendering/client/webpack.server.rails.config.js +39 -0
- data/lib/generators/react_on_rails/templates/bootstrap/app/assets/stylesheets/_bootstrap-custom.scss +63 -0
- data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_post-bootstrap.scss +10 -0
- data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_pre-bootstrap.scss +8 -0
- data/lib/generators/react_on_rails/templates/bootstrap/client/assets/stylesheets/_react-on-rails-sass-helper.scss +19 -0
- data/lib/generators/react_on_rails/templates/bootstrap/client/bootstrap-sass.config.js +89 -0
- data/lib/generators/react_on_rails/templates/dev_tests/.rspec +2 -0
- data/lib/generators/react_on_rails/templates/dev_tests/spec/features/hello_world_spec.rb +25 -0
- data/lib/generators/react_on_rails/templates/dev_tests/spec/rails_helper.rb +57 -0
- data/lib/generators/react_on_rails/templates/dev_tests/spec/simplecov_helper.rb +21 -0
- data/lib/generators/react_on_rails/templates/dev_tests/spec/spec_helper.rb +95 -0
- data/lib/generators/react_on_rails/templates/heroku_deployment/.buildpacks +2 -0
- data/lib/generators/react_on_rails/templates/heroku_deployment/Procfile +1 -0
- data/lib/generators/react_on_rails/templates/heroku_deployment/config/puma.rb +15 -0
- data/lib/generators/react_on_rails/templates/js_linters/client/.eslintignore +1 -0
- data/lib/generators/react_on_rails/templates/js_linters/client/.eslintrc +48 -0
- data/lib/generators/react_on_rails/templates/js_linters/client/.jscsrc +18 -0
- data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx +39 -0
- data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +33 -0
- data/lib/generators/react_on_rails/templates/no_redux/base/client/app/bundles/HelloWorld/startup/HelloWorldAppClient.jsx.tt +8 -0
- data/lib/generators/react_on_rails/templates/no_redux/server_rendering/client/app/bundles/HelloWorld/startup/HelloWorldAppServer.jsx +8 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/actions/helloWorldActionCreators.jsx +8 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/components/HelloWorldWidget.jsx +48 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/constants/helloWorldConstants.jsx +8 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/containers/HelloWorld.jsx +43 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/reducers/helloWorldReducer.jsx +19 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/reducers/index.jsx +14 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/startup/HelloWorldAppClient.jsx.tt +19 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/bundles/HelloWorld/store/helloWorldStore.jsx +35 -0
- data/lib/generators/react_on_rails/templates/redux/base/client/app/lib/middlewares/loggerMiddleware.js +20 -0
- data/lib/generators/react_on_rails/templates/redux/server_rendering/client/app/bundles/HelloWorld/startup/HelloWorldAppServer.jsx +19 -0
- data/lib/generators/react_on_rails/templates/ruby_linters/.rubocop.yml +26 -0
- data/lib/generators/react_on_rails/templates/ruby_linters/.scss-lint.yml +205 -0
- data/lib/generators/react_on_rails/templates/ruby_linters/lib/tasks/brakeman.rake +17 -0
- data/lib/generators/react_on_rails/templates/ruby_linters/lib/tasks/ci.rake +33 -0
- data/lib/generators/react_on_rails/templates/ruby_linters/ruby-lint.yml +20 -0
- data/lib/react_on_rails.rb +6 -0
- data/lib/react_on_rails/configuration.rb +60 -0
- data/lib/react_on_rails/engine.rb +7 -0
- data/lib/react_on_rails/prerender_error.rb +31 -0
- data/lib/react_on_rails/server_rendering_pool.rb +110 -0
- data/lib/react_on_rails/version.rb +3 -0
- data/package.json +76 -0
- data/rakelib/docker.rake +33 -0
- data/rakelib/dummy_apps.rake +20 -0
- data/rakelib/example_type.rb +160 -0
- data/rakelib/examples.rake +103 -0
- data/rakelib/examples_config.yml +19 -0
- data/rakelib/lint.rake +37 -0
- data/rakelib/node_package.rake +11 -0
- data/rakelib/run_rspec.rake +65 -0
- data/rakelib/task_helpers.rb +44 -0
- data/react_on_rails.gemspec +31 -0
- data/ruby-lint.yml +24 -0
- metadata +119 -2
|
@@ -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,20 @@
|
|
|
1
|
+
presenter: syntastic
|
|
2
|
+
|
|
3
|
+
directories:
|
|
4
|
+
- app
|
|
5
|
+
- config
|
|
6
|
+
- spec
|
|
7
|
+
|
|
8
|
+
ignore_paths:
|
|
9
|
+
- client
|
|
10
|
+
- node_modules
|
|
11
|
+
|
|
12
|
+
analysis_classes:
|
|
13
|
+
# - argument_amount
|
|
14
|
+
- pedantics
|
|
15
|
+
- shadowing_variables
|
|
16
|
+
# Too many false positives for these
|
|
17
|
+
# - undefined_methods
|
|
18
|
+
# - undefined_variables
|
|
19
|
+
# - unused_variables
|
|
20
|
+
- useless_equality_checks
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module ReactOnRails
|
|
2
|
+
def self.configure
|
|
3
|
+
yield(configuration)
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
# TODO ROB
|
|
7
|
+
# parse the client/package.json and ensure that either:
|
|
8
|
+
# 1. version number matches
|
|
9
|
+
# 2. version number is a relative path (for testing)
|
|
10
|
+
# Throw error if not.
|
|
11
|
+
# Allow skipping this check in the configuration in case somebody has a wacky configuration, such
|
|
12
|
+
# as you don't know where their package.json
|
|
13
|
+
|
|
14
|
+
def self.configuration
|
|
15
|
+
@configuration ||= Configuration.new(
|
|
16
|
+
server_bundle_js_file: "app/assets/javascripts/generated/server.js",
|
|
17
|
+
prerender: false,
|
|
18
|
+
replay_console: true,
|
|
19
|
+
logging_on_server: true,
|
|
20
|
+
raise_on_prerender_error: false,
|
|
21
|
+
trace: Rails.env.development?,
|
|
22
|
+
development_mode: Rails.env.development?,
|
|
23
|
+
server_renderer_pool_size: 1,
|
|
24
|
+
server_renderer_timeout: 20)
|
|
25
|
+
# TODO ROB: do the version check
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class Configuration
|
|
29
|
+
attr_accessor :server_bundle_js_file, :prerender, :replay_console,
|
|
30
|
+
:trace, :development_mode,
|
|
31
|
+
:logging_on_server, :server_renderer_pool_size,
|
|
32
|
+
:server_renderer_timeout, :raise_on_prerender_error
|
|
33
|
+
|
|
34
|
+
def initialize(server_bundle_js_file: nil, prerender: nil, replay_console: nil,
|
|
35
|
+
trace: nil, development_mode: nil,
|
|
36
|
+
logging_on_server: nil, server_renderer_pool_size: nil,
|
|
37
|
+
server_renderer_timeout: nil, raise_on_prerender_error: nil)
|
|
38
|
+
if File.exist?(server_bundle_js_file)
|
|
39
|
+
self.server_bundle_js_file = server_bundle_js_file
|
|
40
|
+
else
|
|
41
|
+
self.server_bundle_js_file = nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
self.prerender = prerender
|
|
45
|
+
self.replay_console = replay_console
|
|
46
|
+
self.logging_on_server = logging_on_server
|
|
47
|
+
if development_mode.nil?
|
|
48
|
+
self.development_mode = Rails.env.development?
|
|
49
|
+
else
|
|
50
|
+
self.development_mode = development_mode
|
|
51
|
+
end
|
|
52
|
+
self.trace = trace.nil? ? Rails.env.development? : trace
|
|
53
|
+
self.raise_on_prerender_error = raise_on_prerender_error
|
|
54
|
+
|
|
55
|
+
# Server rendering:
|
|
56
|
+
self.server_renderer_pool_size = self.development_mode ? 1 : server_renderer_pool_size
|
|
57
|
+
self.server_renderer_timeout = server_renderer_timeout # seconds
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module ReactOnRails
|
|
2
|
+
class PrerenderError < RuntimeError
|
|
3
|
+
# err might be nil if JS caught the error
|
|
4
|
+
def initialize(component_name: nil, err: nil, props: nil,
|
|
5
|
+
js_code: nil, console_messages: nil)
|
|
6
|
+
message = "ERROR in SERVER PRERENDERING\n"
|
|
7
|
+
if err
|
|
8
|
+
message << <<-MSG
|
|
9
|
+
Encountered error: \"#{err}\"
|
|
10
|
+
MSG
|
|
11
|
+
backtrace = err.backtrace.join("\n")
|
|
12
|
+
else
|
|
13
|
+
backtrace = nil
|
|
14
|
+
end
|
|
15
|
+
message << <<-MSG
|
|
16
|
+
when prerendering #{component_name} with props: #{props}
|
|
17
|
+
js_code was:
|
|
18
|
+
#{js_code}
|
|
19
|
+
MSG
|
|
20
|
+
|
|
21
|
+
if console_messages
|
|
22
|
+
message << <<-MSG
|
|
23
|
+
console messages:
|
|
24
|
+
#{console_messages}
|
|
25
|
+
MSG
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
super([message, backtrace].compact.join("\n"))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require "connection_pool"
|
|
2
|
+
|
|
3
|
+
# Based on the react-rails gem.
|
|
4
|
+
# None of these methods should be called directly.
|
|
5
|
+
# See app/helpers/react_on_rails_helper.rb
|
|
6
|
+
module ReactOnRails
|
|
7
|
+
class ServerRenderingPool
|
|
8
|
+
def self.reset_pool
|
|
9
|
+
options = { size: ReactOnRails.configuration.server_renderer_pool_size,
|
|
10
|
+
timeout: ReactOnRails.configuration.server_renderer_pool_size }
|
|
11
|
+
@js_context_pool = ConnectionPool.new(options) { create_js_context }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.reset_pool_if_server_bundle_was_modified
|
|
15
|
+
return unless ReactOnRails.configuration.development_mode
|
|
16
|
+
file_mtime = File.mtime(ReactOnRails.configuration.server_bundle_js_file)
|
|
17
|
+
@server_bundle_timestamp ||= file_mtime
|
|
18
|
+
return if @server_bundle_timestamp == file_mtime
|
|
19
|
+
ReactOnRails::ServerRenderingPool.reset_pool
|
|
20
|
+
@server_bundle_timestamp = file_mtime
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# js_code: JavaScript expression that returns a string.
|
|
24
|
+
# Returns a Hash:
|
|
25
|
+
# html: string of HTML for direct insertion on the page by evaluating js_code
|
|
26
|
+
# consoleReplayScript: script for replaying console
|
|
27
|
+
# hasErrors: true if server rendering errors
|
|
28
|
+
# Note, js_code does not have to be based on React.
|
|
29
|
+
# js_code MUST RETURN json stringify Object
|
|
30
|
+
# Calling code will probably call 'html_safe' on return value before rendering to the view.
|
|
31
|
+
def self.server_render_js_with_console_logging(js_code)
|
|
32
|
+
trace_messsage(js_code)
|
|
33
|
+
json_string = eval_js(js_code)
|
|
34
|
+
result = JSON.parse(json_string)
|
|
35
|
+
|
|
36
|
+
if ReactOnRails.configuration.logging_on_server
|
|
37
|
+
console_script = result["consoleReplayScript"]
|
|
38
|
+
console_script_lines = console_script.split("\n")
|
|
39
|
+
console_script_lines = console_script_lines[2..-2]
|
|
40
|
+
re = /console\.log\.apply\(console, \["\[SERVER\] (?<msg>.*)"\]\);/
|
|
41
|
+
if console_script_lines
|
|
42
|
+
console_script_lines.each do |line|
|
|
43
|
+
match = re.match(line)
|
|
44
|
+
Rails.logger.info { "[react_on_rails] #{match[:msg]}" } if match
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
result
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class << self
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def trace_messsage(js_code)
|
|
55
|
+
return unless ENV["TRACE_REACT_ON_RAILS"].present?
|
|
56
|
+
# Set to anything to print generated code.
|
|
57
|
+
puts "Z" * 80
|
|
58
|
+
puts "react_renderer.rb: 92"
|
|
59
|
+
puts "wrote file tmp/server-generated.js"
|
|
60
|
+
File.write("tmp/server-generated.js", js_code)
|
|
61
|
+
puts "Z" * 80
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def eval_js(js_code)
|
|
65
|
+
@js_context_pool.with do |js_context|
|
|
66
|
+
result = js_context.eval(js_code)
|
|
67
|
+
js_context.eval("console.history = []")
|
|
68
|
+
result
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def create_js_context
|
|
73
|
+
server_js_file = ReactOnRails.configuration.server_bundle_js_file
|
|
74
|
+
if server_js_file.present? && File.exist?(server_js_file)
|
|
75
|
+
bundle_js_code = File.read(server_js_file)
|
|
76
|
+
base_js_code = <<-JS
|
|
77
|
+
#{console_polyfill}
|
|
78
|
+
#{bundle_js_code};
|
|
79
|
+
JS
|
|
80
|
+
ExecJS.compile(base_js_code)
|
|
81
|
+
else
|
|
82
|
+
if server_js_file.present?
|
|
83
|
+
msg = "You specified server rendering JS file: #{server_js_file}, but it cannot be "\
|
|
84
|
+
"read. You may set the server_bundle_js_file in your configuration to be \"\" to "\
|
|
85
|
+
"avoid this warning"
|
|
86
|
+
Rails.logger.warn msg
|
|
87
|
+
puts msg
|
|
88
|
+
end
|
|
89
|
+
ExecJS.compile("")
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Reimplement console methods for replaying on the client
|
|
94
|
+
def console_polyfill
|
|
95
|
+
<<-JS
|
|
96
|
+
var console = { history: [] };
|
|
97
|
+
['error', 'log', 'info', 'warn'].forEach(function (level) {
|
|
98
|
+
console[level] = function () {
|
|
99
|
+
var argArray = Array.prototype.slice.call(arguments);
|
|
100
|
+
if (argArray.length > 0) {
|
|
101
|
+
argArray[0] = '[SERVER] ' + argArray[0];
|
|
102
|
+
}
|
|
103
|
+
console.history.push({level: level, arguments: argArray});
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
JS
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
data/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-on-rails",
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
|
+
"description": "react-on-rails JavaScript for react_on_rails Ruby gem",
|
|
5
|
+
"main": "node_package/lib/ReactOnRails.js",
|
|
6
|
+
"directories": {
|
|
7
|
+
"doc": "docs"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"babel": "^6.3.13",
|
|
12
|
+
"babel-cli": "^6.3.17",
|
|
13
|
+
"babel-core": "^6.3.17",
|
|
14
|
+
"babel-eslint": "^5.0.0-beta4",
|
|
15
|
+
"babel-loader": "^6.2.0",
|
|
16
|
+
"babel-plugin-transform-runtime": "^6.3.13",
|
|
17
|
+
"babel-preset-es2015": "^6.3.13",
|
|
18
|
+
"babel-preset-react": "^6.3.13",
|
|
19
|
+
"babel-preset-stage-0": "^6.3.13",
|
|
20
|
+
"babel-runtime": "^6.3.13",
|
|
21
|
+
"babel-tape-runner": "^2.0.0",
|
|
22
|
+
"babelify": "^7.2.0",
|
|
23
|
+
"blue-tape": "^0.1.11",
|
|
24
|
+
"eslint": "^1.10.3",
|
|
25
|
+
"eslint-config-airbnb": "^2.0.0",
|
|
26
|
+
"eslint-plugin-babel": "^3.0.0",
|
|
27
|
+
"eslint-plugin-react": "^3.11.3",
|
|
28
|
+
"jscs": "^2.6.0",
|
|
29
|
+
"react": "^0.14.3",
|
|
30
|
+
"react-dom": "^0.14.3",
|
|
31
|
+
"tap-spec": "^4.1.1",
|
|
32
|
+
"tape": "^4.4.0",
|
|
33
|
+
"webpack": "^1.12.9"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react": ">= 0.14",
|
|
37
|
+
"react-dom": ">= 0.14"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"node_package/lib"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"test": "node_package/scripts/test",
|
|
44
|
+
"clean": "node_package/scripts/clean",
|
|
45
|
+
"prepublish": "npm run build",
|
|
46
|
+
"build": "node_package/scripts/build",
|
|
47
|
+
"lint": "node_package/scripts/lint && cd spec/dummy/client && npm run lint",
|
|
48
|
+
"lint:fix": "node_package/scripts/lint-fix",
|
|
49
|
+
"check": "npm run lint && npm run test",
|
|
50
|
+
"prerelease": "npm run check && npm run clean && npm run build",
|
|
51
|
+
"release:patch": "node_package/scripts/release patch",
|
|
52
|
+
"release:minor": "node_package/scripts/release minor",
|
|
53
|
+
"release:major": "node_package/scripts/release major",
|
|
54
|
+
"dummy:install": "rake dummy_apps",
|
|
55
|
+
"dummy:spec": "rake run_rspec:dummy",
|
|
56
|
+
"local": "echo 'Be sure to run npm run dummy:install' && npm run build && cd spec/dummy && foreman start"
|
|
57
|
+
},
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "git+https://github.com/shakacode/react_on_rails.git"
|
|
61
|
+
},
|
|
62
|
+
"keywords": [
|
|
63
|
+
"react",
|
|
64
|
+
"webpack",
|
|
65
|
+
"JavaScript",
|
|
66
|
+
"Ruby",
|
|
67
|
+
"on",
|
|
68
|
+
"Rails"
|
|
69
|
+
],
|
|
70
|
+
"author": "justin.gordon@gmail.com",
|
|
71
|
+
"license": "MIT",
|
|
72
|
+
"bugs": {
|
|
73
|
+
"url": "https://github.com/shakacode/react_on_rails/issues"
|
|
74
|
+
},
|
|
75
|
+
"homepage": "https://github.com/shakacode/react_on_rails#readme"
|
|
76
|
+
}
|
data/rakelib/docker.rake
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
namespace :docker do
|
|
2
|
+
desc "Run Rubocop linter from docker"
|
|
3
|
+
task :rubocop do
|
|
4
|
+
sh "docker-compose run lint rake lint:rubocop"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
desc "Run ruby-lint linter from docker"
|
|
8
|
+
task :ruby do
|
|
9
|
+
sh "docker-compose run lint rake lint:ruby"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
desc "Run scss-lint linter from docker"
|
|
13
|
+
task :scss do
|
|
14
|
+
sh "docker-compose run lint rake lint:scss"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc "Run eslint linter from docker"
|
|
18
|
+
task :eslint do
|
|
19
|
+
sh "docker-compose run lint rake lint:eslint"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
desc "Run jscs linter from docker"
|
|
23
|
+
task :jscs do
|
|
24
|
+
sh "docker-compose run lint rake lint:jscs"
|
|
25
|
+
end
|
|
26
|
+
desc "Run all linting from docker"
|
|
27
|
+
task :lint do
|
|
28
|
+
sh "docker-compose run lint rake lint"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
desc "Runs all linters from docker. Run `rake -D docker` to see all available lint options"
|
|
33
|
+
task docker: ["docker:lint"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require_relative "task_helpers"
|
|
2
|
+
include ReactOnRails::TaskHelpers
|
|
3
|
+
|
|
4
|
+
namespace :dummy_apps do
|
|
5
|
+
task :dummy_app do
|
|
6
|
+
dummy_app_dir = File.join(gem_root, "spec/dummy")
|
|
7
|
+
bundle_install_in(dummy_app_dir)
|
|
8
|
+
dummy_app_client_dir = File.join(dummy_app_dir, "client")
|
|
9
|
+
sh_in_dir(dummy_app_client_dir, ["npm install",
|
|
10
|
+
"$(npm bin)/webpack --config webpack.server.js",
|
|
11
|
+
"$(npm bin)/webpack --config webpack.client.js"])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
task dummy_apps: [:dummy_app, :node_package] do
|
|
15
|
+
puts "Prepared all Dummy Apps"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc "Prepares all dummy apps by installing dependencies"
|
|
20
|
+
task dummy_apps: ["dummy_apps:dummy_apps"]
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
require "rake"
|
|
2
|
+
require "pathname"
|
|
3
|
+
|
|
4
|
+
require_relative "task_helpers"
|
|
5
|
+
|
|
6
|
+
# Defines the ExampleType class, where each object represents a unique type of example
|
|
7
|
+
# app that we can generate.
|
|
8
|
+
module ReactOnRails
|
|
9
|
+
module TaskHelpers
|
|
10
|
+
class ExampleType
|
|
11
|
+
def self.all
|
|
12
|
+
@example_types ||= []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.namespace_name
|
|
16
|
+
"examples"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attr_reader :name, :generator_options
|
|
20
|
+
|
|
21
|
+
def initialize(name:, generator_options:)
|
|
22
|
+
@name = name
|
|
23
|
+
@generator_options = generator_options
|
|
24
|
+
self.class.all << self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def name_pretty
|
|
28
|
+
"#{@name} example app"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def server_rendering?
|
|
32
|
+
generator_options.include?("--server-rendering")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def dir
|
|
36
|
+
File.join(examples_dir, name)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def dir_exist?
|
|
40
|
+
Dir.exist?(dir)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def client_dir
|
|
44
|
+
File.join(dir, "client")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def source_package_json
|
|
48
|
+
File.join(gem_root, "lib/generators/react_on_rails/templates/base/base/client/package.json.tt")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def node_modules_dir
|
|
52
|
+
File.join(client_dir, "node_modules")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def webpack_bundles_dir
|
|
56
|
+
File.join(dir, "app", "assets", "javascripts", "generated")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def webpack_bundles
|
|
60
|
+
bundles = []
|
|
61
|
+
bundles << File.join(webpack_bundles_dir, "app-bundle.js")
|
|
62
|
+
bundles << File.join(webpack_bundles_dir, "server-bundle.js") if server_rendering?
|
|
63
|
+
bundles << File.join(webpack_bundles_dir, "vendor-bundle.js")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def gemfile
|
|
67
|
+
File.join(dir, "Gemfile")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def gemfile_lock
|
|
71
|
+
"#{gemfile}.lock"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def package_json
|
|
75
|
+
File.join(client_dir, "package.json")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Gems we need to add to the Gemfile before bundle installing
|
|
79
|
+
def required_gems
|
|
80
|
+
relative_gem_root = Pathname(gem_root).relative_path_from(Pathname(dir))
|
|
81
|
+
["gem 'react_on_rails', path: '#{relative_gem_root}'"]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Options we pass when running `rails new` from the command-line
|
|
85
|
+
def rails_options
|
|
86
|
+
"--skip-bundle --skip-spring --skip-git --skip-test-unit --skip-active-record"
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Methods for retrieving the name of a task specific to the example type
|
|
90
|
+
%w(gen prepare clean clobber npm_install build_webpack_bundles).each do |task_type|
|
|
91
|
+
method = "#{task_type}_task_name" # ex: `clean_task_name`
|
|
92
|
+
task_name = "#{task_type}_#{name}" # ex: `clean_basic`
|
|
93
|
+
|
|
94
|
+
define_method(method) { "#{self.class.namespace_name}:#{task_name}" }
|
|
95
|
+
define_method("#{method}_short") { task_name }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def rspec_task_name_short
|
|
99
|
+
"example_#{name}"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def rspec_task_name
|
|
103
|
+
"run_rspec:#{rspec_task_name_short}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def source_files
|
|
107
|
+
FileList.new(all_files_in_dir(generators_source_dir))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Note: we need to explicitly declare a file we know is supposed to be there
|
|
111
|
+
# to indicate that the example is in need of being rebuilt in the case of its absence.
|
|
112
|
+
def generated_files
|
|
113
|
+
FileList.new(all_files_in_dir(dir)) do |fl|
|
|
114
|
+
fl.include(gemfile) # explicitly declared file (dependency of Gemfile.lock)
|
|
115
|
+
fl.include(package_json) # explicitly declared file (dependency of NPM Install)
|
|
116
|
+
fl.exclude(%r{client(/node_modules(.+)?)?$}) # leave node_modules folder
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def generated_client_files
|
|
121
|
+
generated_files.exclude { |f| !f.start_with?(client_dir) }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# generated files plus explicitly included files resulting from running
|
|
125
|
+
# bundle install, npm install, and generating the webpack bundles
|
|
126
|
+
def prepared_files
|
|
127
|
+
generated_files
|
|
128
|
+
.include(webpack_bundles)
|
|
129
|
+
.include(node_modules_dir)
|
|
130
|
+
.include(gemfile_lock)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def clean_files
|
|
134
|
+
generated_files
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Assumes we are inside client folder
|
|
138
|
+
def build_webpack_bundles_shell_commands
|
|
139
|
+
webpack_command = File.join("$(npm bin)", "webpack")
|
|
140
|
+
shell_commands = []
|
|
141
|
+
shell_commands << "#{webpack_command} --config webpack.server.rails.config.js" if server_rendering?
|
|
142
|
+
shell_commands << "#{webpack_command} --config webpack.client.rails.config.js"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Assumes we are inside a rails app's folder and necessary gems have been installed
|
|
146
|
+
def generator_shell_commands
|
|
147
|
+
shell_commands = []
|
|
148
|
+
shell_commands << "rails generate react_on_rails:install #{generator_options}"
|
|
149
|
+
shell_commands << "rails generate react_on_rails:dev_tests #{generator_options}"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
private
|
|
153
|
+
|
|
154
|
+
# Defines globs that scoop up all files (including dotfiles) in given directory
|
|
155
|
+
def all_files_in_dir(p_dir)
|
|
156
|
+
[File.join(p_dir, "**", "*"), File.join(p_dir, "**", ".*")]
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|