From 8c5ceb906bb52ab7369c8d633fc839365330ae62 Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Sat, 1 Jan 2022 11:31:13 -0600 Subject: [PATCH] Add optional support for Vite (#31) * Add optional support for Vite * Keep sprockets so turbo install works; then remove it --- Gemfile.tt | 7 +++--- README.md | 11 +++++++++ README.md.tt | 5 +--- app/frontend/entrypoints/application.scss | 1 + app/frontend/template.rb | 30 +++++++++++++++++++++++ app/template.rb | 12 ++++++++- rubocop.yml.tt | 4 +++ template.rb | 25 ++++++++++++++++--- 8 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 app/frontend/entrypoints/application.scss create mode 100644 app/frontend/template.rb 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!