Skip to content

Comments

CableReady installer#179

Closed
julianrubisch wants to merge 3 commits intomasterfrom
cable-ready-installer
Closed

CableReady installer#179
julianrubisch wants to merge 3 commits intomasterfrom
cable-ready-installer

Conversation

@julianrubisch
Copy link
Contributor

@julianrubisch julianrubisch commented Jan 31, 2022

I've taken a first stab at the new unified CableReady Installer, and borrowed heavily from https://github.com/hotwired/turbo-rails/blob/main/lib/tasks/turbo_tasks.rake

Let me break it down for you a bit:

I've tested many scenarios locally, but doing a bit of testing certainly wouldn't hurt 🙏

@julianrubisch julianrubisch marked this pull request as ready for review February 1, 2022 08:56
@Matt-Yorkley
Copy link
Contributor

Matt-Yorkley commented Feb 2, 2022

Hey 👋

I've been playing with CR and SR on a greenfield app that's using Vite and ran into a couple of issues with some of the install tasks for both. I took some rough notes:

The helpers_generator here fails with Vite:

main_folder = defined?(Webpacker) ? Webpacker.config.source_path.to_s.gsub("#{Rails.root}/", "") : "app/javascript"
filepath = [
"#{main_folder}/controllers/index.js",
"#{main_folder}/controllers/index.ts",
"#{main_folder}/packs/application.js",
"#{main_folder}/packs/application.ts"
]
.select { |path| File.exist?(path) }
.map { |path| Rails.root.join(path) }
.first

It assumes the main_folder is "app/javascript" and the entrypoint directory is named "packs".

A slight adjustment makes it work for either:

    main_folder = defined?(Webpacker) ? Webpacker.config.source_path.to_s.gsub("#{Rails.root}/", "") : "app/javascript"
++  main_folder = "app/frontend" if defined? ViteRuby

    filepath = [
      "#{main_folder}/controllers/index.js",
      "#{main_folder}/controllers/index.ts",
      "#{main_folder}/packs/application.js",
      "#{main_folder}/packs/application.ts",
++    "#{main_folder}/entrypoints/application.js",
++    "#{main_folder}/entrypoints/application.ts"
    ]

There are some similar install tasks in SR that also break in Vite but just need a very slightly different path. And there's this Webpacker-specific line that gets added during setup:

StimulusReflex.debug = process.env.RAILS_ENV === 'development'

which throws an error with Vite. It works with a slight (Vite-specific) adjustment:

--StimulusReflex.debug = process.env.RAILS_ENV === 'development'
++StimulusReflex.debug = import.meta.env.DEV

I'm wondering if these could be generalised a bit. I haven't tried with jsbundling-rails, but it also uses ESBuild so I assume it would be similar to Vite in regards to default paths..?

@Matt-Yorkley
Copy link
Contributor

Obviously it's annoying AF having to cater to Webpacker / Shakapacker(!) / Importmaps / jsbundling-rails / Vite, but from the DX side of things it's really nice if the install tasks Just Work™ without any issues 🤷‍♂️

@julianrubisch
Copy link
Contributor Author

Yeah, so this PR is about the main CR installer (which even doesn’t exist yet!)

shall we pull out your comment into an issue?

@julianrubisch
Copy link
Contributor Author

Closing in favor of #233

marcoroth added a commit that referenced this pull request Feb 13, 2023
This PR is the CableReady counterpart to stimulusreflex/stimulus_reflex#610.

I'm not going to rehash everything discussed in the SR installer; it is a modified subset of the same system. There are some small differences but great pains have been taken to keep everything consistent. **It is possible to install CableReady, and then add StimulusReflex to the project and install StimulusReflex at a later date.** Note that if you try to run the CableReady installer when StimulusReflex is in your project, it will exit and tell you to run the SR installer; 

It supports all major bundlers in their default configuration:

Rails 6.1: webpacker 5.4.3, shakapacker, vite
Rails 7: importmap, esbuild, shakapacker, vite

I've adapted the `cable_ready:channel` generator to work with the new installer. The `cable_ready:initializer` generator has been removed in favor of the installer.

```bash
rails cable_ready:install # fully automatic detections, with prompts
rails cable_ready:install esbuild # specify a bundler
rails cable_ready:install entrypoint=app/frontend webpacker # install with webpacker 5.4.3 in app/frontend
rails cable_ready:install:step action_cable yarn bundle # re-run one or more steps
rails cable_ready:install:restart # wipe state and restart install

rails cable_ready:install uncomment=true # uncomment any necessary includes that have been commented
rails cable_ready:install spring=false # do not remove spring (equivalent to answering `n`)
rails cable_ready:install trace=true # debug install process with full stack trace

rails cable_ready:install:step mrujs # install mrujs
rails cable_ready:install:step compression # monkey patch Action Cable to compress WS traffic with deflate

# full fat install with zero interactive prompts, suitable for scripting
rails cable_ready:install esbuild entrypoint=app/javascript uncomment=true spring=true
```

