├── fixtures
└── app
│ ├── config.rb
│ └── source
│ └── assets
│ └── javascripts
│ ├── plain_jsx.js.jsx
│ └── coffeescript.js.jsx.coffee
├── script
├── spec
└── bootstrap
├── .travis.yml
├── Gemfile
├── lib
├── middleman-react.rb
└── middleman-react
│ ├── version.rb
│ ├── jsx
│ └── template.rb
│ ├── extension.rb
│ └── jsx.rb
├── spec
└── features
│ ├── support
│ └── env.rb
│ ├── jsx.feature
│ └── coffeescript.feature
├── .gitignore
├── LICENSE
├── middleman-react.gemspec
├── README.md
└── Gemfile.lock
/fixtures/app/config.rb:
--------------------------------------------------------------------------------
1 | activate :react
2 |
--------------------------------------------------------------------------------
/fixtures/app/source/assets/javascripts/plain_jsx.js.jsx:
--------------------------------------------------------------------------------
1 | /** @jsx React.DOM */
2 |
;
3 |
--------------------------------------------------------------------------------
/script/spec:
--------------------------------------------------------------------------------
1 | #!/bin/sh -xe
2 |
3 | bundle --binstubs --quiet
4 |
5 | bin/rubocop lib
6 | bin/cucumber spec/features
7 |
--------------------------------------------------------------------------------
/script/bootstrap:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | [ `which bundle` ] || gem install bundler
4 |
5 | bundle --binstubs --quiet
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | bundler_args: --binstubs
3 | rvm:
4 | - 2.1.0
5 | - 2.0.0
6 | - 1.9.3
7 | script:
8 | - script/spec
9 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gemspec
4 |
5 | group :development do
6 | gem "rake", "~> 0.9.2"
7 | gem "rdoc", "~> 3.9"
8 | gem "yard", "~> 0.8.0"
9 | end
10 |
--------------------------------------------------------------------------------
/lib/middleman-react.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 |
3 | require 'middleman-core'
4 |
5 | ::Middleman::Extensions.register(:react) do
6 | require 'middleman-react/extension'
7 | ::Middleman::React::Extension
8 | end
9 |
--------------------------------------------------------------------------------
/lib/middleman-react/version.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 |
3 | module Middleman
4 | # Gem packaging constants
5 | module React
6 | PACKAGE = 'middleman-react'
7 | VERSION = '0.11.1'
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/fixtures/app/source/assets/javascripts/coffeescript.js.jsx.coffee:
--------------------------------------------------------------------------------
1 | ###* @jsx React.DOM ###
2 |
3 | @app.components.test = React.createClass
4 | render: ->
5 | `
6 |
7 |
`
8 |
--------------------------------------------------------------------------------
/spec/features/support/env.rb:
--------------------------------------------------------------------------------
1 | ENV["TEST"] = "true"
2 |
3 | PROJECT_ROOT_PATH = File.join(File.dirname(__FILE__), '../../../')
4 |
5 | require "middleman-core"
6 | require "middleman-core/step_definitions"
7 | require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-react')
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | *.rbc
3 | .bundle
4 | .config
5 | coverage
6 | InstalledFiles
7 | lib/bundler/man
8 | pkg
9 | rdoc
10 | spec/reports
11 | test/tmp
12 | test/version_tmp
13 | tmp
14 | bin
15 | fixtures/build
16 |
17 | # YARD artifacts
18 | .yardoc
19 | _yardoc
20 | doc/
21 |
--------------------------------------------------------------------------------
/lib/middleman-react/jsx/template.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 |
3 | require 'tilt'
4 |
5 | module Middleman
6 | module React
7 | # Tilt Tempalte for handling JSX files
8 | class Template < Tilt::Template
9 | self.default_mime_type = 'application/javascript'
10 |
11 | def prepare; end
12 |
13 | def evaluate(scope, locals, &block)
14 | @output ||= JSX.transform(data)
15 | end
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/middleman-react/extension.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 |
3 | require 'middleman-core'
4 | require 'middleman-react/jsx'
5 | require 'middleman-react/jsx/template'
6 |
7 | module Middleman
8 | module React
9 | # Middleman extension entry point
10 | class Extension < Middleman::Extension
11 | def initialize(app, options_hash = {}, &block)
12 | ::Tilt.register 'jsx', Middleman::React::Template
13 | ::Sprockets.register_engine 'jsx', Middleman::React::Template
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/features/jsx.feature:
--------------------------------------------------------------------------------
1 | Feature: Transforming JSX into Javascript
2 | Background:
3 | Given a fixture app "app"
4 | Given a successfully built app at "app"
5 |
6 | Scenario: A simple JSX file
7 | When I cd to "build"
8 | Then the following files should exist:
9 | | assets/javascripts/plain_jsx.js |
10 | When I run `cat assets/javascripts/plain_jsx.js`
11 | Then the stdout from "cat assets/javascripts/plain_jsx.js" should contain exactly:
12 | """
13 | /** @jsx React.DOM */
14 | React.DOM.div(null);
15 |
16 | """
17 | And the exit status should be 0
18 |
--------------------------------------------------------------------------------
/lib/middleman-react/jsx.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 |
3 | require 'execjs'
4 | require 'react/source'
5 |
6 | module Middleman
7 | module React
8 | # Methods for invoking the JSXTransformer via ExecJS
9 | module JSX
10 | def self.context
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)
17 | end
18 |
19 | def transform(code)
20 | context.call('JSXTransformer.transform', code)['code']
21 | end
22 | module_function :transform
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/spec/features/coffeescript.feature:
--------------------------------------------------------------------------------
1 | Feature: Transforming JSX into Javascript when it is written in Coffeescript
2 | Background:
3 | Given a fixture app "app"
4 | Given a successfully built app at "app"
5 |
6 | Scenario: A JSX file written in coffeescript
7 | When I cd to "build"
8 | Then the following files should exist:
9 | | assets/javascripts/coffeescript.js |
10 | When I run `cat assets/javascripts/coffeescript.js`
11 | Then the stdout from "cat assets/javascripts/coffeescript.js" should contain exactly:
12 | """
13 |
14 | /** @jsx React.DOM */
15 |
16 | (function() {
17 | this.app.components.test = React.createClass({displayName: 'test',
18 | render: function() {
19 | return React.DOM.div(null,
20 | TestComponent({data: this.props.someData})
21 | );
22 | }
23 | });
24 |
25 | }).call(this);
26 |
27 | """
28 | And the exit status should be 0
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Justin Morris
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/middleman-react.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | $:.push File.expand_path("../lib", __FILE__)
3 | require File.expand_path('../lib/middleman-react/version', __FILE__)
4 |
5 | Gem::Specification.new do |gem|
6 | gem.name = Middleman::React::PACKAGE
7 | gem.version = Middleman::React::VERSION
8 | gem.platform = Gem::Platform::RUBY
9 | gem.authors = ["Justin Morris"]
10 | gem.email = ["desk@pixelbloom.com"]
11 | gem.homepage = "https://github.com/plasticine/middleman-react"
12 | gem.summary = %q{Ruby gem for automatically transforming JSX and using React in Middleman.}
13 | gem.description = %q{Ruby gem for automatically transforming JSX and using React in Middleman.}
14 | gem.license = 'MIT'
15 | gem.files = `git ls-files`.split("\n")
16 | gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17 | gem.require_paths = ["lib"]
18 |
19 | gem.add_dependency "middleman-core", [">= 3.0"]
20 | gem.add_dependency "execjs"
21 | gem.add_dependency "react-source", "~> 0.11.1"
22 |
23 | gem.add_development_dependency "aruba"
24 | gem.add_development_dependency "cane"
25 | gem.add_development_dependency "cucumber"
26 | gem.add_development_dependency "middleman", '~> 3.2'
27 | gem.add_development_dependency "pry"
28 | gem.add_development_dependency "rake"
29 | gem.add_development_dependency "rspec"
30 | gem.add_development_dependency "rubocop"
31 | end
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | middleman-react [](http://badge.fury.io/rb/middleman-react) [](https://travis-ci.org/plasticine/middleman-react) [](https://codeclimate.com/github/plasticine/middleman-react)
2 | ===============
3 |
4 | ### Use [React] JSX transformations with [Middleman].
5 |
6 | Inspired (and pretty much a clone of really) the [react-rails] gem for Middleman. This gem allows you to write and use `*.jsx` assets inside Middleman.
7 |
8 | #### Usage
9 | 1. `gem install middleman-react`
10 | 2. `activate :react` in `config.rb`
11 |
12 |
13 | #### Sprockets loading react-source
14 |
15 | In your Middleman `config.rb` add the following:
16 |
17 | ``` ruby
18 | after_configuration do
19 | sprockets.append_path File.dirname(::React::Source.bundled_path_for('react.js'))
20 | end
21 | ```
22 |
23 | Now you can Sprockets include React:
24 |
25 | ```
26 | //= require react
27 | ```
28 |
29 | Or with addons:
30 |
31 | ```
32 | //= require react-with-addons
33 | ```
34 |
35 | #### Developing / Contributing
36 | 1. Fork it!
37 | 2. Get set up: `./script/bootstrap`
38 | 3. ...?
39 | 4. Run specs: `./script/spec`
40 | 5. Pull request!
41 |
42 | [React]: http://facebook.github.io/react/
43 | [Middleman]: http://middlemanapp.com
44 | [react-rails]: https://github.com/facebook/react-rails
45 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | middleman-react (0.11.1)
5 | execjs
6 | middleman-core (>= 3.0)
7 | react-source (~> 0.11.1)
8 |
9 | GEM
10 | remote: https://rubygems.org/
11 | specs:
12 | activesupport (3.2.16)
13 | i18n (~> 0.6, >= 0.6.4)
14 | multi_json (~> 1.0)
15 | aruba (0.5.4)
16 | childprocess (>= 0.3.6)
17 | cucumber (>= 1.1.1)
18 | rspec-expectations (>= 2.7.0)
19 | ast (1.1.0)
20 | builder (3.2.2)
21 | cane (2.6.1)
22 | parallel
23 | childprocess (0.4.0)
24 | ffi (~> 1.0, >= 1.0.11)
25 | chunky_png (1.2.9)
26 | coderay (1.1.0)
27 | coffee-script (2.2.0)
28 | coffee-script-source
29 | execjs
30 | coffee-script-source (1.7.0)
31 | compass (0.12.2)
32 | chunky_png (~> 1.2)
33 | fssm (>= 0.2.7)
34 | sass (~> 3.1)
35 | cucumber (1.3.10)
36 | builder (>= 2.1.2)
37 | diff-lcs (>= 1.1.3)
38 | gherkin (~> 2.12)
39 | multi_json (>= 1.7.5, < 2.0)
40 | multi_test (>= 0.0.2)
41 | diff-lcs (1.2.5)
42 | execjs (1.4.0)
43 | multi_json (~> 1.0)
44 | ffi (1.9.3)
45 | fssm (0.2.10)
46 | gherkin (2.12.2)
47 | multi_json (~> 1.3)
48 | haml (4.0.5)
49 | tilt
50 | hike (1.2.3)
51 | i18n (0.6.9)
52 | json (1.8.1)
53 | kramdown (1.3.1)
54 | listen (1.3.1)
55 | rb-fsevent (>= 0.9.3)
56 | rb-inotify (>= 0.9)
57 | rb-kqueue (>= 0.2)
58 | method_source (0.8.2)
59 | middleman (3.2.2)
60 | coffee-script (~> 2.2.0)
61 | compass (>= 0.12.2)
62 | execjs (~> 1.4.0)
63 | haml (>= 3.1.6)
64 | kramdown (~> 1.2)
65 | middleman-core (= 3.2.2)
66 | middleman-sprockets (>= 3.1.2)
67 | sass (>= 3.1.20)
68 | uglifier (~> 2.4.0)
69 | middleman-core (3.2.2)
70 | activesupport (~> 3.2.6)
71 | bundler (~> 1.1)
72 | i18n (~> 0.6.9)
73 | listen (~> 1.1)
74 | rack (>= 1.4.5)
75 | rack-test (~> 0.6.1)
76 | thor (>= 0.15.2, < 2.0)
77 | tilt (~> 1.4.1)
78 | middleman-sprockets (3.2.0)
79 | middleman-core (~> 3.2)
80 | sprockets (~> 2.1)
81 | sprockets-helpers (~> 1.0.0)
82 | sprockets-sass (~> 1.0.0)
83 | multi_json (1.8.4)
84 | multi_test (0.0.3)
85 | parallel (0.9.2)
86 | parser (2.1.4)
87 | ast (~> 1.1)
88 | slop (~> 3.4, >= 3.4.5)
89 | powerpack (0.0.9)
90 | pry (0.9.12.6)
91 | coderay (~> 1.0)
92 | method_source (~> 0.8)
93 | slop (~> 3.4)
94 | rack (1.5.2)
95 | rack-test (0.6.2)
96 | rack (>= 1.0)
97 | rainbow (2.0.0)
98 | rake (0.9.6)
99 | rb-fsevent (0.9.4)
100 | rb-inotify (0.9.3)
101 | ffi (>= 0.5.0)
102 | rb-kqueue (0.2.0)
103 | ffi (>= 0.5.0)
104 | rdoc (3.12.2)
105 | json (~> 1.4)
106 | react-source (0.11.1)
107 | rspec (2.14.1)
108 | rspec-core (~> 2.14.0)
109 | rspec-expectations (~> 2.14.0)
110 | rspec-mocks (~> 2.14.0)
111 | rspec-core (2.14.7)
112 | rspec-expectations (2.14.5)
113 | diff-lcs (>= 1.1.3, < 2.0)
114 | rspec-mocks (2.14.5)
115 | rubocop (0.18.1)
116 | json (>= 1.7.7, < 2)
117 | parser (~> 2.1.3)
118 | powerpack (~> 0.0.6)
119 | rainbow (>= 1.99.1, < 3.0)
120 | sass (3.2.14)
121 | slop (3.4.7)
122 | sprockets (2.10.1)
123 | hike (~> 1.2)
124 | multi_json (~> 1.0)
125 | rack (~> 1.0)
126 | tilt (~> 1.1, != 1.3.0)
127 | sprockets-helpers (1.0.1)
128 | sprockets (~> 2.0)
129 | sprockets-sass (1.0.2)
130 | sprockets (~> 2.0)
131 | tilt (~> 1.1)
132 | thor (0.18.1)
133 | tilt (1.4.1)
134 | uglifier (2.4.0)
135 | execjs (>= 0.3.0)
136 | json (>= 1.8.0)
137 | yard (0.8.7.3)
138 |
139 | PLATFORMS
140 | ruby
141 |
142 | DEPENDENCIES
143 | aruba
144 | cane
145 | cucumber
146 | middleman (~> 3.2)
147 | middleman-react!
148 | pry
149 | rake (~> 0.9.2)
150 | rdoc (~> 3.9)
151 | rspec
152 | rubocop
153 | yard (~> 0.8.0)
154 |
--------------------------------------------------------------------------------