TS编译器API:防止导出.出现在没有导出修饰符的节点上 [英] TS compiler API: prevent Export. to appear on nodes where there is not a export modifier

查看:99
本文介绍了TS编译器API:防止导出.出现在没有导出修饰符的节点上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在js中,声明的导出变量如下:"Exports.my_var = cool_value"

in js an exported variable is declared like: "Exports.my_var = cool_value ",

使用Typyscript编译器api时,我有一些最初具有export修饰符的变量,如:

when using the Typyscript compiler api i have some varibales that originally have the export modifier like:

export let a = 1;
a = a + 1;

解析为

Exports.a = 1;
Exports.a = Exports.a + 1;

但是我不希望将它们导出到js文件中,我尝试删除节点上的export修饰符,但它们仍使用Exports进行编译.

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]

一些示例代码

变形金刚:

 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.一个.

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';

输出:

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 属性.

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);
    };

基本上,编译器在转换阶段之前收集要导出的所有名称,然后将所有与导出名称匹配的标识符替换为具有 exports.前缀.因此,剥离 export 修饰符无效,因为编译器已确定要导出的名称.

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.

这篇关于TS编译器API:防止导出.出现在没有导出修饰符的节点上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