TS 编译器 API:阻止导出。出现在没有导出修饰符的节点上
TS compiler API: prevent Export. to appear on nodes where there is not a export modifier
在 js 中,导出的变量声明如下:
"Exports.my_var = cool_value "
,
当使用 Typyscript 编译器时 api 我有一些最初具有导出修饰符的变量,例如:
export let a = 1;
a = a + 1;
解决于
Exports.a = 1;
Exports.a = Exports.a + 1;
但我不想将它们导出到 js 文件中,我尝试删除节点上的导出修饰符,但它们仍然与导出一起编译。
[更新]
一些示例代码
变形金刚:
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 和 visitEachChild 是自定义函数,但作为 ts 工作。一个。
test.ts:
export let a = 30;
export let z = 10;
z = z + a;
a = a + z;
export let c = 'hello';
c = 'hey there';
输出:
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';
似乎一种方法是将所有标识符设置为具有 LocalName
发出标志并删除源文件中的内部 externalModuleIndicator
属性。
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);
};
基本上,编译器会在转换阶段之前收集所有要导出的名称,然后用 exports.
前缀替换所有与导出名称匹配的标识符。所以剥离 export
修饰符没有效果,因为编译器已经决定了要导出的名称。
在 js 中,导出的变量声明如下:
"Exports.my_var = cool_value "
,
当使用 Typyscript 编译器时 api 我有一些最初具有导出修饰符的变量,例如:
export let a = 1;
a = a + 1;
解决于
Exports.a = 1;
Exports.a = Exports.a + 1;
但我不想将它们导出到 js 文件中,我尝试删除节点上的导出修饰符,但它们仍然与导出一起编译。
[更新]
一些示例代码
变形金刚:
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 和 visitEachChild 是自定义函数,但作为 ts 工作。一个。
test.ts:
export let a = 30;
export let z = 10;
z = z + a;
a = a + z;
export let c = 'hello';
c = 'hey there';
输出:
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';
似乎一种方法是将所有标识符设置为具有 LocalName
发出标志并删除源文件中的内部 externalModuleIndicator
属性。
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);
};
基本上,编译器会在转换阶段之前收集所有要导出的名称,然后用 exports.
前缀替换所有与导出名称匹配的标识符。所以剥离 export
修饰符没有效果,因为编译器已经决定了要导出的名称。