Skip to content

Commit d5c4717

Browse files
committed
Allow for drop-in replacement using recommended files structure
1 parent aca3294 commit d5c4717

File tree

9 files changed

+91
-12
lines changed

9 files changed

+91
-12
lines changed

lib/react/jsx.rb

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@
55

66
module React
77
module JSX
8-
# lazily loaded during first request
98
def self.context
10-
# TODO: create React::Source::contents_for
11-
contents =
12-
# If execjs uses therubyracer, there is no 'global'. Make sure
13-
# we have it so JSX script can work properly.
14-
'var global = global || this;' +
15-
File.read(React::Source.bundled_path_for('JSXTransformer.js'))
16-
@context ||= ExecJS.compile(contents)
9+
# lazily loaded during first request and reloaded every time when in dev or test
10+
unless @context && ::Rails.env.production?
11+
12+
# TODO: create React::Source::contents_for
13+
contents =
14+
# If execjs uses therubyracer, there is no 'global'. Make sure
15+
# we have it so JSX script can work properly.
16+
'var global = global || this;' +
17+
File.read(React::Source.bundled_path_for('JSXTransformer.js'))
18+
@context = ExecJS.compile(contents)
19+
end
20+
21+
@context
1722
end
1823

1924
def self.transform(code)

lib/react/rails/railtie.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,17 @@ class Railtie < ::Rails::Railtie
2828
tmp_path.join('react.js'))
2929
FileUtils.cp(::React::Source.bundled_path_for('JSXTransformer.js'),
3030
tmp_path.join('JSXTransformer.js'))
31+
app.assets.prepend_path tmp_path
3132

32-
# Make sure it can be found
33-
app.assets.append_path(tmp_path)
33+
# Allow overriding react files that are not based on environment
34+
# e.g. /vendor/react/JSXTransformer.js
35+
dropin_path = app.root.join("vendor/assets/react")
36+
app.assets.prepend_path dropin_path if dropin_path.exist?
37+
38+
# Allow overriding react files that are based on environment
39+
# e.g. /vendor/react/react.js
40+
dropin_path_env = app.root.join("vendor/assets/react/#{variant}")
41+
app.assets.prepend_path dropin_path_env if dropin_path_env.exist?
3442
end
3543
end
3644
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/** @jsx React.DOM */
2+
<div/>;

test/dummy/config/environments/test.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
# test suite. You never need to work with it otherwise. Remember that
66
# your test database is "scratch space" for the test suite and is wiped
77
# and recreated between test runs. Don't rely on the data there!
8-
config.cache_classes = true
8+
9+
# we need this to reload the jsx transformer when different version is dropped in
10+
config.cache_classes = false
11+
config.reload_plugins = true
12+
config.assets.cache_store = :null_store
913

1014
# Do not eager load code on boot. This avoids loading your whole application
1115
# just for the purpose of running a single test. If you are using a tool that
@@ -33,4 +37,6 @@
3337

3438
# Print deprecation notices to the stderr.
3539
config.active_support.deprecation = :stderr
40+
41+
config.react.variant = :test
3642
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var JSXTransformer = {
2+
transform: function () {
3+
return {
4+
code: 'test_confirmation_token_jsx_transformed;'
5+
};
6+
}
7+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
'test_confirmation_token_react_content';

test/jsxtransform_test.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'test_helper'
2+
require 'fileutils'
23

3-
# The transformer is inserting a newline after the docblock for some reason...
4+
# Sprockets is inserting a newline after the docblock for some reason...
45
EXPECTED_JS = <<eos
56
/** @jsx React.DOM */
67
@@ -28,6 +29,19 @@ class JSXTransformTest < ActionDispatch::IntegrationTest
2829
get 'assets/example.js'
2930
assert_response :success
3031
assert_equal EXPECTED_JS, @response.body
32+
FileUtils.rm_r CACHE_PATH if CACHE_PATH.exist?
33+
end
34+
35+
test 'can use dropped in version of JSX transformer' do
36+
hidden_path = File.expand_path("../dummy/vendor/assets/react/JSXTransformer__.js", __FILE__)
37+
replacing_path = File.expand_path("../dummy/vendor/assets/react/JSXTransformer.js", __FILE__)
38+
39+
FileUtils.mv hidden_path, replacing_path
40+
get 'assets/example2.js'
41+
assert_response :success
42+
assert_equal 'test_confirmation_token_jsx_transformed;', @response.body
43+
FileUtils.mv replacing_path, hidden_path
44+
FileUtils.rm_r CACHE_PATH if CACHE_PATH.exist?
3145
end
3246

3347
test 'asset pipeline should transform JSX + Coffeescript' do

test/react_test.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
require 'test_helper'
2+
require 'fileutils'
3+
4+
class ReactTest < ActionDispatch::IntegrationTest
5+
6+
test 'asset pipeline should deliver react file in a non-production variant' do
7+
actual_react_file_path = File.expand_path("../dummy/tmp/react-rails/react.js", __FILE__)
8+
actual_react_file_content = File.read actual_react_file_path
9+
10+
react_file_token = "'test_confirmation_token_react_content_non_production';\n";
11+
File.open(actual_react_file_path, 'w') {|f| f.write react_file_token}
12+
13+
get 'assets/react.js'
14+
assert_response :success
15+
assert_equal react_file_token, @response.body
16+
17+
File.open(actual_react_file_path, 'w') {|f| f.write actual_react_file_content}
18+
FileUtils.rm_r CACHE_PATH if CACHE_PATH.exist?
19+
end
20+
21+
test 'asset pipeline should deliver drop-in react file replacement' do
22+
hidden_path = File.expand_path("../dummy/vendor/assets/react/test/react__.js", __FILE__)
23+
replacing_path = File.expand_path("../dummy/vendor/assets/react/test/react.js", __FILE__)
24+
25+
FileUtils.mv hidden_path, replacing_path
26+
get 'assets/react.js'
27+
assert_response :success
28+
assert_equal "'test_confirmation_token_react_content';\n", @response.body
29+
FileUtils.mv replacing_path, hidden_path
30+
FileUtils.rm_r CACHE_PATH if CACHE_PATH.exist?
31+
end
32+
33+
end

test/test_helper.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
require File.expand_path("../dummy/config/environment.rb", __FILE__)
55
require "rails/test_help"
6+
require "pathname"
7+
8+
CACHE_PATH = Pathname.new File.expand_path("../dummy/tmp/cache", __FILE__)
69

710
Rails.backtrace_cleaner.remove_silencers!
811

0 commit comments

Comments
 (0)