Skip to content

Commit 2f5955c

Browse files
committed
refactor(JSX::Transformer) use Transformer class; allow asset_path config
1 parent 077176f commit 2f5955c

File tree

6 files changed

+69
-38
lines changed

6 files changed

+69
-38
lines changed

lib/react/jsx.rb

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,21 @@
11
require 'execjs'
22
require 'react/jsx/template'
3+
require 'react/jsx/transformer'
34
require 'rails'
45

56
module React
67
module JSX
78
mattr_accessor :transform_options
9+
def self.transform(code)
10+
transformer.transform(code)
11+
end
812

9-
def self.context
13+
def self.transformer
1014
# lazily loaded during first request and reloaded every time when in dev or test
11-
unless @context && ::Rails.env.production?
12-
contents =
13-
# If execjs uses therubyracer, there is no 'global'. Make sure
14-
# we have it so JSX script can work properly.
15-
'var global = global || this;' +
16-
17-
# search for transformer file using sprockets - allows user to override
18-
# this file in his own application
19-
File.read(::Rails.application.assets.resolve('JSXTransformer.js'))
20-
21-
@context = ExecJS.compile(contents)
15+
if @transformer.nil? || !::Rails.env.production?
16+
@transformer = Transformer.new(transform_options)
2217
end
23-
24-
@context
25-
end
26-
27-
def self.transform(code, options={})
28-
js_options = {
29-
stripTypes: options[:strip_types],
30-
harmony: options[:harmony],
31-
}
32-
result = context.call('JSXTransformer.transform', code, js_options)
33-
return result['code']
18+
@transformer
3419
end
3520
end
3621
end

lib/react/jsx/template.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def prepare
1010
end
1111

1212
def evaluate(scope, locals, &block)
13-
@output ||= JSX::transform(data, JSX.transform_options)
13+
@output ||= JSX::transform(data)
1414
end
1515
end
1616
end

lib/react/jsx/transformer.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module React
2+
module JSX
3+
class Transformer
4+
DEFAULT_ASSET_PATH = 'JSXTransformer.js'
5+
6+
def initialize(options)
7+
@strip_types = options.fetch(:strip_types, false)
8+
@harmony = options.fetch(:harmony, false)
9+
@asset_path = options.fetch(:asset_path, DEFAULT_ASSET_PATH)
10+
11+
# If execjs uses therubyracer, there is no 'global'. Make sure
12+
# we have it so JSX script can work properly.
13+
js_code = 'var global = global || this;' + jsx_transform_code
14+
@context = ExecJS.compile(js_code)
15+
end
16+
17+
18+
def transform(code)
19+
result = @context.call('JSXTransformer.transform', code, {stripTypes: @strip_types, harmony: @harmony})
20+
result["code"]
21+
end
22+
23+
def jsx_transform_code
24+
# search for transformer file using sprockets - allows user to override
25+
# this file in his own application
26+
::Rails.application.assets[@asset_path].to_s
27+
end
28+
end
29+
end
30+
end

test/jsxtransform_test.rb renamed to test/react/jsx_test.rb

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
eos
2222

2323
class JSXTransformTest < ActionDispatch::IntegrationTest
24+
setup { clear_sprockets_cache }
25+
teardown { clear_sprockets_cache }
2426

2527
test 'asset pipeline should transform JSX' do
2628
get '/assets/example.js'
@@ -40,14 +42,12 @@ class JSXTransformTest < ActionDispatch::IntegrationTest
4042
end
4143

4244
test 'can use dropped-in version of JSX transformer' do
43-
hidden_path = File.expand_path("../dummy/vendor/assets/react/JSXTransformer__.js", __FILE__)
44-
replacing_path = File.expand_path("../dummy/vendor/assets/react/JSXTransformer.js", __FILE__)
45+
hidden_path = Rails.root.join("vendor/assets/react/JSXTransformer__.js")
46+
replacing_path = Rails.root.join("vendor/assets/react/JSXTransformer.js")
4547

46-
FileUtils.mv hidden_path, replacing_path
48+
FileUtils.cp hidden_path, replacing_path
4749
get '/assets/example3.js'
48-
49-
FileUtils.mv replacing_path, hidden_path
50-
FileUtils.rm_r CACHE_PATH if CACHE_PATH.exist?
50+
FileUtils.rm replacing_path
5151

5252
assert_response :success
5353
assert_equal 'test_confirmation_token_jsx_transformed;', @response.body
@@ -69,4 +69,20 @@ class JSXTransformTest < ActionDispatch::IntegrationTest
6969
assert_response :success
7070
assert_match(/\(i\s*,\s*name\s*\)\s*\{/, @response.body, "type annotations are removed")
7171
end
72+
73+
test 'accepts asset_path: option' do
74+
hidden_path = Rails.root.join("vendor/assets/react/JSXTransformer__.js")
75+
custom_path = Rails.root.join("vendor/assets/react/custom")
76+
replacing_path = custom_path.join("CustomTransformer.js")
77+
78+
React::JSX.transform_options = {asset_path: "custom/CustomTransformer.js"}
79+
80+
FileUtils.mkdir_p(custom_path)
81+
FileUtils.cp(hidden_path, replacing_path)
82+
get '/assets/example3.js'
83+
84+
FileUtils.rm_rf custom_path
85+
assert_response :success
86+
assert_equal 'test_confirmation_token_jsx_transformed;', @response.body
87+
end
7288
end

test/react_test.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
require 'test_helper'
22
class ReactTest < ActionDispatch::IntegrationTest
33
setup do
4-
FileUtils.rm_r(CACHE_PATH) if CACHE_PATH.exist?
5-
4+
clear_sprockets_cache
65
end
76

87
teardown do
9-
FileUtils.rm_r(CACHE_PATH) if CACHE_PATH.exist?
8+
clear_sprockets_cache
109
end
1110

1211
test 'asset pipeline should deliver drop-in react file replacement' do
@@ -25,7 +24,6 @@ def react_asset.fresh?(env); false; end
2524
get '/assets/react.js'
2625

2726
File.unlink(app_react_file_path)
28-
FileUtils.rm_r(CACHE_PATH) if CACHE_PATH.exist?
2927

3028
assert_response :success
3129
assert_equal react_file_token.length, react_asset.to_s.length, "The asset pipeline serves the drop-in file"

test/test_helper.rb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

1212
Rails.backtrace_cleaner.remove_silencers!
1313

14-
# Remove cached files
15-
Rails.root.join('tmp/cache').tap do |tmp|
16-
tmp.rmtree if tmp.exist?
17-
tmp.mkpath
14+
def clear_sprockets_cache
15+
# Remove cached files
16+
Rails.root.join('tmp/cache').tap do |tmp|
17+
tmp.rmtree if tmp.exist?
18+
tmp.mkpath
19+
end
1820
end
1921

2022
# Load support files

0 commit comments

Comments
 (0)