Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

90 lines (69 sloc) 3.369 kB
# Client Asset File
# -----------------
# An asset is a Code (JS or CoffeeScript), CSS or HTML file
log = console.log
fs = require('fs')
pathlib = require('path')
uglifyjs = require('uglify-js')
formatters = require('./formatters')
wrap = require('./wrap')
jsp = uglifyjs.parser
pro = uglifyjs.uglify
# Load, compile and minify the following assets
module.exports = (ss, options) ->
loadFile = (dir, fileName, type, options, cb) ->
dir = pathlib.join(ss.root, dir)
path = pathlib.join(dir, fileName)
extension = pathlib.extname(path)
extension = extension && extension.substring(1) # argh!
formatter = ss.client.formatters[extension]
throw new Error("Invalid path. Request for #{path} must not live outside #{dir}") if path.substr(0, dir.length) != dir
throw new Error("Unsupported file extension '.#{extension}' when we were expecting some type of #{type.toUpperCase()} file. Please provide a formatter for #{path.substring(root.length)} or move it to /client/static") unless formatter
throw new Error("Unable to render '#{fileName}' as this appears to be a #{formatter.assetType.toUpperCase()} file. Expecting some type of #{type.toUpperCase()} file in #{dir.substr(root.length)} instead") unless formatter.assetType == type
formatter.compile(path.replace(/\\/g, '/'), options, cb) # replace '\' with '/' to support Windows
# Public
js: (path, opts, cb) ->
loadFile options.dirs.code, path, 'js', opts, (output) ->
output = wrapCode(output, path, opts.pathPrefix)
output = minifyJSFile(output, path) if opts.compress && !path.indexOf('.min') >= 0
worker: (path, opts, cb) ->
loadFile options.dirs.workers, path, 'js', opts, (output) ->
output = minifyJSFile(output, path) if opts.compress
css: (path, opts, cb) ->
loadFile(options.dirs.css, path, 'css', opts, cb)
html: (path, opts, cb) ->
loadFile(options.dirs.views, path, 'html', opts, cb)
formatKb = (size) ->
"#{Math.round((size / 1024) * 1000) / 1000} KB"
minifyJSFile = (originalCode, fileName) ->
ast = jsp.parse(originalCode)
ast = pro.ast_mangle(ast)
ast = pro.ast_squeeze(ast)
minifiedCode = pro.gen_code(ast)
log(" Minified #{fileName} from #{formatKb(originalCode.length)} to #{formatKb(minifiedCode.length)}".grey)
# Before client-side code is sent to the browser any file which is NOT a library (e.g. /client/code/libs)
# is wrapped in a module wrapper (to keep vars local and allow you to require() one file in another).
# The 'system' directory is a special case - any module placed in this dir will not have a leading slash
wrapCode = (code, path, pathPrefix) ->
pathAry = path.split('/')
# Don't touch the code if it's in a 'libs' directory
return code if 'libs' in pathAry
# Don't add a leading slash if this is a 'system' module
if 'system' in pathAry
modPath = pathAry[pathAry.length-1]
wrap.module(modPath, code)
# Otherwise treat as a regular module
modPath = pathAry.slice(1).join('/')
# Work out namespace for module
if pathPrefix
# Ignore any filenames in the path
if pathPrefix.indexOf('.') > 0
sp = pathPrefix.split('/'); sp.pop();
pathPrefix = sp.join('/')
modPath = path.substr(pathPrefix.length+1)
wrap.module('/' + modPath, code)
Jump to Line
Something went wrong with that request. Please try again.