如何让 Rails 6 与 PureCSS 和 WebPacker 一起工作

问题描述

我正在尝试将使用 PureCSS 作为样式表的 Rails 5 应用程序升级到使用 Webpacker 的 Rails 6 应用程序,除了蛮力方法之外,我没有做任何事情可以使这项工作成功。

我在 application.html.erb

中有这些行
  <%= stylesheet_pack_tag 'application',media: 'all','data-turbolinks-track': 'reload' %>
  <%= javascript_pack_tag 'application','data-turbolinks-track': 'reload' %>

我必须下载所有 PureCSS 并将文件放在 app/assets/stylesheets

然后我不得不将每个文件列为 application.js 中的导入,如图所示

    import "../../assets/stylesheets/base.css"
    import "../../assets/stylesheets/buttons.css"
    import "../../assets/stylesheets/buttons-core.css"
    import "../../assets/stylesheets/forms.css"
    import "../../assets/stylesheets/forms-r.css"`
    import "../../assets/stylesheets/menus-core.css"
    import "../../assets/stylesheets/menus-dropdown.css"
    import "../../assets/stylesheets/menus-horizontal.css"
    import "../../assets/stylesheets/menus-scrollable.css"
    import "../../assets/stylesheets/menus-skin.css"
    import "../../assets/stylesheets/tables.css"

我试图通过将导入移动到 app/assets/stylesheets/application.css

来整理它
...
 *= require_tree .
 *= require_self
 */

@import "base.css";
@import "buttons.css";
@import "buttons-core.css";
...

但是无论我尝试要求还是将 application.css 导入到 application.js 中,这都不起作用

import "../../assets/stylesheets/application.css"

require("../../assets/stylesheets/application.css")

我真的希望 purecss-sass gem 继续工作,但我真的不明白为什么它没有?

肯定有更好的方法吗?

解决方法

这里有很多东西要打开,所以请耐心等待。

肯定有更好的方法吗?

不是真的。在 Webpack 中,您可以使用 webpack-import-glob-loader 以 glob 模式加载目录中的所有文件。在 Sprockets 中,require_tree 指令会拉取整个目录。用于已贬值的 Ruby SASS 编译器的旧 sass-rails gem 可以为 @import 使用 globs(但始终不鼓励使用它)。

然而,所有这些方法的问题在于它们无法让您控制加载顺序。由于 CSS 是一种规则在声明顺序中具有优先权的语言,因此这是一种灾难。

如果您不想让 application.js 过长,请将其拆分为单独的 pure_css.js 文件并从那里导入子文件。您真的想get purecss from Yarn而不是依赖“链轮资产宝石”。

Webpack 与链轮

Rails 6 中的资产非常混乱,因为社区还没有真正找到一套最佳实践,而且文档也没有跟上。

According to David Heinemeier Hansson (DHH) Webpack 和 Sprockets 旨在与用于 JavaScript 的 Webpack 和 Sprockets 共存,以提供图像、CSS 和 JavaScript “sprinkles”(无论是什么)。

虽然 Webpack 实际上可以处理图像和 css,但它很笨拙(根据 DHH)。其他人并不认为两种不同的工具链可以做大致相同的事情。特别是因为 Sprockets 真的一直依赖社区来创建封装前端包的 gem,而且当我们都知道未来是 NPM/Yarn 时,谁愿意这样做?

Why does Rails 6 include both Webpacker and Sprockets?

链轮指令

/*
*= require_tree .
*= require_self
*/

只有在文件由链轮处理时才会实际工作。 require_tree . 将需要当前目录中的所有文件及其子文件。

但是,由于您通过 Webpack 导入文件,因此不会通过 Sprockets 拉取该文件,并且该注释只是一个普通的旧注释,完全没有任何作用。

如果你想在 css 中使用 Sprockets 而不是 Webpack,你需要 sprockets-rails gem 并且你想使用:

<%= stylesheet_link_tag 'application',media: 'all','data-turbolinks-track': 'reload' %>

如果 purecss-sass gem 的 gemspec 与 Rails 6 兼容,那么使用 Sprockets 应该允许您继续使用它。但是这种方法可能不是很适合未来。

CSS @import

在 CSS 中,@import at-rule 可用于将样式表链接在一起。您需要将 @import 与 URL 一起使用,并且样式表通过单独的 HTTP 请求加载到客户端 - 这意味着出于性能原因,通常应避免使用它。

@import "base.css"; 实际上不会工作,因为浏览器会尝试加载 http://example.com/base.css

SASS @import

@import "base.css"; 看起来像是复制粘贴的 SASS。

In SASS @import 告诉 SASS 编译器将其他文件中定义的规则、变量、mixin 和函数拉到当前文件中。与等效的 CSS 不同,这是在服务器端完成的,不会引起额外的 HTTP 请求。 @import 一直很成问题,is replaced by @use 中的 Dart SASS

如果您想使用 SASS 并避免使用已弃用的 libsass 和 Ruby 编译器,则您需要 use Webpack instead 的 Sprockets。