Ramaze + CoffeeScript: возможно ли автоматически генерировать Javascript с помощью Ramaze?

Я пытаюсь найти способ автоматически генерировать Javascript из файла CoffeeScript, как это легко сделать в Sinatra, например:

require 'sinatra'
require 'coffee-script'
get '/*.js' do
  name = params[:splat][0]
  file_name = File.join("#{name}.coffee")
  pass unless File.exists?(file_name)
  content_type(:js, :charset => 'utf-8')
  coffee(IO.read(file_name))
end

Таким образом, в моем коде я мог действовать так, как будто присутствуют .js файлов, даже если я получил только .coffee файлов. Это менее специфично и менее глючно, чем использование клиентского компилятора CoffeeScript...


person Andreas    schedule 03.07.2012    source источник


Ответы (2)


Спасибо leucos!!!

Я тоже думал о промежуточном программном обеспечении Rack, но задаюсь вопросом, не было ли более «разумного» решения (например, с врожденным).

Во всяком случае, это работает, и это здорово!

Вот модифицированная версия вашего кода:

require 'coffee-script'

# An attempt to allow Ramaze to generate Js file from coffee files
module Rack
  class BrewedCoffee
    def initialize(app, options = {})
      @app = app
      @lookup_path = options[:lookup_path].nil? ? [__DIR__] : options[:lookup_path]
    end

    def call(env)
      name = env['PATH_INFO']

      # Continue processing if requested file is not js
      return @app.call(env) if File.extname(name) != '.js'

      coffee_name = "#{name[0...-3]}.coffee"

      @lookup_path.each do |p|
        coffee_file = File.join(p, coffee_name)
        next unless File.file?(coffee_file)

        response_body = CoffeeScript.compile(File.read(coffee_file))
        headers = {}
        headers["Content-Type"] = 'application/javascript'
        headers["Content-Length"] = response_body.length.to_s

        return [200, headers, [response_body]]
      end

      @app.call(env)
    end
  end
end

Я немного подчищаю и удаляю зависимость от Ramaze, таким образом, это чисто промежуточное ПО Rack :).

Вы можете использовать его, вызывая:

m.use Rack::BrewedCoffee, :lookup_path => Ramaze.options.roots

До свидания, Андреас

person Andreas    schedule 04.07.2012
comment
На самом деле, мы оба, вероятно, заново изобретаем колесо: github.com/mattly/rack-coffee - person leucos; 04.07.2012

Лучший способ справиться с этим, вероятно, написать собственное промежуточное ПО стойки и использовать его, как показано ниже. Вероятно, вам нужно использовать какое-то кэширование, чтобы вы не перестраивали свои .js файлы из .coffee при каждом вызове.

require 'ramaze'

class BrewedCoffee
  def initialize(app)
    @app = app
  end

  def call(env)
    name = env['PATH_INFO']

    # Continue processing if requested file is not js
    return @app.call(env) if name !~ /\.js$/

    # Caching & freshness checks here...
    # ...

    # Brewing coffee
    name = name.split('.')[0..-2].join('.') + ".coffee"

    Ramaze.options.roots.each do |p|
      file_name = File.join("#{name}.coffee")
      next unless File.exists?(file_name)

      response_body = coffee(IO.read(file_name))
      headers["Content-Type"] = 'application/javascript'
      headers["Content-Length"] = response_body.length.to_s


      [status, headers, response_body]
    end

    @app.call(env)
  end
end


class MyController < Ramaze::Controller
  map '/'

  ...
end

Ramaze.middleware! :dev do |m|
  m.use(BrewedCoffee)
  m.run(Ramaze::AppMap)
end

Ramaze.start

Это быстро взломано и требует больше любви, но вы поняли идею. И вы, вероятно, не хотите делать это в продакшне, а просто предварительно строить свой кофе, иначе у вас будут проблемы с вашими сисопами :D

person leucos    schedule 04.07.2012