Given the following ES module;
import {child} from './childFile';
const local = 'local';
export {child, local}
I can extract the file references for exports in a ts.SourceFile: (given a valid program and checker in tsc v5.2.2)
const fileSymbol = checker.getSymbolAtLocation(sourceFile);
fileSymbol?.exports?.forEach((symbol) => {
console.log(symbol.name); //'local' or 'child'
const nodes = symbol.declarations!;
console.log(ts.SyntaxKind[nodes[0].kind]); //ExportSpecifier
const targets = checker.getAliasedSymbol(symbol)?.declarations!;
console.log(targets[0].getSourceFile().fileName); //'./localFile' or './childFile'
});
Given the equivalent CommonJs module I am struggling to achieve the same result:
const {child} = require('./child');
const local = 'local';
exports = {child, local}
I have tried the following:
- Using compilerOption 'module':'NodeNext':
const fileSymbol = checker.getSymbolAtLocation(sourceFile);
console.log(fileSymbol); //undefined
- Using compilerOption 'module':'NodeNext'
const fileSymbol = checker.getSymbolAtLocation(sourceFile);
console.log(fileSymbol?.exports) //Map(0) {}
(source as any).locals.forEach((symbol: ts.Symbol) => {
console.log(symbol.name); //'child' or 'local'
const nodes = symbol.declarations!;
console.log(ts.SyntaxKind[nodes[0].kind]); //BindingElement or VariableDeclaration
if (ts.isBindingElement(nodes[0])) {
const node = nodes[0];
let bindingSymbol = checker.getSymbolAtLocation(node);
console.log(bindingSymbol); // undefined;
bindingSymbol = checker.getSymbolAtLocation(node.name);
const alias = checker.getAliasedSymbol(bindingSymbol!);
console.log(alias) //undefined;
/**
* and from here I am stuck as to how to get the target filename of the export
*/
}
});
I have been exploring the flowNode and throwing things at the checker to try and find the hook to replicate the ES workflow, but am only going further down rabbit holes...
Help in the right direction in replicating the ES module logic will be appreciated.
This is what I have come up with in all it's hacky nastiness:
Firstly, I switched to what TypeScript wants for a commonJs module (which I now know is
export =and notexports =), which opened up access to fileSymbol.exports.The commonJs module is now:
From there I can do;
I hope that I am missing something in the API and somebody will point me towards a concise solution...