API компилятора TS: запретить экспорт. появляться на узлах, где нет модификатора экспорта - PullRequest
1 голос
/ 11 ноября 2019

в js экспортируемая переменная объявляется как: "Exports.my_var = cool_value ",

при использовании API компилятора Typyscript, у меня есть некоторые вариабельные значения, которые изначально имеют модификатор экспорта, например:

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

1 Ответ

1 голос
/ 11 ноября 2019

Кажется, один из способов сделать это - установить для всех идентификаторов флаг LocalName emit и удалить внутреннее свойство 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 не имеет никакого эффекта, потому что компилятор уже определил, какие имена экспортировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...