Sassing a .Net application - part II
Part 1 of this post I introduced Sass into my current project that is using the ASP.NET MVC framework.
(Which I might add, I'm still using the initial CTP without any trouble and the application is in production. So if your wondering if in preview 4 its ready for production use... stop wondering)
The problem I introduced was changes to sass files required a VS build in order for the rake task to execute and reproduce the css files. This increased the turn around time to around 15 seconds, unacceptable.
The solution I was aiming for was a file system watcher that looked at the sass directory and any changes to my sass files immediately.
I found this filesystemwatcher code that looked pretty easy to implement (im a ruby noob still), so I moved those files to my tools directory and required them in my rakefile.rb
require 'rake'
require File.join(File.dirname(__FILE__), 'tools/haml-2.0.2/lib', 'sass')
require File.join(File.dirname(__FILE__), 'tools/fsw', 'servicestate')
require File.join(File.dirname(__FILE__), 'tools/fsw', 'filesystemwatcher')
As you can see, I've placed the filesystemwatcher files into my tools directory, again allowing the application to only rely on ruby and not obscure plugins.
The next step is to call the sass generation on the various FSW Events (Created, Modified, and Deleted)
desc "Watches sass directory and generates css on save."
task :watch_sass do
_sass2cssAll
css_dir = File.join(File.dirname(__FILE__), 'src/app/mvc/content/css')
sass_dir = File.join(css_dir, 'sass')
watcher = FileSystemWatcher.new()
watcher.addDirectory(sass_dir, "*.sass")
watcher.sleepTime = 1
watcher.start { |status,file|
case status
when FileSystemWatcher::CREATED
_sass2css(file, css_dir)
when FileSystemWatcher::MODIFIED
_sass2css(file, css_dir)
when FileSystemWatcher::DELETED
puts "deleted: #{file}"
end
}
watcher.join() # join to the thread to keep the program alive
end
I refactored my :sass2css task so it calls straight into _sass2cssAll. The reason for this is that invoking the task from within the watcher was causing subsequent changes to not be picked up. I didnt investigate this too much.
I also extracted a method _sass2css so that the watcher only reproduced the css file in question, and not all of them.
Here are the 2 methods I extracted...
def _sass2cssAll
stylesheets_root = File.join(File.dirname(__FILE__), 'src/app/mvc/content/css')
Dir[stylesheets_root + "/sass/*.sass"].each do |source|
_sass2css(source, stylesheets_root)
end
end
def _sass2css(source,stylesheets_root)
target = File.join(stylesheets_root, File.basename(source, ".sass") + ".css")
puts "Sassing #{source} to #{target}"
puts ""
File.open(target, "w") { |f| f.write(Sass::Engine.new(IO.read(source)).render)}
end
All that I need to do now is fire up the watcher when I start development an watch those css files change!!
Leave a comment