Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dev scripts to bin directory on install #1491

Merged
merged 13 commits into from
Jan 9, 2023
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ RSpec/AnyInstance:
Exclude:
- 'spec/react_on_rails/git_utils_spec.rb'
- 'spec/react_on_rails/locales_to_js_spec.rb'
- 'spec/react_on_rails/binstubs/dev_spec.rb'
- 'spec/react_on_rails/binstubs/dev_static_spec.rb'

RSpec/DescribeClass:
Enabled: false
Expand All @@ -111,6 +113,8 @@ RSpec/BeforeAfterAll:
Exclude:
- 'spec/react_on_rails/generators/dev_tests_generator_spec.rb'
- 'spec/react_on_rails/generators/install_generator_spec.rb'
- 'spec/react_on_rails/binstubs/dev_spec.rb'
- 'spec/react_on_rails/binstubs/dev_static_spec.rb'

RSpec/MessageChain:
Enabled: false
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Please follow the recommendations outlined at [keepachangelog.com](http://keepac
Changes since last non-beta release.

*Please add entries here for your pull requests that are not yet released.*
- Added `./bin/dev` and `./bin/dev-static` executables to ease and standardize running the dev server. [PR 1491](https://github.com/shakacode/react_on_rails/pull/1491) by [ahangarha](https://github.com/ahangarha)

### [13.2.0] - 2022-12-23

Expand Down
16 changes: 11 additions & 5 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ generated using `rails new my_app --javascript=webpack`). If your
application is not yet set up to use webpacker, please see
[the instructions for installing into an existing Rails app](https://www.shakacode.com/react-on-rails/docs/guides/installation-into-an-existing-rails-app/).*

1. Add the `react_on_rails` gem to Gemfile:
1. Add the `shakapacker` and `react_on_rails` gem to Gemfile:

```bash
bundle add shakapacker --strict
bundle add react_on_rails --strict
```

2. Commit this to git (or else you cannot run the generator unless you pass the option `--ignore-warnings`).
2. Run installation command for webpacker:

```bash
rails webpacker:install
```

3. Commit this to git (or else you cannot run the generator unless you pass the option `--ignore-warnings`).

3. Run the generator:

Expand All @@ -30,9 +37,8 @@ application is not yet set up to use webpacker, please see

4. Start the app:

```bash
rails s
```
- Run `./bin/dev` for HMR
- Run `./bin/dev-static` for statically created bundles (no HMR)

5. Visit http://localhost:3000/hello_world.

Expand Down
66 changes: 35 additions & 31 deletions docs/guides/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,58 +45,58 @@ Then we need to create a fresh Rails application as following.
First be sure to run `rails -v` and check you are using Rails 5.1.3 or above. If you are using an older version of Rails, you'll need to install webpacker with react per the instructions [here](https://github.com/rails/webpacker).

```bash
cd <directory where you want to create your new Rails app>
# For Rails 6.x
rails new test-react-on-rails --skip-javascript

# Any name you like for the rails app
# Skip javascript so will add that next and get the current version
# This is for Rails 7
# For Rails 7.x
rails new test-react-on-rails --skip-turbolinks --skip-javascript

cd test-react-on-rails
```

## Add the shakapacker and react_on_rails gems
To avoid issues regarding inconsistent gem and npm versions, you should specify the exact versions
of both the gem and npm package. In other words, don't use the `^` or `~` in the version specifications.
_Use the latest version for `react_on_rails` and `shakapacker`._

```
gem 'react_on_rails', '13.0.1' # prefer exact gem version to match npm version
gem 'shakapacker', '6.4.0' # prefer exact gem version to match npm version
We recommend using the latest version of these gems. Otherwise, specify the
exact versions of both the gem and npm package. In other words, don't use
the `^` or `~` in the version specifications.

```bash
bundle add react_on_rails --strict
bundle add shakapacker --strict
```

Note: The latest released React On Rails version is considered stable. Please use the latest
version to ensure you get all the security patches and the best support.

## Run the shakapacker (webpacker) generator

```terminal
```bash
bundle exec rails webpacker:install
```

**Let's commit everything before installing React on Rails.**
Commit all the changes so far to avoid getting errors in the next step.

```bash
git commit -am "Initial commit"
```
# Here are git commands to make a new git repo and commit everything.
# Newer versions of Rails create the git repo by default.
git add -A
git commit -m "Initial commit"
```

Alternatively you can use `--ignore-warnings` in the next step.

## Run the React on Rails Generator

Install React on Rails: `rails generate react_on_rails:install`. You need to first git commit your files before running the generator, or else it will generate an error.
```bash
rails generate react_on_rails:install
```

You will be prompted to approve changes in certain files. Press `enter` to proceed
one by one or enter `a` to replace all configuration files required by the project.
You can check the diffs before you commit to see what changed.

Note, using `redux` is no longer recommended as the basic installer uses React Hooks.
If you want the redux install: `rails generate react_on_rails:install --redux`
If you want the redux install, run:

```bash
rails generate react_on_rails:install --redux
```
bundle exec rails generate react_on_rails:install
```

Enter `a` to replace all configuration files required by the project. You can check the diffs
before you commit to see what changed.

## Setting up your environment variables

Expand All @@ -108,14 +108,18 @@ EXECJS_RUNTIME=Node

Then run the server with one of the following options:

## Running with HMR
```
foreman start -f Procfile.dev
```
## Running the app

## Running without HMR, statically creating the bundles
### For HMR:

```bash
./bin/dev
```
foreman start -f Procfile.dev-static

### Without HMR, statically creating the bundles

```bash
./bin/dev-static
```

Visit [http://localhost:3000/hello_world](http://localhost:3000/hello_world) and see your **React On Rails** app running!
Expand Down
25 changes: 15 additions & 10 deletions lib/generators/react_on_rails/base_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ def self.helpful_message

<%= javascript_pack_tag 'hello-world-bundle' %>

- To start Rails server run:

./bin/dev # Running with HMR

or

./bin/dev # Running with statically created bundles, without HMR

- To server render, change this line app/views/hello_world/index.html.erb to
`prerender: true` to see server rendering (right click on page and select "view source").

<%= react_component("HelloWorldApp", props: @hello_world_props, prerender: true) %>

Alternative steps to run the app:

- Run `rails s` to start the Rails server.

- Run bin/webpacker-dev-server to start the Webpack dev server for compilation of Webpack
Expand All @@ -152,18 +167,8 @@ def self.helpful_message

- Visit http://localhost:3000/hello_world and see your React On Rails app running!

- Alternately, run the foreman command to start the rails server and run webpack#{' '}
in watch mode.

foreman start -f Procfile.dev-static

- To turn on HMR, edit config/webpacker.yml and set HMR to true. Restart the rails server
and bin/webpacker-dev-server. Or use Procfile.dev.

- To server render, change this line app/views/hello_world/index.html.erb to
`prerender: true` to see server rendering (right click on page and select "view source").

<%= react_component("HelloWorldApp", props: @hello_world_props, prerender: true) %>
MSG
end

Expand Down
33 changes: 33 additions & 0 deletions lib/generators/react_on_rails/bin/dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

def installed?(process)
IO.popen "#{process} -v"
rescue Errno::ENOENT
false
end

def run(process)
args = [*ARGV]
args.shift
puts "Using #{process}"
exec "#{process} start -f Procfile.dev", args.join(" ")
rescue Errno::ENOENT
warn <<~MSG
ERROR:
Please ensure `Procfile.dev` exist in your project!
MSG
exit!
end

if installed? "overmind"
run "overmind"
elsif installed? "foreman"
run "foreman"
else
warn <<~MSG
NOTICE:
For this script to run, you need either 'overmind' or 'foreman' installed on your machine. Please try this script after installing one of them.
MSG
exit!
end
33 changes: 33 additions & 0 deletions lib/generators/react_on_rails/bin/dev-static
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

def installed?(process)
IO.popen "#{process} -v"
rescue Errno::ENOENT
false
end

def run(process)
args = [*ARGV]
args.shift
puts "Using #{process}"
exec "#{process} start -f Procfile.dev-static", args.join(" ")
rescue Errno::ENOENT
warn <<~MSG
ERROR:
Please ensure `Procfile.dev-static` exist in your project!
MSG
exit!
end

if installed? "overmind"
run "overmind"
elsif installed? "foreman"
run "foreman"
else
warn <<~MSG
NOTICE:
For this script to run, you need either 'overmind' or 'foreman' installed on your machine. Please try this script after installing one of them.
MSG
exit!
end
5 changes: 5 additions & 0 deletions lib/generators/react_on_rails/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class InstallGenerator < Rails::Generators::Base
def run_generators
if installation_prerequisites_met? || options.ignore_warnings?
invoke_generators
add_bin_scripts
else
error = "react_on_rails generator prerequisites not met!"
GeneratorMessages.add_error(error)
Expand Down Expand Up @@ -75,6 +76,10 @@ def missing_node?
GeneratorMessages.add_error(error)
true
end

def add_bin_scripts
directory "#{__dir__}/bin", "bin"
end
end
end
end
65 changes: 65 additions & 0 deletions spec/react_on_rails/binstubs/dev_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# frozen_string_literal: true

RSpec.describe "bin/dev script" do
let(:script_path) { "lib/generators/react_on_rails/bin/dev" }

# To suppress stdout during tests
original_stderr = $stderr
original_stdout = $stdout
before(:all) do
$stderr = File.open(File::NULL, "w")
$stdout = File.open(File::NULL, "w")
end

after(:all) do
$stderr = original_stderr
$stdout = original_stdout
end

it "with Overmind installed, uses Overmind" do
allow(IO).to receive(:popen).with("overmind -v").and_return("Some truthy result")

expect_any_instance_of(Kernel).to receive(:exec).with("overmind start -f Procfile.dev", "")

load script_path
end

it "without Overmind and with Foreman installed, uses Foreman" do
allow(IO).to receive(:popen).with("overmind -v").and_raise(Errno::ENOENT)
allow(IO).to receive(:popen).with("foreman -v").and_return("Some truthy result")

expect_any_instance_of(Kernel).to receive(:exec).with("foreman start -f Procfile.dev", "")

load script_path
end

it "without Overmind and Foreman installed, exits with error message" do
allow(IO).to receive(:popen).with("overmind -v").and_raise(Errno::ENOENT)
allow(IO).to receive(:popen).with("foreman -v").and_raise(Errno::ENOENT)
allow_any_instance_of(Kernel).to receive(:exit!)

expected_message = <<~MSG
NOTICE:
For this script to run, you need either 'overmind' or 'foreman' installed on your machine. Please try this script after installing one of them.
MSG

expect { load script_path }.to output(expected_message).to_stderr_from_any_process
end

it "With Overmind and without Procfile, exits with error message" do
allow(IO).to receive(:popen).with("overmind -v").and_return("Some truthy result")

allow_any_instance_of(Kernel)
.to receive(:exec)
.with("overmind start -f Procfile.dev", "")
.and_raise(Errno::ENOENT)
allow_any_instance_of(Kernel).to receive(:exit!)

expected_message = <<~MSG
ERROR:
Please ensure `Procfile.dev` exist in your project!
MSG

expect { load script_path }.to output(expected_message).to_stderr_from_any_process
end
end
Loading