如何在 rails 7 引擎中使用 tailwind css gem?

How to use tailwind css gem in a rails 7 engine?

如何在 rails 引擎中使用顺风?根据向 Rails 生成器提供 css 参数的文档应该可以工作

Rails 7.0.2.2 引擎生成使用

rails plugin new tailtest --mountable --full -d postgresql --css tailwind

这会使用 Postgresql 生成引擎,但对 tailwind 根本不执行任何操作,并且遵循手动安装说明也会失败。

运行,根据 documentationbundle add tailwindcss-rails 将 tailwind 添加到 gemfile 而不是引擎 tailtest.gemspec 所以在将依赖项添加到 gemspec

之后
spec.add_dependency "tailwindcss-rails", "~> 2.0"

和运行 bundle install确实安装了引擎,但是其余的手动安装失败了

然后将要求添加到 lib/engine.rb

require "tailwindcss-rails"
module Tailtest
  class Engine < ::Rails::Engine
    isolate_namespace Tailtest
  end
end

然后运行安装过程失败

rails tailwindcss:install
Resolving dependencies...
rails aborted!
Don't know how to build task 'tailwindcss:install' (See the list of available tasks with `rails --tasks`)
Did you mean?  app:tailwindcss:install

显然 app:tailwindcss:install 命令也失败了。

所以我可能在 engine.rb 文件中遗漏了某种初始化程序,但不知道它应该是什么。

的思路相同。我们不需要使用安装任务。即使您能够 运行 它,它对引擎也没有帮助(请参阅答案末尾的解释)。

另外 rails plugin new 没有 --css 选项。要查看可用选项:rails plugin new -h.

更新引擎的 gemspec 文件:

# my_engine/my_engine.gemspec

spec.add_dependency "tailswindcss-rails"

更新engine.rb:

# my_engine/lib/my_engine/engine.rb

module MyEngine
  class Engine < ::Rails::Engine
    isolate_namespace MyEngine

    # NOTE: add engine manifest to precompile assets in production, if you don't have this yet.
    initializer "my-engine.assets" do |app|
      app.config.assets.precompile += %w[my_engine_manifest]
    end
  end
end

更新资产清单:

# my_engine/app/assets/config/my_engine_manifest.js

//= link_tree ../builds/ .css

更新引擎的布局:

# my_engine/app/views/layouts/my_engine/application.html.erb

<!DOCTYPE html>
<html>
  <head>
   <%# 
       NOTE: make sure this name doesn't clash with anything in the main app.
             think of it as `require` and `$LOAD_PATH`,
             but instead it is `stylesheet_link_tag` and `manifest.js`.
    %>
    <%= stylesheet_link_tag "my_engine", "data-turbo-track": "reload" %>
  </head>
  <body> <%= yield %> </body>
</html>

bundle show命令会给我们安装gem的路径,所以我们可以复制几个文件:

$ bundle show tailwindcss-rails
/home/alex/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/tailwindcss-rails-2.0.8-x86_64-linux

tailswindcss-rails:

复制 tailwind.config.js 文件
$ cp $(bundle show tailwindcss-rails)/lib/install/tailwind.config.js config/tailwind.config.js

application.tailwind.css 文件复制到任何目录以适合您的设置:

$ cp $(bundle show tailwindcss-rails)/lib/install/application.tailwind.css app/assets/stylesheets/application.tailwind.css

因为 tailwindcss-rails 使用独立的可执行文件,我们不需要节点或 rails 来编译样式表。我们只需要访问可执行文件本身。

可执行文件位于此处https://github.com/rails/tailwindcss-rails/tree/v2.0.8/exe/. Instead of running the build task https://github.com/rails/tailwindcss-rails/blob/v2.0.8/lib/tasks/build.rake我们可以直接调用可执行文件。

$ $(bundle show tailwindcss-rails)/exe/tailwindcss -i app/assets/stylesheets/application.tailwind.css -o app/assets/builds/my_engine.css -c config/tailwind.config.js --minify

使用 -w 选项启动监视模式。

$ $(bundle show tailwindcss-rails)/exe/tailwindcss -i app/assets/stylesheets/application.tailwind.css -o app/assets/builds/my_engine.css -c config/tailwind.config.js --minify -w

输出文件应与 stylesheet_link_tag "my_engine" 中的名称匹配。

现在您有了一个普通的 my_engine.css 文件,可以根据需要对其进行处理。在布局中使用它,从主应用程序需要它 application.css。通常的 rails 资产管道规则适用。

如果您想将所有这些都放入任务中,请使用 Engine.root 获取路径。

# my_engine/lib/tasks/my_engine.rake

task :tailwind_engine_watch do
  require 'tailwindcss-rails'
  # NOTE: tailwindcss-rails is an engine
  system "#{Tailwindcss::Engine.root.join("exe/tailwindcss")} \
         -i #{MyEngine::Engine.root.join("app/assets/stylesheets/application.tailwind.css")} \
         -o #{MyEngine::Engine.root.join("app/assets/builds/my_engine.css")} \
         -c #{MyEngine::Engine.root.join("config/tailwind.config.js")} \
         --minify -w"
end

来自引擎目录:

$ bin/rails app:tailwind_engine_watch
+ /home/alex/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/tailwindcss-rails-2.0.8-x86_64-linux/exe/x86_64-linux/tailwindcss -i /home/alex/code/Whosebug/my_engine/app/assets/stylesheets/application.tailwind.css -o /home/alex/code/Whosebug/my_engine/app/assets/builds/my_engine.css -c /home/alex/code/Whosebug/my_engine/config/tailwind.config.js --minify -w

Rebuilding...
Done in 549ms.

如果您要设置很多引擎,请创建自己的安装任务:

desc "Install tailwindcss into our engine"
task :tailwind_engine_install do
  require 'tailwindcss-rails'

  # NOTE: use default app template, which will fail to modify layout, manifest,
  #       and the last command that compiles the initial `tailwind.css`.
  #       It will also add `bin/dev` and `Procfile.dev` which we don't need.
  #       Basically, it's useless in the engine as it is.
  template = Tailwindcss::Engine.root.join("lib/install/tailwindcss.rb")

  # TODO: better to copy the template from 
  #       https://github.com/rails/tailwindcss-rails/blob/v2.0.8/lib/install/tailwindcss.rb
  #       and customize it
  # template = MyEngine::Engine.root("lib/install/tailwindcss.rb")

  require "rails/generators"
  require "rails/generators/rails/app/app_generator"
  
  # NOTE: because the app template uses `Rails.root` it will run the install
  #       on our engine's dummy app. Just override `Rails.root` with our engine
  #       root to run install in the engine directory.
  Rails.configuration.root = MyEngine::Engine.root

  generator = Rails::Generators::AppGenerator.new [Rails.root], {}, { destination_root: Rails.root }
  generator.apply template
end

安装任务参考:

https://github.com/rails/rails/blob/v7.0.2.4/railties/lib/rails/tasks/framework.rake#L8

https://github.com/rails/tailwindcss-rails/blob/v2.0.8/lib/tasks/install.rake

看任务参考:

https://github.com/rails/tailwindcss-rails/blob/v2.0.8/lib/tasks/build.rake#L10