react-rails 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ec24b10fa9c28b21210e7040b868bbba41188a8cda1adf822b87b2fab16329f
4
- data.tar.gz: dfba8f8728426334b5cba7c789c38769af9a42792b234f97e5bb673aa7c513c1
3
+ metadata.gz: e9a12a6f724746ed2a189f4827268eb55fb538a80bb21edc2560809349a8f3aa
4
+ data.tar.gz: aea725c7bb9606e7e98d47b51788860545b58efa50c70d24c1ba599de36c4751
5
5
  SHA512:
6
- metadata.gz: ccdf22c47cf5ea0c8ed3bfb81ac9a948bc68ae3af4e182eb231d2e0a0d073b2abb81b067a262ee79bbe9c712cfc584312e21fdd575f539ff731f4823dbdf0b1f
7
- data.tar.gz: fc762ae39037ff9844b0892eda68dd000a00fe541bba758d0ed00eeaf90434e688b6fa42d90fe6466c6c206a445a32d6802762513dd8ae6e620d01748513af2b
6
+ metadata.gz: df32314ab7e9e039861cd39907d1cf4de240b77188d251cc15cf9ae1eb57dd3180b3c9fdcbffebbe8c148e9f7a8a9aaffae38e6737e9a7635aa8d2511eb102c2
7
+ data.tar.gz: 9089c5e64403d0040f2f183426f56fcf35542361e029838d3be1bfb01d098c4630515e24d083eefd4e72bbc6eb30752d9f9fcfb0e54cd765516d073e4799b7d8
@@ -8,13 +8,28 @@
8
8
 
9
9
  #### Bug Fixes
10
10
 
11
+ ## 2.6.0
12
+
13
+ #### Breaking Changes
14
+
15
+ #### New Features
16
+
17
+ - Typescript component generator #990
18
+
19
+ #### Deprecation
20
+
21
+ #### Bug Fixes
22
+
23
+ - assert_react_component will not pass tests where the case was different #979
24
+ - action_controller/test_case was accidentally `required` in dev #996
25
+
11
26
  ## 2.5.0
12
27
 
13
28
  #### Breaking Changes
14
29
 
15
30
  #### New Features
16
31
 
17
- - React 16.4.2 prebundled #977
32
+ - React 16.8.6 prebundled #977
18
33
  - Added `assert_react_component` test helper #957
19
34
  - Supports Webpacker 4, Ruby 2.6 #934
20
35
  - Supports camelize on ActionController::Parameters #932
