To add in arbitrary text, the best way I know of is to use createIdentifier with the string you want to insert.
To add in an import statement, remember that you're updating the tree without mutating the original.
The ts.visitEachChild API takes a nodesVisitor parameter which specially operates on NodeArrays. Usually, if you don't pass a nodesVisitor in, it will operate on each Node in the NodeArray using the first callback you pass for the visitor parameter, but here you specially want to operate on the full node array.
In your case, you're interested in a SourceFile's statements (which is a NodeArray<Statement>. You can create the import with createImportDeclaration, and update the SourceFile by passing in a nodesVisitor like the following:
function addImport(statements: ts.NodeArray<ts.Statement>) {
const importStatement = ts.createImportStatement(/*...*/);
return ts.createNodeArray([importStatement, ...statements]);
}
visitEachChild(
sourceFile,
/*replace this with something that controls traversal*/ x => x,
context,
addImport);
createIdentifier(`(function compiledTemplate(deps) { /*...*/ }`).import lib from '@scope/lib';?