Gem Sprockets - 在 Rails 之外 (例如 Sinatra) 使用 Assets Pipeline

huacnlee · 2016年10月18日 · 3448 次阅读

Ruby on Rails 的 Assets Pipeline 是一个非常好用的特性,我们有一站式的前端打包编译解决方案。

但你知道吗?脱离了 Rails 我们还是可以用这个功能的哦,它其实在 Sprockets 这个 Gem 里面。

Sprockets is a Ruby library for compiling and serving web assets. It features declarative dependency management for JavaScript and CSS assets, as well as a powerful preprocessor pipeline that allows you to write assets in languages like CoffeeScript, Sass and SCSS. -- https://github.com/rails/sprockets

使用方式

我们可以在任意基于 Rack 的 Ruby 框架(例如 Sinatra)下很容易的使用 sprockets。

├── assets
│   ├── stylesheets
│   │   ├── app.scss
│   │   └── bootstrap.min.css
│   └── javascripts
│       ├── bootstrap.min.js
│       ├── jquery.min.js
│       └── app.coffee
├── views
│   ├── index.erb
│   ├── layout.erb
│   └── not_found.erb
├── environment.rb
├── app.rb
├── Gemfile
├── Gemfile.lock
├── README.md
└──config.ru

Gemfile 增加 sprockets

gem 'sprockets'

group :development do
  gem 'coffee-script'
  gem 'sass'
end

新增一个 environment.rb 用于准备 sprockets 环境:

require 'bundler/setup'
require 'sprockets'

# 准备好 sprockets,弄成全局变量为的是在 erb 里面用它生成带 digest 的 asset path
$sprockets = Sprockets::Environment.new
%w(javascripts stylesheets images fonts).each do |name|
  $sprockets.append_path "assets/#{name}"
end

config.ru

require_relative './environment'
require_relative './app'

# map /assets 交给 sprockets 处理
map '/assets' do
  run $sprockets
end

# 其它的交给 Sinatra 的程序处理
map '/' do
  run Sinatra::Application
end

同时我们还需要 Rake 任务,编译 Assets,Rakefile 增加

require 'rake/sprocketstask'
require_relative './environment'

Rake::SprocketsTask.new do |t|
  t.environment = $sprockets
  t.output      = "./public/assets"
  t.assets      = %w( app.js app.css )
end

现在就有了 3 个 Assets 的 Rake task:

rake assets          # Compile assets
rake clean_assets    # Clean old assets
rake clobber_assets  # Remove all assets

然后,我们就可以像 Rails 一样用 Assets Pipeline 了。

app.scss

/**
 *= require 'bootstrap.min'
 */

body {
  font-family: sans-serif;
  color: #333; 
}

app.coffee

#= require 'jquery.min'
#= require 'bootstrap.min'
#= require_self

window.App =
  hello: ->
    alert("hello world")

layout.erb

<!DOCTYPE html>
<html>
  <head>
    <title>My App</title>
    <link rel="stylesheet" href="/assets/<%= $sprockets['app.css'].digest_path %>" type="text/css"> 
    <script src="/assets/<%= $sprockets['app.js'].digest_path %>" type="text/javascript"></script>
  </head>
</html>
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号