【问题标题】:How do I use Sprockets with Sinatra without a rackup file?如何在没有机架文件的情况下将 Sprockets 与 Sinatra 一起使用?
【发布时间】:2012-05-21 12:42:40
【问题描述】:

我正在编写一个库,其中包含通过 Thor 启动的嵌入式 Sinatra 应用程序。我想在/css/js 上挂载Sprockets::Environment 的实例,并将主应用程序映射到/。这很容易在config.ru 文件中使用Rack::URLMap,但在这种情况下没有,因为我正在使用Sinatra::Application.run! 以编程方式启动Sinatra 应用程序。我怎样才能做到这一点?

【问题讨论】:

    标签: sinatra rack sprockets


    【解决方案1】:

    其实,这并不难。您需要做的就是将Sprockets::Environment 的实例分配给 Sinatra 配置变量,并定义一些路径来查找您感兴趣的资产。

    这是一个基本的例子:

    require "sass"
    require "haml"
    require "erubis"
    require "sinatra"
    require "sprockets"
    
    set :assets, Sprockets::Environment.new
    
    # Configure sprockets
    settings.assets.append_path "app/javascripts"
    settings.assets.append_path "app/stylesheets"
    
    # For compressed JS and CSS output
    require "yui/compressor"
    settings.assets.js_compressor  = YUI::JavaScriptCompressor.new
    settings.assets.css_compressor = YUI::CssCompressor.new
    
    get "/" do
      haml :index
    end
    
    get "/javascripts/:file.js" do
      content_type "application/javascript"
      settings.assets["#{params[:file]}.js"]
    end
    
    get "/stylesheets/:file.css" do
      content_type "text/css"
      settings.assets["#{params[:file]}.css"]
    end
    

    快乐链轮!

    【讨论】:

    • 谢谢你——正是我想要的。
    • 这就像我见过的所有 sinatra-sprockets 示例一样,不起作用(或者,不再起作用)。链轮有什么变化吗?
    • @Ian 这个答案在 2012 年是合适的,但从那时起 Sinatra 和 Sprockets 都发生了很大变化。 FWIW,Sinatra 现在似乎有一个共同需求索引(这是其中之一)。查看他们推荐的 Sprockets 用法,看看是否适合您:recipes.sinatrarb.com/p/asset_management/sprockets
    【解决方案2】:

    我最终编写了一个自定义中间件,其中包含Rack::URLMap 的一些功能。大致是这样的:

    require "sprockets"
    require "sinatra/base"
    
    class SprocketsMiddleware
      attr_reader :app, :prefix, :sprockets
    
      def initialize(app, prefix)
        @app = app
        @prefix = prefix
        @sprockets = Sprockets::Environment.new
    
        yield sprockets if block_given?
      end
    
      def call(env)
        path_info = env["PATH_INFO"]
        if path_info =~ prefix
          env["PATH_INFO"].sub!(prefix, "")
          sprockets.call(env)
        else
          app.call(env)
        end
      ensure
        env["PATH_INFO"] = path_info
      end
    end
    
    class App < Sinatra::Base
      use SprocketsMiddleware, %r{/assets} do |env|
        env.append_path "assets/css"
        env.append_path "assets/js"
      end
    end
    
    App.run!
    

    【讨论】:

      【解决方案3】:

      以下是我如何将 Sprockets 集成到 Sinatra 中,并使用类似 Rails 的目录布局、帮助程序以及 JS 和 CSS 的缩小。

      我选择编写一个 Sinatra 扩展。该扩展封装了 sprockets 的配置(路径、缩小、助手),并且可以被应用程序注册。

      module Sinatra
        module Assets
          extend Sinatra::Extension
      
          configure do
            set :assets, Sprockets::Environment.new(root).tap { |assets|
              %w(assets vendor/assets).each do |base|
                %w(images javascripts stylesheets).each do |type|
                  assets.append_path File.join(base, type)
                end
              end
              if production?
                assets.js_compressor = Closure::Compiler.new
                assets.css_compressor = YUI::CssCompressor.new
                uid = Digest::MD5.hexdigest(File.dirname(__FILE__))[0,8]
                assets.cache = Sprockets::Cache::FileStore.new("/tmp/sinatra-#{uid}")
              else
                assets.cache = nil
              end
            }
          end
      
          get "/assets/*" do
            env["PATH_INFO"].sub!(%r{^/assets}, "")
            expires Time.now + (365*24*60*60) if settings.production?
            settings.assets.call(env)
          end
      
          helpers do
            include Sprockets::Helpers
      
            Sprockets::Helpers.configure do |config|
              config.expand = development?
              config.digest = production?
            end
      
            def assets_environment
              settings.assets
            end
          end
        end
      end
      

      在您的应用程序中使用扩展很简单:

      class App < Sinatra::Base
        register Sinatra::Assets
        # ...
      end
      

      资产可以放在assetsvendor/assets。例如vendor/assets/jquery.js可以被逻辑名引用,即http://localhost/assets/jquery.js

      在上面的示例中,我使用了sprockets-helpers,它提供了诸如javascript_tag 之类的帮助程序。上面给出的配置假设在开发中,您要扩展引用资产所需的资产(导致每个资产有多个标签)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-24
        • 2016-02-21
        • 2021-10-31
        相关资源
        最近更新 更多