Sublime Text 3 Build Systems
I have been trying out Sublime Text 3 as a replacement for Espresso as my general purpose editor. So far, I absolutely love it.
Before I started this trial I was still using Espresso 1, as I was never convinced that version 2 had any new features that I urgently needed. As I have got back in to the hobby of more web focused development, the little bugs have became more and more annoying. I needed a change.
I have seen a lot of recommendations for this editor in the past, but I never understood what it did that was so special, as opposed to using a basic text editor. The true power of this application lies in the features behind the interface. I love the Build Systems feature. This article gives an example of using the build feature perform a commit to GitHub. To me that does not count as a build and a bit of an abuse of the feature, but it showed me what was possible and it looked useful.
The build system feature provides a simple way to get a command run with a single shortcut: ⌘B. In the Tools menu I have configured the build system to be “Automatic” so it can choose the correct one for the file type I am editing. More on how to set this up later.
Configuring a Build System for Jekyll
User created build systems, on the Mac at least, need to be in the ~/Library/Application Support/Sublime Text 3/Packages/User
directory. This application uses JSON formatted files for build system configuration.
For my Jekyll site development I have created a Jekyll.sublime-build
file with this content:
{
"cmd": ["/usr/bin/rake", "build[jekyll]"],
"env": {"LANG":"en_US.UTF-8", "LC_ALL":"en_US.UTF-8"},
"working_dir": "$project_path",
"selector": "text.html.markdown.jekyll"
}
Based on the number of incompatible guides I found on the format of this file, I can only assume this has changed between the different versions of Sublime Text. I found this documentation at least gave me a pointer in the direction to go, although it required a lot of trial and error to get working.
This script states to use the rake
command to execute my build
target, supplying the parameter jekyll
. In my setup this means that only the Jekyll elements of the site get rebuilt. I can supply all
to this target to also build the CSS files from the Less source at the same time. Prior to running this command the current working directory gets changed to the root directory of the project. I had to set some additional env settings as I was getting an invalid byte sequence in US-ASCII
error for some of my markdown files. The selector
attribute defines the scope that this build system should apply to, so the “Automatic” build system can pick this configuration. The value here relates to the “Markdown (Jekyll)” mode of this plugin. The value itself came from the scopeName
attribute of a .tmLanguage
file in the plugin source. I could not find a way to get this information from the user interface.
In all of the Jekyll based projects I am currently working on I stick to the same pattern for build targets. I’m a sucker for conventions across projects.
Configuring a Build System for Grunt
Not long ago I switched from using the less node compiler directly to setting up a workflow in Grunt. I wanted to switch to a better workflow so I could perform actions such as using myth to handle adding in required browser prefixes for CSS and uncss for cleaning up unused styles produced by Font Awesome. My build
target, with the ‘less’ parameter, now calls Grunt. This just calls the command line, but still required some set up to work within Sublime Text.
I created another build file called Less.sublime-build
with the content:
{
"cmd": ["/usr/bin/rake", "build[css]"],
"env": {"LANG":"en_US.UTF-8", "LC_ALL":"en_US.UTF-8"},
"working_dir": "$project_path",
"selector": "source.less"
}
To save having to configure the path that Sublime Text uses, I set up a symlink for the node binary, and in the rake file included the full path to my grunt binary. The error I had got without the symlink was pretty cryptic, but Stack Overflow came to the rescue as always.
The Rake File
As previouly mentioned, these targets just call the command line so the rake file itself remains simple to understand.
require 'yaml'
require 'rubygems'
require 'stringex'
desc 'Build and send to dev server'
task :build, :opt do |t, args|
opt = args[:opt]
if !opt then
opt = "all"
end
puts sprintf("Building %s\n", opt)
if ("all".casecmp opt) == 0 then
css
jekyll
elsif("css".casecmp opt) == 0 then
css
# need to copy to the built site prior to deployment
FileUtils.cp_r(Dir['assets/css/*'],'../dwi_built_site/assets/css')
elsif("jekyll".casecmp opt) == 0 then
jekyll
end
upload
puts 'Done.'
end
def jekyll
puts 'Building Jekyll pages...'
sh 'bundle exec jekyll build -d ../dwi_built_site'
puts 'Jekyll page build complete.'
end
def css
puts 'Building CSS...'
sh '/usr/local/bin/grunt build'
puts 'CSS build complete.'
end
task :deploy_dev do
upload
end
def upload
puts 'Sending to server...'
sh 'rsync -avz --delete ../dwi_built_site/ [email protected]:/home/wwwroot/dwi/'
puts 'Sent'
end
In Conclusion
A build system built in to the editor like this a great convienience. For my purposes it saves me having to switch over to the terminal every time I want to deploy my code changes.
Sublime Text seems to be a nice powerful editor, with lots of hidden features. It may be my editor of choice, but I want to try out some of the other contenders before committing to purchasing any product.