Created
March 11, 2017 11:37
-
-
Save nknapp/ff5b93c7366f6458cea10c88c9521069 to your computer and use it in GitHub Desktop.
Concept for source-mapping the output of a Handlebars-template back to the template
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Handlebars = require('handlebars'); | |
var LineCounter = require("line-counter"); | |
var env = Handlebars.create(); | |
function SourceMapCompiler() { | |
} | |
SourceMapCompiler.prototype = new Handlebars.JavaScriptCompiler(); | |
SourceMapCompiler.prototype.appendToBuffer = function (source, location, explicit) { | |
var result = Handlebars.JavaScriptCompiler.prototype.appendToBuffer.apply(this, [source, location, true]) | |
return [`helpers.$consumeSourceMapEntry(${result[1].line}, ${result[1].column}, buffer.length);`, result] | |
} | |
env.JavaScriptCompiler = SourceMapCompiler | |
var sourceMappings = [] | |
// A helper seems to be about the only way to pass data from the template function to the calling context | |
env.registerHelper("$consumeSourceMapEntry", function (sourceLine, sourceColumn, targetIndex) { | |
sourceMappings.push({ | |
source: { | |
column: sourceColumn+1, | |
line: sourceLine | |
}, | |
target: targetIndex | |
}) | |
} | |
) | |
const template = '1{{abc}}\n2a\n3{{cde}}\n4\n5b\n6\n\n\n\n\n{{abc}}'; | |
var output = env.compile(template)({ | |
abc: 'a\nmultiline\string', | |
cde: 'x' | |
}); | |
// Map target-indexes to lines/columns | |
var counter = new LineCounter(output); | |
sourceMappings.forEach(function(entry) { | |
entry.target = counter.locate(entry.target) | |
}) | |
console.log(sourceMappings) | |
console.log(JSON.stringify({template, output},null,2)) | |
Mhm, this does not work with partials and block-helpers:
- The
buffer
is new when sub-programs are executed. Somehow I have to grab the point where the partial is called and recalculated the target-index based on that point. - The SourceNodes in the compile function do not have the information in which partial they occur.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a proof-of-concept. The source-maps that the Handlebars project generates are just from compiled-template to the template (as far as I know). For debugging and developing templates, what I sometimes need is from "template-output" to "template".
This is an idea of how to achieve it, without changing Handlebars itself.
As a workaround, the mappings are passed back to the callee through a helper. This should actually be a hook inside Handlebars, but I have to think about it.