From 3a7123fd5e071de0137d190a5695b8fd19e8a921 Mon Sep 17 00:00:00 2001 From: Steve Polito Date: Fri, 19 Apr 2024 14:03:09 -0400 Subject: [PATCH] Styles Generator: Install `postcss-url` Closes #1190 When including styles from `node_modules` via `@import`, we discovered that static assets referenced in those style sheets are not loaded, resulting in an error. Since [cssbundling-rails][] ships with [postcss-import][], we are already encouraging the use of importing styles from `node_modules`. This commit aims to solve this problem by installing and configuring [postcss-url][]. Because `postcss-url` needs a directory to copy assets to, we create `app/assets/static` as part of the generator. One thing to note is that we override the `postcss.config.js` generated by the cssbundling-rails installation script, which assumes that the following plugins have been installed. - `postcss-import` - `postcss-nesting` - `autoprefixer` Should that change, this file would be invalid, and those packages would need to be installed. [cssbundling-rails]: https://github.com/rails/cssbundling-rails [postcss-import]: https://github.com/postcss/postcss-import [postcss-url]: https://github.com/postcss/postcss-url --- lib/generators/suspenders/styles_generator.rb | 20 +++++++++++ .../templates/styles/postcss.config.js | 11 ++++++ test/fixtures/files/postcss.config.js | 11 ++++++ .../suspenders/styles_generator_test.rb | 35 +++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 lib/generators/templates/styles/postcss.config.js create mode 100644 test/fixtures/files/postcss.config.js diff --git a/lib/generators/suspenders/styles_generator.rb b/lib/generators/suspenders/styles_generator.rb index a4703a223..cdc5feef5 100644 --- a/lib/generators/suspenders/styles_generator.rb +++ b/lib/generators/suspenders/styles_generator.rb @@ -3,6 +3,7 @@ module Generators class StylesGenerator < Rails::Generators::Base include Suspenders::Generators::APIAppUnsupported + source_root File.expand_path("../../templates/styles", __FILE__) desc <<~MARKDOWN Configures application to use PostCSS via cssbundling-rails. @@ -39,6 +40,25 @@ def configure_application_stylesheet TEXT end end + + def install_postcss_url + run "yarn add postcss-url" + end + + def configures_postcss + File.delete(postcss_config) if File.exist?(postcss_config) + + empty_directory "app/assets/static" + create_file "app/assets/static/.gitkeep" + + copy_file "postcss.config.js", "postcss.config.js" + end + + private + + def postcss_config + Rails.root.join("postcss.config.js") + end end end end diff --git a/lib/generators/templates/styles/postcss.config.js b/lib/generators/templates/styles/postcss.config.js new file mode 100644 index 000000000..9c48e607b --- /dev/null +++ b/lib/generators/templates/styles/postcss.config.js @@ -0,0 +1,11 @@ +module.exports = { + plugins: [ + require('postcss-import'), + require('postcss-nesting'), + require('autoprefixer'), + require('postcss-url')({ + url: 'copy', + assetsPath: 'app/assets/static' + }) + ], +} diff --git a/test/fixtures/files/postcss.config.js b/test/fixtures/files/postcss.config.js new file mode 100644 index 000000000..9c48e607b --- /dev/null +++ b/test/fixtures/files/postcss.config.js @@ -0,0 +1,11 @@ +module.exports = { + plugins: [ + require('postcss-import'), + require('postcss-nesting'), + require('autoprefixer'), + require('postcss-url')({ + url: 'copy', + assetsPath: 'app/assets/static' + }) + ], +} diff --git a/test/generators/suspenders/styles_generator_test.rb b/test/generators/suspenders/styles_generator_test.rb index 684d909c4..6647643d6 100644 --- a/test/generators/suspenders/styles_generator_test.rb +++ b/test/generators/suspenders/styles_generator_test.rb @@ -75,6 +75,39 @@ class StylesGeneratorTest < Rails::Generators::TestCase end end + test "installs postcss-url" do + output = run_generator + + assert_match(/add\s*postcss-url/, output) + end + + test "configures postcss.config.js" do + expected = file_fixture("postcss.config.js").read + + run_generator + + assert_file app_root("postcss.config.js") do |file| + assert_equal expected, file + end + end + + test "overrides existing postcss.config.js" do + touch "postcss.config.js", content: "unexpected" + expected = file_fixture("postcss.config.js").read + + run_generator + + assert_file app_root("postcss.config.js") do |file| + assert_equal expected, file + end + end + + test "creates directory to store static assets generated from postcss-url" do + run_generator + + assert_file app_root("app/assets/static/.gitkeep") + end + test "generator has a custom description" do assert_no_match(/Description/, generator_class.desc) end @@ -94,6 +127,8 @@ def restore_destination remove_file_if_exists "app/assets/stylesheets/base.css" remove_file_if_exists "app/assets/stylesheets/components.css" remove_file_if_exists "app/assets/stylesheets/utilities.css" + remove_file_if_exists "postcss.config.js" + remove_dir_if_exists "app/assets/static" end end end