rework the asset pipeline to use environments
This commit is contained in:
parent
f6ac7b9c30
commit
c6223341f4
60
AssetFile
60
AssetFile
|
@ -1,25 +1,18 @@
|
||||||
$: << 'lib'
|
$: << 'lib'
|
||||||
|
|
||||||
require 'rake-pipeline-web-filters'
|
require 'rake-pipeline-web-filters'
|
||||||
require 'rake-pipeline/travis'
|
require 'travis/assets'
|
||||||
require 'compass'
|
require 'compass'
|
||||||
|
|
||||||
ROOTS ||= [Pathname.new(File.expand_path('.'))]
|
assets ||= Travis::Assets.new
|
||||||
|
assets.setup_compass
|
||||||
paths = %w(styles scripts images static vendor).inject({}) do |paths, type|
|
assets.update_version
|
||||||
paths.merge(type.to_sym => ROOTS.map { |root| root.join("assets/#{type}").to_s })
|
|
||||||
end
|
|
||||||
|
|
||||||
Compass.configuration.images_path = paths[:images].first
|
|
||||||
Compass.configuration.add_import_path paths[:styles].first
|
|
||||||
|
|
||||||
Travis::Version.update
|
|
||||||
|
|
||||||
output 'public/scripts'
|
output 'public/scripts'
|
||||||
input paths[:scripts] do
|
input assets.scripts do
|
||||||
match '**/*.hbs' do
|
match '**/*.hbs' do
|
||||||
travis_handlebars
|
handlebars :precompile => assets.production?
|
||||||
concat 'app/templates.js'
|
concat 'templates.js'
|
||||||
end
|
end
|
||||||
|
|
||||||
match '**/*.coffee' do
|
match '**/*.coffee' do
|
||||||
|
@ -27,38 +20,29 @@ input paths[:scripts] do
|
||||||
end
|
end
|
||||||
|
|
||||||
match 'vendor/**/*.js' do
|
match 'vendor/**/*.js' do
|
||||||
precedence = %w(jquery.min minispade handlebars ember).map { |name| "vendor/#{name}.js" }
|
safe_concat assets.vendor_order, 'vendor.js'
|
||||||
safe_concat precedence, 'vendor.js'
|
end
|
||||||
|
|
||||||
|
match %r(^(?!vendor).*\.js$) do
|
||||||
|
modules = proc { |input| input.path.gsub(%r((^app/|lib/|\.js$)), '') }
|
||||||
|
minispade(string: assets.development?, rewrite_requires: true, module_id_generator: modules)
|
||||||
end
|
end
|
||||||
|
|
||||||
match '**/*.js' do
|
match '**/*.js' do
|
||||||
copy { |path| ["dev/#{path}", "min/#{path}"] }
|
concat ['vendor.js'], ['app.js', 'min/app.js']
|
||||||
end
|
end
|
||||||
|
|
||||||
match %r(^dev/(?!vendor).*\.js$) do
|
if assets.production?
|
||||||
modules = proc { |input| input.path.gsub(%r((^dev/|app/|lib/|\.js$)), '') }
|
match 'min/app.js' do
|
||||||
minispade(string: true, rewrite_requires: true, module_id_generator: modules)
|
|
||||||
end
|
|
||||||
|
|
||||||
match 'dev/**/*.js' do
|
|
||||||
concat ['dev/vendor.js'], 'app.js'
|
|
||||||
end
|
|
||||||
|
|
||||||
match %r(^min/(?!vendor).*\.js$) do
|
|
||||||
modules = proc { |input| input.path.gsub(%r((^min/|app/|lib/|\.js$)), '') }
|
|
||||||
minispade(string: false, rewrite_requires: true, module_id_generator: modules)
|
|
||||||
end
|
|
||||||
|
|
||||||
match 'min/**/*.js' do
|
|
||||||
concat ['min/vendor.js'], 'min/app.js'
|
|
||||||
strip_debug
|
strip_debug
|
||||||
uglify squeeze: true, max_line_length: 200
|
uglify squeeze: true
|
||||||
copy 'app.min.js'
|
concat 'app.min.js'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
output 'public/styles'
|
output 'public/styles'
|
||||||
input paths[:styles] do
|
input assets.styles do
|
||||||
match '**/*.{scss,sass}' do
|
match '**/*.{scss,sass}' do
|
||||||
sass
|
sass
|
||||||
concat [], 'app.css'
|
concat [], 'app.css'
|
||||||
|
@ -66,7 +50,7 @@ input paths[:styles] do
|
||||||
end
|
end
|
||||||
|
|
||||||
output 'public/images'
|
output 'public/images'
|
||||||
input paths[:images] do
|
input assets.images do
|
||||||
skip %r(^ui/)
|
skip %r(^ui/)
|
||||||
match '**/*' do
|
match '**/*' do
|
||||||
copy
|
copy
|
||||||
|
@ -74,7 +58,7 @@ input paths[:images] do
|
||||||
end
|
end
|
||||||
|
|
||||||
output 'public'
|
output 'public'
|
||||||
input paths[:static] do
|
input assets.static do
|
||||||
match '**/*' do
|
match '**/*' do
|
||||||
copy
|
copy
|
||||||
end
|
end
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -21,7 +21,7 @@ group :development do
|
||||||
gem 'newrelic_rpm', '~> 3.3.0'
|
gem 'newrelic_rpm', '~> 3.3.0'
|
||||||
gem 'hubble', github: 'roidrage/hubble'
|
gem 'hubble', github: 'roidrage/hubble'
|
||||||
|
|
||||||
gem 'rake-pipeline', github: 'livingsocial/rake-pipeline'
|
gem 'rake-pipeline', github: 'livingsocial/rake-pipeline', ref: '3465e0e3e1'
|
||||||
gem 'rake-pipeline-web-filters', github: 'wycats/rake-pipeline-web-filters'
|
gem 'rake-pipeline-web-filters', github: 'wycats/rake-pipeline-web-filters'
|
||||||
|
|
||||||
gem 'coffee-script'
|
gem 'coffee-script'
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/livingsocial/rake-pipeline.git
|
remote: git://github.com/livingsocial/rake-pipeline.git
|
||||||
revision: 3914452278165b7eb3a79071d3b63b46fee59a2f
|
revision: 3465e0e3e134bf52ddf5d138e8c8262412080095
|
||||||
|
ref: 3465e0e3e1
|
||||||
specs:
|
specs:
|
||||||
rake-pipeline (0.6.0)
|
rake-pipeline (0.6.0)
|
||||||
json
|
|
||||||
rake (~> 0.9.0)
|
rake (~> 0.9.0)
|
||||||
thor
|
thor
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ This is a static html/js app so you shouldn't need to install anything.
|
||||||
|
|
||||||
Running locally with a local API server:
|
Running locally with a local API server:
|
||||||
|
|
||||||
bundle exec rackup
|
RUN_API=1 bundle exec rackup -p 3000
|
||||||
|
|
||||||
Running against existing API endpoint:
|
Running against existing API endpoint:
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ Run locally, one on `ci.dev` and one on `api.dev`:
|
||||||
### Compiling assets manually
|
### Compiling assets manually
|
||||||
|
|
||||||
bundle exec rakep
|
bundle exec rakep
|
||||||
|
ENV=production bundle exec rakep
|
||||||
|
|
||||||
### Compiling assets on change
|
### Compiling assets on change
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,10 @@ module Guard
|
||||||
private
|
private
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
started = Time.now
|
||||||
|
print 'Compiling ... '
|
||||||
system 'bundle exec rakep'
|
system 'bundle exec rakep'
|
||||||
|
puts "done (#{(Time.now - started).round(2)}s)."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
require 'rake-pipeline'
|
|
||||||
|
|
||||||
module Rake::Pipeline::Travis
|
|
||||||
autoload :Filters, 'rake-pipeline/travis/filters'
|
|
||||||
autoload :Helpers, 'rake-pipeline/travis/helpers'
|
|
||||||
autoload :Version, 'rake-pipeline/travis/version'
|
|
||||||
end
|
|
||||||
|
|
||||||
Rake::Pipeline::DSL::PipelineDSL.send(:include, Rake::Pipeline::Travis::Helpers)
|
|
|
@ -1,54 +0,0 @@
|
||||||
require 'pathname'
|
|
||||||
require 'digest/md5'
|
|
||||||
|
|
||||||
module Rake::Pipeline::Travis
|
|
||||||
class Version
|
|
||||||
FILE_NAME = 'public/version'
|
|
||||||
SOURCES = %w(AssetFile Gemfile.lock assets)
|
|
||||||
|
|
||||||
def self.update
|
|
||||||
new.update
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :root
|
|
||||||
|
|
||||||
def initialize(root = nil)
|
|
||||||
@root = Pathname.new(root || File.expand_path('.'))
|
|
||||||
end
|
|
||||||
|
|
||||||
def read
|
|
||||||
file.read
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
@hash = nil
|
|
||||||
write(hash)
|
|
||||||
hash
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
def file
|
|
||||||
root.join(FILE_NAME)
|
|
||||||
end
|
|
||||||
|
|
||||||
def write(version)
|
|
||||||
file.open('w+') { |f| f.write(version) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def hash
|
|
||||||
@hash ||= digest.to_s[0..7]
|
|
||||||
end
|
|
||||||
|
|
||||||
def digest
|
|
||||||
Digest::MD5.new << `ls -lAR #{sources.join(' ')} | awk '{print $5, $6, $7, $9}'`
|
|
||||||
end
|
|
||||||
|
|
||||||
def sources
|
|
||||||
SOURCES.map do |source|
|
|
||||||
source = root.join(source)
|
|
||||||
source.to_s if source.exist?
|
|
||||||
end.compact
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
52
lib/travis/assets.rb
Normal file
52
lib/travis/assets.rb
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
require 'rake-pipeline'
|
||||||
|
|
||||||
|
module Travis
|
||||||
|
class Assets
|
||||||
|
autoload :Filters, 'travis/assets/filters'
|
||||||
|
autoload :Helpers, 'travis/assets/helpers'
|
||||||
|
autoload :Version, 'travis/assets/version'
|
||||||
|
|
||||||
|
TYPES = [:styles, :scripts, :images, :static, :vendor]
|
||||||
|
VENDOR_ORDER = %w(jquery.min minispade handlebars ember)
|
||||||
|
|
||||||
|
attr_reader :roots, :env
|
||||||
|
|
||||||
|
def initialize(roots = '.')
|
||||||
|
@roots = Array(roots).map { |root| Pathname.new(File.expand_path(root)) }
|
||||||
|
@env = ENV['ENV']
|
||||||
|
end
|
||||||
|
|
||||||
|
def production?
|
||||||
|
env == 'production'
|
||||||
|
end
|
||||||
|
|
||||||
|
def development?
|
||||||
|
!production?
|
||||||
|
end
|
||||||
|
|
||||||
|
def vendor_order
|
||||||
|
VENDOR_ORDER.map { |name| "vendor/#{name}.js" }
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_compass
|
||||||
|
Compass.configuration.images_path = images.first
|
||||||
|
styles.each do |path|
|
||||||
|
Compass.configuration.add_import_path(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_version
|
||||||
|
Travis::Assets::Version.new.update
|
||||||
|
end
|
||||||
|
|
||||||
|
TYPES.each { |type| define_method(type) { paths[type] } }
|
||||||
|
|
||||||
|
def paths
|
||||||
|
@paths ||= TYPES.inject({}) do |paths, type|
|
||||||
|
paths.merge(type.to_sym => roots.map { |root| root.join("assets/#{type}").to_s })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rake::Pipeline::DSL::PipelineDSL.send(:include, Travis::Assets::Helpers)
|
|
@ -1,19 +1,18 @@
|
||||||
require 'rake-pipeline'
|
require 'rake-pipeline'
|
||||||
|
|
||||||
require 'execjs'
|
require 'execjs'
|
||||||
require 'uglifier'
|
require 'uglifier'
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
|
|
||||||
class Rake::Pipeline
|
|
||||||
module Travis
|
module Travis
|
||||||
|
class Assets
|
||||||
module Filters
|
module Filters
|
||||||
class Drop < Matcher
|
class Drop < Rake::Pipeline::Matcher
|
||||||
def output_files
|
def output_files
|
||||||
input_files.reject { |f| f.path =~ @pattern }
|
input_files.reject { |f| f.path =~ @pattern }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Handlebars < Filter
|
class Handlebars < Rake::Pipeline::Filter
|
||||||
class << self
|
class << self
|
||||||
def source
|
def source
|
||||||
[
|
[
|
||||||
|
@ -30,22 +29,35 @@ class Rake::Pipeline
|
||||||
def context
|
def context
|
||||||
@@context ||= ExecJS.compile(source)
|
@@context ||= ExecJS.compile(source)
|
||||||
end
|
end
|
||||||
|
|
||||||
def compile(source)
|
|
||||||
context.call('compileHandlebarsTemplate', source + "\n")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attr_reader :options
|
||||||
|
|
||||||
|
def initialize(*args, &block)
|
||||||
|
@options = args.last.is_a?(Hash) ? args.pop : {}
|
||||||
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_output(inputs, output)
|
def generate_output(inputs, output)
|
||||||
inputs.each do |input|
|
inputs.each do |input|
|
||||||
source = self.class.compile(input.read)
|
source = input.read
|
||||||
|
source = options[:precompile] ? compile(source) : escape(source)
|
||||||
source = wrap(name(input.path), source)
|
source = wrap(name(input.path), source)
|
||||||
output.write source
|
output.write source
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def compile(source)
|
||||||
|
self.class.context.call('compileHandlebarsTemplate', source + "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
def escape(source)
|
||||||
|
source.to_json
|
||||||
|
end
|
||||||
|
|
||||||
def wrap(name, source)
|
def wrap(name, source)
|
||||||
"\nEmber.TEMPLATES['#{name}'] = Ember.Handlebars.template(#{source});\n"
|
method = options[:precompile] ? 'template' : 'compile'
|
||||||
|
"\nEmber.TEMPLATES['#{name}'] = Ember.Handlebars.#{method}(#{source});\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
def name(path)
|
def name(path)
|
||||||
|
@ -53,7 +65,7 @@ class Rake::Pipeline
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class SafeConcat < ConcatFilter
|
class SafeConcat < Rake::Pipeline::ConcatFilter
|
||||||
def generate_output(inputs, output)
|
def generate_output(inputs, output)
|
||||||
inputs.each do |input|
|
inputs.each do |input|
|
||||||
output.write File.read(input.fullpath) + ";"
|
output.write File.read(input.fullpath) + ";"
|
||||||
|
@ -76,7 +88,7 @@ class Rake::Pipeline
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class StripDebug < Filter
|
class StripDebug < Rake::Pipeline::Filter
|
||||||
def generate_output(inputs, output)
|
def generate_output(inputs, output)
|
||||||
inputs.each do |input|
|
inputs.each do |input|
|
||||||
source = File.read(input.fullpath)
|
source = File.read(input.fullpath)
|
|
@ -1,9 +1,9 @@
|
||||||
require 'rake-pipeline/dsl'
|
require 'rake-pipeline/dsl'
|
||||||
|
|
||||||
class Rake::Pipeline
|
|
||||||
module Travis
|
module Travis
|
||||||
|
class Assets
|
||||||
module Helpers
|
module Helpers
|
||||||
def travis_handlebars(*args, &block)
|
def handlebars(*args, &block)
|
||||||
filter(Filters::Handlebars, *args, &block)
|
filter(Filters::Handlebars, *args, &block)
|
||||||
end
|
end
|
||||||
|
|
56
lib/travis/assets/version.rb
Normal file
56
lib/travis/assets/version.rb
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
require 'pathname'
|
||||||
|
require 'digest/md5'
|
||||||
|
|
||||||
|
module Travis
|
||||||
|
class Assets
|
||||||
|
class Version
|
||||||
|
FILE_NAME = 'public/version'
|
||||||
|
SOURCES = %w(AssetFile Gemfile.lock assets)
|
||||||
|
|
||||||
|
def self.update
|
||||||
|
new.update
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :root
|
||||||
|
|
||||||
|
def initialize(root = nil)
|
||||||
|
@root = Pathname.new(root || File.expand_path('.'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def read
|
||||||
|
file.read
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@hash = nil
|
||||||
|
write(hash)
|
||||||
|
hash
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def file
|
||||||
|
root.join(FILE_NAME)
|
||||||
|
end
|
||||||
|
|
||||||
|
def write(version)
|
||||||
|
file.open('w+') { |f| f.write(version) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def hash
|
||||||
|
@hash ||= digest.to_s[0..7]
|
||||||
|
end
|
||||||
|
|
||||||
|
def digest
|
||||||
|
Digest::MD5.new << `ls -lAR #{sources.join(' ')} | awk '{print $5, $6, $7, $9}'`
|
||||||
|
end
|
||||||
|
|
||||||
|
def sources
|
||||||
|
SOURCES.map do |source|
|
||||||
|
source = root.join(source)
|
||||||
|
source.to_s if source.exist?
|
||||||
|
end.compact
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
File diff suppressed because one or more lines are too long
3116
public/scripts/app.min.js
vendored
3116
public/scripts/app.min.js
vendored
File diff suppressed because one or more lines are too long
34866
public/scripts/min/app.js
Normal file
34866
public/scripts/min/app.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
||||||
096c4ea9
|
5f08468e
|
Loading…
Reference in New Issue
Block a user