如何在没有机架文件的情况下将Sprockets与Sinatra一起使用?

Jim*_*dra 10 rack sinatra sprockets

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

Dam*_*son 13

实际上,这并不难.您需要做的就是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
Run Code Online (Sandbox Code Playgroud)

快乐的sprocketing!


Jim*_*dra 5

我最终通过编写具有一些功能的自定义中间件来完成它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!
Run Code Online (Sandbox Code Playgroud)