Add inline sourcemap support

This commit is contained in:
Dylan Piercey 2015-09-27 20:08:39 -06:00
parent 36e80d7f5c
commit 347a625525
4 changed files with 33 additions and 14 deletions

View File

@ -14,7 +14,7 @@ CoffeeScript.eval = (code, options = {}) ->
# Running code does not provide access to this scope.
CoffeeScript.run = (code, options = {}) ->
options.bare = on
options.bare = on
options.shiftLine = on
Function(compile code, options)()
@ -24,12 +24,10 @@ return unless window?
# Include source maps where possible. If we've got a base64 encoder, a
# JSON serializer, and tools for escaping unicode characters, we're good to go.
# Ported from https://developer.mozilla.org/en-US/docs/DOM/window.btoa
if btoa? and JSON? and unescape? and encodeURIComponent?
if btoa? and JSON?
compile = (code, options = {}) ->
options.sourceMap = true
options.inline = true
{js, v3SourceMap} = CoffeeScript.compile code, options
"#{js}\n//# sourceMappingURL=data:application/json;base64,#{btoa unescape encodeURIComponent v3SourceMap}\n//# sourceURL=coffeescript"
options.inlineMap = true
CoffeeScript.compile code, options
# Load a remote script from the current domain via XHR.
CoffeeScript.load = (url, callback, options = {}, hold = false) ->

View File

@ -19,6 +19,15 @@ exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md']
# Expose helpers for testing.
exports.helpers = helpers
# Function that allows for btoa in both nodejs and the browser.
base64encode = (src) -> switch
when typeof Buffer is 'function'
new Buffer(src).toString('base64')
when typeof btoa is 'function'
btoa(src)
else
throw new Error('Unable to base64 encode inline sourcemap.')
# Function wrapper to add source file information to SyntaxErrors thrown by the
# lexer/parser/compiler.
withPrettyErrors = (fn) ->
@ -42,7 +51,10 @@ exports.compile = compile = withPrettyErrors (code, options) ->
{merge, extend} = helpers
options = extend {}, options
if options.sourceMap
if options.inlineMap
options.sourceMap ?= yes
if options.sourceMap
map = new SourceMap
tokens = lexer.tokenize code, options
@ -84,10 +96,17 @@ exports.compile = compile = withPrettyErrors (code, options) ->
js = "// #{header}\n#{js}"
if options.sourceMap
answer = {js}
answer.sourceMap = map
answer.v3SourceMap = map.generate(options, code)
answer
v3SourceMap = map.generate(options, code)
if options.inlineMap
sourceMapDataURI = "//# sourceMappingURL=data:application/json;base64,#{base64encode v3SourceMap}"
sourceURL = "//# sourceURL=#{options.filename ? 'coffeescript'}"
"#{js}\n#{sourceMapDataURI}\n#{sourceURL}"
else
answer = {js}
answer.sourceMap = map
answer.v3SourceMap = map.generate(options, code)
answer
else
js
@ -181,12 +200,12 @@ if require.extensions
Use CoffeeScript.register() or require the coffee-script/register module to require #{ext} files.
"""
exports._compileFile = (filename, sourceMap = no) ->
exports._compileFile = (filename, sourceMap = no, inlineMap = no) ->
raw = fs.readFileSync filename, 'utf8'
stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
try
answer = compile(stripped, {filename, sourceMap, literate: helpers.isLiterate filename})
answer = compile(stripped, {filename, sourceMap, inlineMap, literate: helpers.isLiterate filename})
catch err
# As the filename and code of a dynamically loaded file will be different
# from the original file compiled with CoffeeScript.run, add that

View File

@ -39,6 +39,7 @@ SWITCHES = [
['-i', '--interactive', 'run an interactive CoffeeScript REPL']
['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling']
['-m', '--map', 'generate source map and save as .js.map files']
['-M', '--inline-map', 'generate source map and include it directly in output']
['-n', '--nodes', 'print out the parse tree that the parser produces']
[ '--nodejs [ARGS]', 'pass options directly to the "node" binary']
[ '--no-header', 'suppress the "Generated by" header']
@ -413,6 +414,7 @@ compileOptions = (filename, base) ->
bare: opts.bare
header: opts.compile and not opts['no-header']
sourceMap: opts.map
inlineMap: opts['inline-map']
}
if filename
if base

View File

@ -5,7 +5,7 @@ path = require 'path'
# Load and run a CoffeeScript file for Node, stripping any `BOM`s.
loadFile = (module, filename) ->
answer = CoffeeScript._compileFile filename, false
answer = CoffeeScript._compileFile filename, yes, yes
module._compile answer, filename
# If the installed version of Node supports `require.extensions`, register