【问题标题】:How do I exclude a .css file from loading in application.scss in Rails?如何从 Rails 中的 application.scss 加载中排除 .css 文件?
【发布时间】:2017-09-20 16:50:30
【问题描述】:

我有 YooTheme 和 Bootstrap,它们互相干扰。设计师用的是 YooTheme 做主页,我没时间翻译。如何仅在索引页中包含 yootheme.css,并将其从其他任何地方的标题中排除?我有

application.haml - 布局
/ UIkit CSS
-# %link{:rel => "stylesheet", :href => "https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.30/css/uikit.min.css"}/
%link{:rel => "stylesheet", :crossorigin => "anonymous", :href => "https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css", :integrity => "sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ"}/
= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' 
application.scss
 *= require_tree .
 *= require_self

app/assets/stylesheets/yootheme.css

index.haml
=stylesheet_link_tag 'yootheme.css', media: :all

【问题讨论】:

    标签: css ruby-on-rails ruby-on-rails-5 asset-pipeline


    【解决方案1】:

    您可以在 application.css 文件中使用sprockets#stub 和要排除的文件名,以防止其加载:

    *= stub yootheme.css
    

    然后要手动合并它,您必须将文件添加到您的 assets.rb,重新启动服务器,然后使用 stylesheet_link_tag 帮助程序自行加载文件:

    # config/initializers/assets.rb
    # Rails.application.config.assets.precompile += %w( yootheme.css )
    
    # view
    = stylesheet_link_tag 'yootheme.css', media: :all
    

    【讨论】:

    • 很漂亮 - 但你应该避免在 SASS/SCSS 中使用 sprockets 指令,因为它们不能很好地与 Sass 编译器配合使用。我也真的不明白这将如何在部署设置中进行编译。
    • 或者您是否将*= stub yootheme.css 指令留在其中并且重新启动以触发资产重新编译?
    【解决方案2】:

    不要在 SASS/SCSS 中使用 require_tree

    Sprockets 提供了一些放置在 cmets 内部的指令 称为 require、require_tree 和 require_self。 不要在你的 SASS/SCSS 文件中使用它们。它们非常原始,不能很好地处理 Sass 文件。而是使用 Sass 的原生 sass-rails 自定义集成的 @import 指令 Rails 项目的约定。 https://github.com/rails/sass-rails

    如果您不使用任何 Sass 功能,例如变量、函数、mixins 等,您可以使用require_tree。但是,一旦您这样做,您就会意识到它们在任何文件中都不可用,除非在它们被声明的文件中。那是因为在 Sprockets 将文件连接在一起之前,每个文件都在 SASS 编译器中运行。

    因此,您最好使用@import 'foo' 并手动声明应将哪些文件及其添加到已编译样式表的顺序。

    它并不像听起来那么糟糕

    默认资产管道设置是一个很好的尝试,可以让懒惰的程序员不要将所有内容都塞进单个 css/js 文件中,同时仍将其编译为单个优化文件。它确实需要require_tree . 才有意义。

    我通常会关闭资产生成器:

    # config/application.rb
    module MyApp
      class Application < Rails::Application
        config.generators do |g|
          g.assets false
          # or
          g.stylesheets false
        end
      end
    end
    

    相反,我故意将app/assets 中的代码组织成模块。任何不是我的代码都会进入/vendor

    您可以使用 glob imports 从库文件夹中导入 sass mixins 和变量 - 但它不能/不应替换 require_tree

    使用 content_for 代替单独的布局

    使用单独的布局意味着您必须复制整个文件才能更改一两行。

    您可以使用content_for 在布局中创建动态块:

    # application.html.haml:
    !!!
    %html
      %head
        %title My Rails app
        - content_for :assets
          = stylesheet_link_tag "application"
          = javascript_include_tag "application"
        = csrf_meta_tag
    
      %body
        = yield
    

    然后稍后在index 模板中我们可以添加到head 部分:

    - content_for :assets
      = stylesheet_link_tag "some_other_file"
    

    这将在= javascript_include_tag "application" 下添加样式表链接,因为 content_for 将提供的块连接到已捕获的内容。使用flush: true 丢弃任何以前提供的内容(按布局)。

    - content_for :assets, flush: true
      = stylesheet_link_tag "some_other_file"
    

    【讨论】:

    • 即使你没有使用 sass,在 sprockets 中贪婪的 require_tree 指令也无法控制文件的包含方式(按字母顺序)。在 CSS 中,作为指令的公牛按照定义的顺序具有优先级。所以我真正的收获是提防require_tree
    • "这是因为在 Sprockets 将文件连接在一起之前,每个文件都在 SASS 编译器中运行。"这就解释了为什么我必须在所有文件中重复 @import "colors.scss";
    【解决方案3】:

    类似的东西

    index.haml(布局) ..

    - if action_name=="index"
       /* include both application.css and yootheme.css for index*/
       = stylesheet_link_tag 'application', 'yootheme.css', media: :all
    - else
       /* include only application.css*/
       =stylesheet_link_tag 'application, media: :all
    

    【讨论】:

    • 两种布局仍将包含stylesheet_link_tag 'application',并且仍将包含yootheme.css。如何排除yootheme.css
    • @Chloe 检查上面的答案。您可以进行基于操作的资产加载
    猜你喜欢
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 2013-04-15
    • 1970-01-01
    • 2016-11-12
    相关资源
    最近更新 更多