Skip to content

Instantly share code, notes, and snippets.

@larzconwell
Last active December 10, 2015 17:48
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 larzconwell/4470370 to your computer and use it in GitHub Desktop.
Save larzconwell/4470370 to your computer and use it in GitHub Desktop.
Handle asset compiling in Geddy, temp solution
/*
* Simple asset compiler for Geddy, should be okay to use in production as it
* creates on init, and only updates when files change.
* (though it would waste resources as it still watches the dirs)
*
* To use do the following in your shell:
* mkdir -p app/assets/{css,js}
* touch config/after_start.js
*
* after that just copy these contents into config/after_start.js
* then start coding your assets in the respected dir in app/assets
*
* How it works:
* After the server starts up, it gathers the dirs in app/assets/{css,js},
* creates those dirs in public/{css,js} if needed, and also compiles the
* files found in those dirs to their public path equivalent. Then it watches
* the dirs in app/assets for change events on their files, then re-compiles them
*
* Add languages
* If you wanna use something other than CoffeeScript and Stylus, add a var for it to the
* compilers vars below then go down to the compile function below, here add an if statement
* to check it's extension. Then inside the if as the others do, set the compiler var with
* the require and then call the write function with the compiled contents of data
*/
var fs = require('fs')
, path = require('path')
// Compilers
var coffee, stylus
// Watch all files in the given source directory,
// and compile them to the correct dest directory
function watchAndCompile(source, dest, callback) {
var destPath = ''
// Watch all paths on the base source directory
watch(source, dest, callback)
fs.readdir(source, function (err, paths) {
if (err)
callback(err)
paths.forEach(function (p) {
p = path.join(source, p)
fs.stat(p, function (err, stats) {
if (err)
callback(err)
// If the path is a directory, create the destination for it
// and watch that directory
if (stats.isDirectory()) {
destPath = path.join(dest, p.replace(source, ''))
fs.mkdir(destPath, 0777, function (err) {
if (err && err.code !== 'EEXIST')
callback(err)
watchAndCompile(p, destPath, callback)
})
}
// If it's a file go ahead a compile it to start off
if (stats.isFile())
compile(p, dest)
})
})
})
}
// Watch a directory and compile a file in it on a change
// event if it exists
function watch (dir, dest, callback) {
fs.watch(dir, function (ev, p) {
if (ev === 'change')
p = path.join(dir, p)
fs.exists(p, function (exists) {
if (exists)
compile(p, dest, callback)
})
})
}
function compile (p, dest, callback) {
var baseFile = path.basename(p)
, baseExt = path.extname(baseFile).slice(1)
, destFile = path.join(dest, baseFile)
, write
write = function (contents) {
fs.writeFile(destFile, contents, 'utf-8', function (err) {
if (err)
callback(err)
geddy.log.info('Compiled ' + p + ' to ' + destFile)
})
}
// Read file contents
fs.readFile(p, 'utf-8', function (err, data) {
if (err)
callback(err)
// CoffeeScript
if (baseExt === 'coffee') {
coffee = coffee || require('coffee-script')
try {
write(coffee.compile(data))
} catch (err) {
callback(err)
}
}
// Stylus
if (baseExt === 'styl') {
stylus = stylus || require('stylus')
stylus.render(data, function (err, css) {
if (err)
callback(err)
write(css)
})
}
})
}
watchAndCompile('app/assets/js', 'public/js', function (err) {
if (err)
throw err
})
watchAndCompile('app/assets/css', 'public/css', function (err) {
if (err)
throw err
})
@dustincoates
Copy link

This was really useful--I needed some solution for Stylus support.

I noticed there was a small issue, however. When the file is written, it keeps the same extension it had before. Since I only needed Stylus support, I changed the destfile variable to include .css on the end after removing .styl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment