Skip to content

Instantly share code, notes, and snippets.

@RubaXa
Last active December 27, 2018 13:47
Show Gist options
  • Save RubaXa/5896badb923f0805aa9fcdc480afe9cc to your computer and use it in GitHub Desktop.
Save RubaXa/5896badb923f0805aa9fcdc480afe9cc to your computer and use it in GitHub Desktop.
/* Example code
// Input
class Foo {
templateString = 'some value';
}
// Output
import __LIB__ from '@scope/lib/path/to/lib';
class Foo {
templateString = (function compiledTemplate(deps) {
// ...
return result;
})({lib: __LIB__});
}
*/
const ts = require('typescript');
function visitNodeAndChildren(node) {
if (node == null) return node;
return ts.visitEachChild(visitNode(node), (childNode) => visitNodeAndChildren(childNode));
}
function visitNode(node) {
if (node.kind === ts.SyntaxKind.PropertyDeclaration && node.name.text === 'template') {
// Generated code
const code = `(function compiledTemplate(deps) {
// ...
return result;
})({lib: __LIB__})`;
// 1. How implement?
const initializer = astFragmentFromString(tpl);
return ts.updateProperty(node, node.decorators, node.modifiers, node.name, node.type, initializer);
} else {
return node;
}
}
module.exports = function transformerFactory(context) {
return function (file) {
// 2. How add `import __LIB__ from '@scope/path/to/lib';`
file = addImport(file, '__LIB__', '@scope/path/to/lib');
return visitNodeAndChildren(file);
};
};
// ============== My attempts does not work :[ ===============
function astFragmentFromString(code) {
const fragment = ts.createSourceFile('./template.ts', code, ts.ScriptTarget.ES5);
return fragment;
}
function addImport(file, name, pathTo) {
file.statements.unshift(
ts.createImportDeclaration(
undefined,
undefined,
ts.createImportClause(ts.createIdentifier(name)),
ts.createLiteral(pathTo)
)
);
return file;
}
/**
* TypeError: Cannot read property 'kind' of undefined
* at checkGrammarModuleElementContext (node_modules/typescript/lib/typescript.js:44907:53)
*/
module.exports = function transformerFactory(context) {
return function (file) {
const imports = {};
const result = visitNodeAndChildren(file, context, imports);
Object.keys(imports).forEach(name => {
const importDecl = ts.createImportDeclaration(
undefined,
undefined,
ts.createImportClause(ts.createIdentifier(name)),
ts.createLiteral(imports[name])
);
file.statements = ts.createNodeArray([
importDecl,
...file.statements
]);
});
return result;
};
};
@hmmhmmhm
Copy link

hmmhmmhm commented Dec 27, 2018

Hello, can I ask you a question?

I am trying to inject a module
import statement by transformer.ts

(I refer a lot to your old code.
thanks to you for leaving a record.)

I succeeded in inserting the import statement
but the import statement that I injected
was not translated intermittently into the es5 grammar.

11
This is the code that I used in transfomer.js

12
Cord injection worked normally,
Although the company target option is designated as es5,
The code I inserted is having a problem that doesn't translate.

13
14

However, if I add an import statement that
has nothing to do with the module import code
I will inject to the source code before module injection,
the translation of the code I inserted is also successful.

hmm... is this compiling option problem...?
If so, which compiling options should be modified?
I don't know which code to modify... (x_x)

Have you ever had a problem like this?
If you know the solution, please let me know.

Anyway, thank you for leaving the code.

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