Skip to content

Instantly share code, notes, and snippets.

@hennk
Created May 28, 2012 11:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hennk/2818759 to your computer and use it in GitHub Desktop.
Save hennk/2818759 to your computer and use it in GitHub Desktop.
rake pipeline configuration, memory leak
APPNAME = 'liquid_editor'
require 'rake-pipeline-web-filters'
require File.join(File.dirname(__FILE__), 'support/ember_strip_debug_filter/ember_strip_debug_filter')
require File.join(File.dirname(__FILE__), 'support/precompiling_handlebars_filter/precompiling_handlebars_filter')
SHOULD_UGLIFY = ENV['RAKEP_MODE'] == 'production'
output (ENV['LIQUID_EDITOR_ASSETS_OUTPUT'] || 'assets')
class BOMFilter < Rake::Pipeline::Filter
def generate_output(inputs, output)
inputs.each do |input|
output.write("\uFEFF" + input.read)
end
end
end
class FixBootstrapPaths < Rake::Pipeline::Filter
def generate_output(inputs, output)
inputs.each do |input|
output.write(input.read.gsub(/"\.\.\/img/, '"assets/bootstrap/img'))
end
end
end
class FixVendorRequires < Rake::Pipeline::Filter
def generate_output(inputs, output)
inputs.each do |input|
result = input.read.gsub(/^(require\(['"])([^)\/]+\/)/) do
match1 = $1
match2 = $2
if match2 =~ /(vendor|#{APPNAME})\//
match1 + match2
else
"#{match1}vendor/#{match2}"
end
end
output.write(result)
end
end
end
class JSHintRC < Rake::Pipeline::Filter
def jshintrc
@jshintrc ||= File.read(".jshintrc")
end
def generate_output(inputs, output)
inputs.each do |input|
output.write "var JSHINTRC = #{jshintrc};\n\n#{input.read}"
end
end
end
input 'app' do
match '{lib,vendor}/**/*.js' do
filter FixVendorRequires
minispade :module_id_generator => proc { |input|
input.path.sub(/^lib\//, "#{APPNAME}/").sub(/\.js$/, '')
},
:string => !SHOULD_UGLIFY,
:rewrite_requires => true
if SHOULD_UGLIFY
filter EmberStripDebugFilter
uglify
end
concat %w[
vendor/jquery.js
vendor/ember.js
], 'app.js'
end
match 'modules/**/*.js' do
if SHOULD_UGLIFY
filter EmberStripDebugFilter
uglify
end
concat [
],'modules.js'
end
match 'templates/**/*.handlebars' do
filter PrecompilingHandlebarsFilter,
:key_name_proc => proc { |input| input.path.sub(/^templates\//, '').sub(/\.handlebars$/, '') },
:precompile => SHOULD_UGLIFY
minispade :module_id_generator => proc { |input|
input.path.sub(/^templates\//, "#{APPNAME}/~templates/").sub(/\.handlebars$/, '').sub(/\.js$/, '')
},
:string => !SHOULD_UGLIFY,
:rewrite_requires => true
if SHOULD_UGLIFY
uglify
end
concat 'app.js'
end
match 'tests/**/*.js' do
minispade :module_id_generator => proc { |input|
input.path.sub(/\.js$/, '')
},
:string => !SHOULD_UGLIFY,
:rewrite_requires => true
concat 'app-tests.js'
end
match "app-tests.js" do
filter JSHintRC
end
match 'css/main.less' do
less :paths => ['app/css']
if SHOULD_UGLIFY
yui_css
end
concat 'app.css'
end
match "static/**/*" do
concat do |input|
input.sub(/static\//, '')
end
end
match "app.css,app.js" do
filter BOMFilter
end
end
# vim: filetype=ruby
class EmberStripDebugFilter < Rake::Pipeline::Filter
def strip_debug(data)
# Strip debug code
data.gsub!(%r{^(\s)+ember_(assert|deprecate|warn)\((.*)\).*$}, "")
end
def generate_output(inputs, output)
inputs.each do |input|
result = input.read
strip_debug(result)
output.write result
end
end
end
class PrecompilingHandlebarsFilter < Rake::Pipeline::Filter
include Rake::Pipeline::Web::Filters::FilterWithDependencies
# @return [Hash] a hash of options for generate_output
attr_reader :options
# @param [Hash] options
# options to pass to the output generator
# @option options [String] :target
# the variable to store templates in
# @param [Proc] block a block to use as the Filter's
# {#output_name_generator}.
def initialize(options={},&block)
# Convert .handlebars file extensions to .js
block ||= proc { |input| input.sub(/\.handlebars$/, '.js') }
super(&block)
@options = {
:target =>'Ember.TEMPLATES',
:wrapper_proc => proc { |source| "Ember.Handlebars.compile(#{source});" },
:precompiler_wrapper_proc => proc { |precompiled| "Ember.Handlebars.template(#{precompiled});"},
:key_name_proc => proc { |input| File.basename(input.path, File.extname(input.path)) }
}.merge(options)
end
def generate_output(inputs, output)
inputs.each do |input|
# The name of the template is the filename, sans extension
name = options[:key_name_proc].call(input)
if options[:precompile]
source = input.read
precompiled = js_context.call("precompileEmberHandlebars", source)
output.write "#{options[:target]}['#{name}']=#{options[:precompiler_wrapper_proc].call(precompiled)}"
else
# Read the file and escape it so it's a valid JS string
source = input.read.to_json
# Write out a JS file, saved to target, wrapped in compiler
output.write "#{options[:target]}['#{name}']=#{options[:wrapper_proc].call(source)}"
end
end
end
private
def js_context
# We're using Ember to precompile templates
unless @context
headless = File.read("support/precompiling_handlebars_filter/headless-ember.js")
ember = File.read("app/vendor/ember.js")
@context = ExecJS.compile([headless, ember].join("\n"))
end
@context
end
def external_dependencies
[ 'json', 'execjs' ]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment