问题
in js an exported variable is declared like:
"Exports.my_var = cool_value "
,
when using the Typyscript compiler api i have some varibales that originally have the export modifier like:
export let a = 1;
a = a + 1;
that resolves in
Exports.a = 1;
Exports.a = Exports.a + 1;
but i don't want them to be exported in the js file, i tried removing the export modifiers on the nodes, but they are still compiled with the Exports.
[UPDATE]
some example code
Transformer:
ast = VisitNode(ast,function() {
let visitor = (n) => {
console.log('VISITING',n.kind);
if(n.modifiers) {
n.modifiers = undefined;
console.log(n.modifiers);
}
return visitEachChild(n,visitor,ctx);
}
return visitor;
}());
return ast;
VisitNode and visitEachChild are custom function, but work as the ts. ones.
test.ts:
export let a = 30;
export let z = 10;
z = z + a;
a = a + z;
export let c = 'hello';
c = 'hey there';
output:
exports.a = 30;
exports.z = 10;
exports.z = exports.z + exports.a;
exports.a = exports.a + exports.z;
exports.c = 'hello';
exports.c = 'hey there';
回答1:
It seems one way to do it is to set all the identifiers to have a LocalName
emit flag and remove the internal externalModuleIndicator
property on the source file.
const transformer = <T extends ts.Node>(context: ts.TransformationContext) =>
(rootNode: T) => {
function visit(sourceFile: ts.Node): ts.Node {
if (!ts.isSourceFile(sourceFile))
throw new Error("This code only works with a source file.");
// strip this internal property to get rid of `exports.__esModule = true;`
delete (sourceFile as any).externalModuleIndicator;
return ts.visitEachChild(sourceFile, statement => {
// remove the export modifiers
if (statement.modifiers) {
const newModifiers = statement.modifiers
.filter(m => m.kind !== ts.SyntaxKind.ExportKeyword);
statement.modifiers = ts.createNodeArray(newModifiers);
}
return ts.visitEachChild(statement, visitIdentifiers, context);
function visitIdentifiers(descendant: ts.Node) {
if (ts.isIdentifier(descendant))
return ts.setEmitFlags(descendant, ts.EmitFlags.LocalName);
return ts.visitEachChild(descendant, visitIdentifiers, context);
}
}, context);
}
return ts.visitNode(rootNode, visit);
};
Basically, the compiler collects all the names to export before the transformation phase, then it substitutes all the identifiers that match an exported name to have an exports.
prefix. So stripping the export
modifier has no effect because the compiler has already decided what names to export.
来源:https://stackoverflow.com/questions/58793176/ts-compiler-api-prevent-export-to-appear-on-nodes-where-there-is-not-a-export