## Why should this be added

We really need to up our installation and integration game to overcome the emotional barrier people often feel when comparing us against a built-in solution. The more we can make installing CR feel like ordering a Big Mac combo, the less water "golden path" arguments hold.

Closes #179 with massive kudos to @julianrubisch for showing me how to structure an installer.
Closes #180 with apologies to @Matt-Yorkley for the delay
Fixes #130 with a hat-tip to @julianrubisch 
Fixes #131

-----

Co-authored-by: Marco Roth <[email protected]>
Co-authored-by: Julian Rubisch <[email protected]>
marcoroth added a commit to stimulusreflex/stimulus_reflex that referenced this pull request Feb 19, 2023
With sincere and genuine apologies for how long this has been in the
oven, here is my best attempt at providing a luxe, single-command
install task for SR. It builds directly on the techniques and outputs of
preceding foundational efforts by both
[Julian](stimulusreflex/cable_ready#179) and
[Marco](https://github.com/stimulusreflex/stimulus_reflex/tree/v3.5-installer).

It supports all major bundlers in their default configuration:

Rails 6.1: webpacker 5.4.3, shakapacker, vite
Rails 7: importmap, esbuild, shakapacker, vite

The installer is divided into steps which are designed to be either
generic or highly specific to one of the bundlers.

The installer uses temporary files to maintain state; one of the major
wins is that it means the setup process can fail, they can fix an issue,
and task is smart enough to resume where they left off. It will also
survive a reboot, which is something you cannot say about environment
variables.

One of the things I'm most excited about is the new `example` the
install task offers to generate. Instead of just a Reflex class and
Stimulus controller, I realized that there's huge value in creating
something that people can just run out of the box. This creates a
controller, fully self-contained view and root. Right now, it's super
minimalist, but I talk more in the Why section below about my vision for
this.

I stash an MD5 hash of `Gemfile` so that we only need to run `bundle` if
something changes. Likewise, I actually dynamically rebuild
`package.json` based on added dependencies, development dependencies and
removed dependencies. This allows us to run the dreaded, slow AF `yarn`
build process 0 or 1 times, instead of 3 times since there is no way to
combine these three operations on the command line.

I make efforts to create or modify most files in-place, but for files
like the `{entrypoint}/controllers/index.js` where it's likely they made
changes, it copies the existing file to `.bak`, generates a "perfect"
new file, and then gives them a list of such replacements at the end.

```bash
rails stimulus_reflex:install # fully automatic detections, with prompts
rails stimulus_reflex:install esbuild # specify a bundler
rails stimulus_reflex:install entrypoint=app/frontend webpacker # install with webpacker 5.4.3 in app/frontend
rails stimulus_reflex:install:step action_cable yarn bundle # re-run one or more steps
rails stimulus_reflex:install:restart # wipe state and restart install

rails stimulus_reflex:install uncomment=true # uncomment any necessary includes that have been commented
rails stimulus_reflex:install spring=false # do not remove spring (equivalent to answering `n`)
rails stimulus_reflex:install example=true # create an example page and route
rails stimulus_reflex:install trace=true # debug install process with full stack trace

rails stimulus_reflex:install:step mrujs # force install mrujs
rails stimulus_reflex:install:step compression # monkey patch Action Cable to compress WS traffic with deflate

# full fat install with zero interactive prompts, suitable for scripting
rails stimulus_reflex:install esbuild entrypoint=app/javascript uncomment=true example=true
```

## Why should this be added

First, we really need to up our installation and integration game to
overcome the emotional barrier people often feel when comparing us
against a built-in solution. The more we can make installing SR/CR feel
like ordering a Big Mac combo, the less water "golden path" arguments
hold.

Second, I am convinced that one of the most powerful things we can do to
advance the adoption of this stack is to put as much energy into the
onboarding experience as we can, and to that end, I want to develop the
built-in `example` to showcase as many core concepts and
*differentiating* features as we can on one page. I'm picturing an
engaging "long scroll" that alternates between live demos with code
examples, short lists of compelling features and maybe even a few
testimonials, like a microsite.

---

The CableReady version now lives at
stimulusreflex/cable_ready#233.

Co-authored-by: Marco Roth <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants