diff --git a/Gemfile.tt b/Gemfile.tt
index e23dd28..539c702 100644
--- a/Gemfile.tt
+++ b/Gemfile.tt
@@ -6,9 +6,9 @@ ruby "<%= RUBY_VERSION %>"
gem "active_type"
<%= gemfile_entry "bcrypt", force: true -%>
<%= gemfile_entry "bootsnap" -%>
-<%= gemfile_entry "cssbundling-rails" -%>
-<%= gemfile_entry "importmap-rails" -%>
-<%= gemfile_entry "jsbundling-rails" -%>
+<%= gemfile_entry "cssbundling-rails" unless install_vite? -%>
+<%= gemfile_entry "importmap-rails" unless install_vite? -%>
+<%= gemfile_entry "jsbundling-rails" unless install_vite? -%>
<%= gemfile_entry "pg" -%>
gem "pgcli-rails"
<%= gemfile_entry "puma" -%>
@@ -19,6 +19,7 @@ gem "sidekiq"
<%= gemfile_entry "sprockets-rails" -%>
<%= gemfile_entry "stimulus-rails" -%>
<%= gemfile_entry "turbo-rails" -%>
+<%= %Q{gem "vite_rails"\n} if install_vite? -%>
group :production do
gem "postmark-rails"
diff --git a/README.md b/README.md
index 03f3562..3b55cd6 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,16 @@ The template will perform the following steps:
## What is included?
+#### Optional support for `vite_rails`⚡️
+
+Add the `--javascript vite` option to the `rails new` command to get started with Vite! [Vite][vite] is an easy to use alternative to Webpack(er), and much more powerful than the standard import map and css/jsbundling-rails options that are built into Rails.
+
+- Frontend code (JS, CSS, images) will be placed in `app/frontend/`
+- Run `yarn start` to start the development server with hot reloading
+- SCSS will be used for styles (the `--css` option will be ignored)
+
+If you don't specify `--javascript vite`, then this template will use the standard Rails 7 behavior.
+
#### These gems are added to the standard Rails stack
* Core
@@ -119,3 +129,4 @@ Rails generators are very lightly documented; what you’ll find is that most of
[application templates]:http://guides.rubyonrails.org/generators.html#application-templates
[template.rb]: template.rb
[thor]: https://github.com/erikhuda/thor
+[vite]: https://vite-ruby.netlify.app
diff --git a/README.md.tt b/README.md.tt
index f4ed075..9322eef 100644
--- a/README.md.tt
+++ b/README.md.tt
@@ -32,10 +32,7 @@ Run the `bin/setup` script. This script will:
### Run it!
1. Run `bin/rake` to run all tests and lint checks.
-2. Start the app with `yarn start` or run these processes individually:
- - Rails: `bin/rails s -b 0.0.0.0`
- - Webpack: `bin/webpack-dev-server`
- - Sidekiq: `bin/sidekiq`
+2. Start the app with `yarn start`
Access the app at .
diff --git a/app/frontend/entrypoints/application.scss b/app/frontend/entrypoints/application.scss
new file mode 100644
index 0000000..21e656c
--- /dev/null
+++ b/app/frontend/entrypoints/application.scss
@@ -0,0 +1 @@
+@import "~/stylesheets";
diff --git a/app/frontend/template.rb b/app/frontend/template.rb
new file mode 100644
index 0000000..1dd85b3
--- /dev/null
+++ b/app/frontend/template.rb
@@ -0,0 +1,30 @@
+empty_directory_with_keep_file "app/frontend/fonts"
+empty_directory_with_keep_file "app/frontend/images"
+empty_directory "app/frontend/stylesheets/mixins"
+
+copy_file "app/assets/stylesheets/colors.scss", "app/frontend/stylesheets/colors.scss"
+copy_file "app/assets/stylesheets/application.sass.scss", "app/frontend/stylesheets/index.scss"
+copy_file "app/assets/stylesheets/mixins/typography.scss", "app/frontend/stylesheets/mixins/typography.scss"
+
+gsub_file "app/frontend/stylesheets/index.scss", /@use "\./, '@use "~/stylesheets'
+
+copy_file "app/frontend/entrypoints/application.scss"
+
+package_json = File.read("package.json")
+if package_json.match?(%r{@hotwired/turbo-rails})
+ prepend_to_file "app/frontend/entrypoints/application.js", <<~JS
+ import "@hotwired/turbo-rails";
+ JS
+end
+if package_json.match?(%r{@hotwired/stimulus})
+ prepend_to_file "app/frontend/entrypoints/application.js", <<~JS
+ import "~/controllers";
+ JS
+end
+
+# Remove sprockets
+gsub_file "Gemfile", /^gem "sprockets.*\n/, ""
+remove_file "config/initializers/assets.rb"
+remove_dir "app/assets"
+comment_lines "config/environments/development.rb", /^\s*config\.assets\./
+comment_lines "config/environments/production.rb", /^\s*config\.assets\./
diff --git a/app/template.rb b/app/template.rb
index e196c64..603a358 100644
--- a/app/template.rb
+++ b/app/template.rb
@@ -33,10 +33,20 @@ gsub_file "app/views/layouts/base.html.erb", %r{^\s*
.*}, <<-ERB
ERB
-insert_into_file "app/views/layouts/base.html.erb", <<-ERB, before: %r{^\s*}
+insert_into_file "app/views/layouts/base.html.erb", <<-ERB.rstrip, before: %r{^\s*}
<%= yield(:head) %>
ERB
+if install_vite?
+ gsub_file "app/views/layouts/base.html.erb", /^.*<%= stylesheet_link_tag.*$/, ""
+ gsub_file "app/views/layouts/base.html.erb",
+ /vite_javascript_tag 'application' %>/,
+ 'vite_javascript_tag "application", "data-turbo-track": "reload" %>'
+ insert_into_file "app/views/layouts/base.html.erb", <<-ERB, before: /^.*<%= vite_javascript_tag/
+ <%= vite_stylesheet_tag "application.scss", "data-turbo-track": "reload" %>
+ ERB
+end
+
copy_file "app/views/layouts/application.html.erb"
copy_file "app/views/shared/_flash.html.erb"
copy_file "app/views/home/index.html.erb"
diff --git a/rubocop.yml.tt b/rubocop.yml.tt
index 3e867b8..eb2ac05 100644
--- a/rubocop.yml.tt
+++ b/rubocop.yml.tt
@@ -23,6 +23,10 @@ Layout/HashAlignment:
- table
- key
+Layout/LineLength:
+ Exclude:
+ - "config/initializers/content_security_policy.rb"
+
Layout/SpaceAroundEqualsInParameterDefault:
EnforcedStyle: no_space
diff --git a/template.rb b/template.rb
index d159e81..2bf412b 100644
--- a/template.rb
+++ b/template.rb
@@ -8,6 +8,13 @@ def apply_template!
assert_postgresql
add_template_repository_to_source_path
+ if install_vite?
+ self.options = options.merge(
+ css: nil,
+ skip_asset_pipeline: true
+ )
+ end
+
template "Gemfile.tt", force: true
template "README.md.tt", force: true
@@ -34,9 +41,16 @@ def apply_template!
after_bundle do
apply "app/assets/template.rb"
+
+ if install_vite?
+ File.rename("app/javascript", "app/frontend") if File.exist?("app/javascript")
+ run_with_clean_bundler_env "bundle exec vite install"
+ run "yarn add sass"
+ apply "app/frontend/template.rb"
+ end
+
apply "app/template.rb"
- run_with_clean_bundler_env "bundle update"
create_database_and_initial_migration
run_with_clean_bundler_env "bin/setup"
@@ -207,8 +221,10 @@ def add_yarn_start_script
run_with_clean_bundler_env "yarn add --dev concurrently"
- procs = ["'bin/rails s -b 0.0.0.0'", "bin/sidekiq"]
- procs << "'bin/webpack-dev-server'" if File.exist?("bin/webpack-dev-server")
+ procs = ["'bin/rails s -b 0.0.0.0'"]
+ procs << "'bin/vite dev'" if File.exist?("bin/vite")
+ procs << "bin/webpack-dev-server" if File.exist?("bin/webpack-dev-server")
+ procs << "bin/sidekiq"
add_package_json_script(start: "concurrently --raw --kill-others-on-fail #{procs.join(" ")}")
end
@@ -240,4 +256,7 @@ def add_package_json_script(scripts)
end
end
+def install_vite?
+ options[:javascript] == "vite"
+end
apply_template!