data/README.md CHANGED
@@ -3,12 +3,12 @@
3
3
  [![Gem](https://img.shields.io/gem/v/react-rails.svg?style=flat-square)](http://rubygems.org/gems/react-rails)
4
4
  [![npm](https://img.shields.io/npm/v/react_ujs.svg?style=flat-square)](https://www.npmjs.com/package/react_ujs)
5
5
  [![Build Status](https://img.shields.io/travis/reactjs/react-rails/master.svg?style=flat-square)](https://travis-ci.org/reactjs/react-rails)
6
- [![Maintainers Wanted](https://img.shields.io/badge/Maintainers-Wanted-red.svg)
6
+ [![Maintainers Wanted](https://img.shields.io/badge/Maintainers-Wanted-red.svg?style=flat-square)]()
7
7
 
8
8
 
9
9
  React-Rails is a flexible tool to use [React](http://facebook.github.io/react/) with Rails. The benefits:
10
10
  * Automatically renders React server-side and client-side
11
- * Supports Webpacker 3.x, 2.x, 1.1+
11
+ * Supports Webpacker 4.x, 3.x, 2.x, 1.1+
12
12
  * Supports Sprockets 4.x, 3.x, 2.x
13
13
  * Lets you use [JSX](http://facebook.github.io/react/docs/jsx-in-depth.html), [ES6](http://es6-features.org/), [TypeScript](https://www.typescriptlang.org/), [CoffeeScript](http://coffeescript.org/)
14
14
 
@@ -40,6 +40,10 @@ A source code example utilizing React-Rails: https://github.com/BookOfGreg/react
40
40
  - [Upgrading](#upgrading)
41
41
  - [2.3 to 2.4](#23-to-24)
42
42
  - [Common Errors](#common-errors)
43
+ - [During installation](#during-installation)
44
+ - [Undefined Set](#undefined-set)
45
+ - [Using TheRubyRacer](#using-therubyracer)
46
+ - [HMR](#hmr)
43
47
  - [Related Projects](#related-projects)
44
48
  - [Contributing](#contributing)
45
49
 
@@ -64,7 +68,7 @@ $ cd my-app
64
68
  ```
65
69
 
66
70
  ##### 2) Add `webpacker` and `react-rails` to your gemfile:
67
- ```
71
+ ```ruby
68
72
  gem 'webpacker'
69
73
  gem 'react-rails'
70
74
  ```
@@ -83,7 +87,7 @@ This gives you:
83
87
  - `app/javascript/packs/server_rendering.js` for [server-side rendering](#server-side-rendering)
84
88
 
85
89
  ##### 4) Link the JavaScript pack in Rails view using `javascript_pack_tag` [helper](https://github.com/rails/webpacker#usage):
86
- ```
90
+ ```erb
87
91
  <!-- application.html.erb in Head tag below turbolinks -->
88
92
  <%= javascript_pack_tag 'application' %>
89
93
  ```
@@ -102,7 +106,7 @@ Note: Your component is added to `app/javascript/components/` by default.
102
106
 
103
107
  ##### 7) [Render it in a Rails view](#view-helper):
104
108
 
105
- ```
109
+ ```erb
106
110
  <!-- erb: paste this in view -->
107
111
  <%= react_component("HelloWorld", { greeting: "Hello from react-rails." }) %>
108
112
  ```
@@ -192,7 +196,7 @@ end
192
196
 
193
197
  `react-rails` provides a pre-bundled React.js & a UJS driver to the Rails asset pipeline. Get started by adding the `react-rails` gem:
194
198
 
195
- ```
199
+ ```ruby
196
200
  gem 'react-rails'
197
201
  ```
198
202
 
@@ -627,6 +631,7 @@ For the vast majority of cases this will get you most of the migration:
627
631
  - re-run `bundle exec rails webpacker:install:react` to update npm packages (Webpacker only)
628
632
 
629
633
  ## Common Errors
634
+ ### During installation
630
635
  1) While using installers.(rails webpacker:install:react && rails webpacker:install)
631
636
  Error:
632
637
  ```
@@ -650,6 +655,24 @@ sudo apt-get update && sudo apt-get install yarn
650
655
 
651
656
  yarn install
652
657
  ```
658
+ ### Undefined Set
659
+ ```
660
+ ExecJS::ProgramError (identifier 'Set' undefined):
661
+
662
+ (execjs):1
663
+ ```
664
+ If you see any variation of this issue, see [Using TheRubyRacer](#using-therubyracer)
665
+
666
+
667
+ ### Using TheRubyRacer
668
+ TheRubyRacer [hasn't updated LibV8](https://github.com/cowboyd/therubyracer/blob/master/therubyracer.gemspec#L20) (The library that powers Node.js) from v3 in 2 years, any new features are unlikely to work.
669
+
670
+ LibV8 itself is already [beyond version 7](https://github.com/cowboyd/libv8/releases/tag/v7.3.492.27.1) therefore many serverside issues are caused by old JS engines and fixed by using an up to date one such as [MiniRacer](https://github.com/discourse/mini_racer) or [TheRubyRhino](https://github.com/cowboyd/therubyrhino) on JRuby.
671
+
672
+ ### HMR
673
+ HMR is possible with this gem as it does just pass through to Webpacker. Please open an issue to let us know tips and tricks for it to add to the wiki.
674
+
675
+ One example: [Stack Overflow answer with Babel and Webpacker config](https://stackoverflow.com/a/54846330/193785)
653
676
 
654
677
  ## Related Projects
655
678
 
@@ -664,7 +687,7 @@ yarn install
664
687
 
665
688
  🎉 Thanks for taking the time to contribute! 🎉
666
689
 
667
- With 2 Million+ downloads of the react-rails Gem and another 100k+ downloads of react_ujs on NPM, you're helping the biggest React + Rails community!
690
+ With 5 Million+ downloads of the react-rails Gem and another 2 Million+ downloads of react_ujs on NPM, you're helping the biggest React + Rails community!
668
691
 
669
692
  By contributing to React-Rails, you agree to abide by the [code of conduct](https://github.com/reactjs/react-rails/blob/master/CODE_OF_CONDUCT.md).
670
693
 
@@ -55,6 +55,11 @@ module React
55
55
  default: false,
56
56
  desc: 'Output es6 class based component'
57
57
 
58
+ class_option :ts,
59
+ type: :boolean,
60
+ default: false,
61
+ desc: 'Output tsx class based component'
62
+
58
63
  class_option :coffee,
59
64
  type: :boolean,
60
65
  default: false,
@@ -89,9 +94,38 @@ module React
89
94
  }
90
95
  }
91
96
 
97
+ TYPESCRIPT_TYPES = {
98
+ 'node' => 'React.ReactNode',
99
+ 'bool' => 'boolean',
100
+ 'boolean' => 'boolean',
101
+ 'string' => 'string',
102
+ 'number' => 'number',
103
+ 'object' => 'object',
104
+ 'array' => 'Array<any>',
105
+ 'shape' => 'object',
106
+ 'element' => 'object',
107
+ 'func' => 'object',
108
+ 'function' => 'object',
109
+ 'any' => 'any',
110
+
111
+ 'instanceOf' => ->(type) {
112
+ type.to_s.camelize
113
+ },
114
+
115
+ 'oneOf' => ->(*opts) {
116
+ opts.map{ |k| "'#{k.to_s}'" }.join(" | ")
117
+ },
118
+
119
+ 'oneOfType' => ->(*opts) {
120
+ opts.map{ |k| "#{ts_lookup(k.to_s, k.to_s)}" }.join(" | ")
121
+ }
122
+ }
123
+
92
124
  def create_component_file
93
125
  template_extension = if options[:coffee]
94
126
  'js.jsx.coffee'
127
+ elsif options[:ts]
128
+ 'js.jsx.tsx'
95
129
  elsif options[:es6] || webpacker?
96
130
  'es6.jsx'
97
131
  else
@@ -101,7 +135,13 @@ module React
101
135
  # Prefer webpacker to sprockets:
102
136
  if webpacker?
103
137
  new_file_name = file_name.camelize
104
- extension = options[:coffee] ? 'coffee' : 'js'
138
+ extension = if options[:coffee]
139
+ 'coffee'
140
+ elsif options[:ts]
141
+ 'tsx'
142
+ else
143
+ 'js'
144
+ end
105
145
  target_dir = webpack_configuration.source_path
106
146
  .join('components')
107
147
  .relative_path_from(::Rails.root)
@@ -128,6 +168,7 @@ module React
128
168
 
129
169
  def file_header
130
170
  if webpacker?
171
+ return %|import * as React from "react"\n| if options[:ts]
131
172
  %|import React from "react"\nimport PropTypes from "prop-types"\n|
132
173
  else
133
174
  ''
@@ -146,23 +187,58 @@ module React
146
187
  defined?(Webpacker)
147
188
  end
148
189
 
149
- def parse_attributes!
150
- self.attributes = (attributes || []).map do |attr|
151
- name = ''
152
- type = ''
153
- options = ''
154
- options_regex = /(?<options>{.*})/
190
+ def parse_attributes!
191
+ self.attributes = (attributes || []).map do |attr|
192
+ name = ''
193
+ type = ''
194
+ args = ''
195
+ args_regex = /(?<args>{.*})/
196
+
197
+ name, type = attr.split(':')
198
+
199
+ if matchdata = args_regex.match(type)
200
+ args = matchdata[:args]
201
+ type = type.gsub(args_regex, '')
202
+ end
203
+
204
+ if options[:ts]
205
+ { :name => name, :type => ts_lookup(name, type, args), :union => union?(args) }
206
+ else
207
+ { :name => name, :type => lookup(type, args) }
208
+ end
209
+ end
210
+ end
211
+
212
+ def union?(args = '')
213
+ return args.to_s.gsub(/[{}]/, '').split(',').count > 1
214
+ end
155
215
 
156
- name, type = attr.split(':')
216
+ def self.ts_lookup(name, type = 'node', args = '')
217
+ ts_type = TYPESCRIPT_TYPES[type]
218
+ if ts_type.blank?
219
+ if type =~ /^[[:upper:]]/
220
+ ts_type = TYPESCRIPT_TYPES['instanceOf']
221
+ else
222
+ ts_type = TYPESCRIPT_TYPES['node']
223
+ end
224
+ end
157
225
 
158
- if matchdata = options_regex.match(type)
159
- options = matchdata[:options]
160
- type = type.gsub(options_regex, '')
161
- end
226
+ args = args.to_s.gsub(/[{}]/, '').split(',')
162
227
 
163
- { :name => name, :type => lookup(type, options) }
164
- end
165
- end
228
+ if ts_type.respond_to? :call
229
+ if args.blank?
230
+ return ts_type.call(type)
231
+ end
232
+
233
+ ts_type = ts_type.call(*args)
234
+ end
235
+
236
+ ts_type
237
+ end
238
+
239
+ def ts_lookup(name, type = 'node', args = '')
240
+ self.class.ts_lookup(name, type, args)
241
+ end
166
242
 
167
243
  def self.lookup(type = 'node', options = '')
168
244
  react_prop_type = REACT_PROP_TYPES[type]
@@ -0,0 +1,36 @@
1
+ <%= file_header %>
2
+ <% unions = attributes.select{ |a| a[:union] } -%>
3
+ <% if unions.size > 0 -%>
4
+ <% unions.each do |e| -%>
5
+ type <%= e[:name].titleize %> = <%= e[:type]%>
6
+ <% end -%>
7
+ <% end -%>
8
+
9
+ interface I<%= component_name %>Props {
10
+ <% if attributes.size > 0 -%>
11
+ <% attributes.each do | attribute | -%>
12
+ <% if attribute[:union] -%>
13
+ <%= attribute[:name].camelize(:lower) %>: <%= attribute[:name].titleize %>;
14
+ <% else -%>
15
+ <%= attribute[:name].camelize(:lower) %>: <%= attribute[:type] %>;
16
+ <% end -%>
17
+ <% end -%>
18
+ <% end -%>
19
+ }
20
+
21
+ interface I<%= component_name %>State {
22
+ }
23
+
24
+ class <%= component_name %> extends React.Component <I<%= component_name %>Props, I<%= component_name %>State> {
25
+ render() {
26
+ return (
27
+ <React.Fragment>
28
+ <% attributes.each do |attribute| -%>
29
+ <%= attribute[:name].titleize %>: {this.props.<%= attribute[:name].camelize(:lower) %>}
30
+ <% end -%>
31
+ </React.Fragment>
32
+ );
33
+ }
34
+ }
35
+
36
+ <%= file_footer %>
@@ -11,6 +11,10 @@ module React
11
11
  attr_accessor :output_buffer
12
12
  mattr_accessor :camelize_props_switch
13
13
 
14
+ def initialize
15
+ @cache_ids = []
16
+ end
17
+
14
18
  # {ControllerLifecycle} calls these hooks
15
19
  # You can use them in custom helper implementations
16
20
  def setup(controller)
@@ -40,6 +44,9 @@ module React
40
44
  data[:react_class] = name
41
45
  data[:react_props] = (props.is_a?(String) ? props : props.to_json)
42
46
  data[:hydrate] = 't' if prerender_options
47
+
48
+ num_components = @cache_ids.count { |c| c.start_with? name }
49
+ data[:react_cache_id] = "#{name}-#{num_components}"
43
50
  end
44
51
  end
45
52
  html_tag = html_options[:tag] || :div
@@ -58,7 +58,7 @@ module React
58
58
 
59
59
  ActiveSupport.on_load(:action_view) do
60
60
  include ::React::Rails::ViewHelper
61
- ActionDispatch::IntegrationTest.send(:include, React::Rails::TestHelper)
61
+ ActionDispatch::IntegrationTest.send(:include, React::Rails::TestHelper) if ::Rails.env.test?
62
62
  end
63
63
  end
64
64
 
@@ -12,7 +12,6 @@ module React
12
12
  assert_select "div[data-react-class=?]", name do |dom|
13
13
  if block_given?
14
14
  props = JSON.parse(dom.attr("data-react-props"))
15
- props.deep_transform_keys! { |key| key.to_s.underscore }
16
15
  props.deep_symbolize_keys!
17
16
 
18
17
  yield(props)
@@ -2,6 +2,6 @@ module React
2
2
  module Rails
3
3
  # If you change this, make sure to update VERSIONS.md
4
4
  # and republish the UJS by updating package.json and `bundle exec rake ujs:publish`
5
- VERSION = '2.5.0'
5
+ VERSION = '2.6.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: react-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul O’Shannessy
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2019-03-31 00:00:00.000000000 Z
14
+ date: 2019-07-27 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: appraisal
@@ -146,7 +146,7 @@ dependencies:
146
146
  - !ruby/object:Gem::Version
147
147
  version: 3.0.0
148
148
  - !ruby/object:Gem::Dependency
149
- name: chromedriver-helper
149
+ name: webdrivers
150
150
  requirement: !ruby/object:Gem::Requirement
151
151
  requirements:
152
152
  - - ">="
@@ -215,6 +215,20 @@ dependencies:
215
215
  - - ">="
216
216
  - !ruby/object:Gem::Version
217
217
  version: '3.2'
218
+ - !ruby/object:Gem::Dependency
219
+ name: pry-byebug
220
+ requirement: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - ">="
223
+ - !ruby/object:Gem::Version
224
+ version: '0'
225
+ type: :development
226
+ prerelease: false
227
+ version_requirements: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - ">="
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
218
232
  - !ruby/object:Gem::Dependency
219
233
  name: connection_pool
220
234
  requirement: !ruby/object:Gem::Requirement
@@ -310,6 +324,7 @@ files:
310
324
  - lib/generators/templates/component.es6.jsx
311
325
  - lib/generators/templates/component.js.jsx
312
326
  - lib/generators/templates/component.js.jsx.coffee
327
+ - lib/generators/templates/component.js.jsx.tsx
313
328
  - lib/generators/templates/react_server_rendering.rb
314
329
  - lib/generators/templates/server_rendering.js
315
330
  - lib/generators/templates/server_rendering_pack.js