Уберите декоратор Typescript в сборке релиза - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть время отладки Typescript decorator @log, который регистрирует ввод / вывод / статистику оформленных функций.

Я бы хотел полностью удалить этот конкретный @log декоратор при компиляции релизной версии.

Легко удалить операторы console.log из сборки выпуска или сделать что-то условно в коде декоратора, но я хотел бы убедиться, что нет никаких издержек при вызове самой функции декоратора.

Есть ли способ достичь этого с помощью Typescript?

Мой проект основан на веб-пакетах. Если это невозможно с Typescript, может быть, это можно сделать на более поздней стадии с плагином Babel, с UglifyJS или каким-либо другим альтернативным плагином?

1 Ответ

0 голосов
/ 04 сентября 2018

Задавая этот вопрос, я полностью упустил из виду один неловко тривиальный аспект. Сама функция декоратора вызывается только один раз для каждого объявления метода. Если декоратор вычисляется во время инициализации для функции no-op, накладные расходы будут возникать только во время инициализации, и они будут довольно минимальными, как показано в коде ниже.

Инстанцирование класса и вызовы функций во время выполнения функций, отмеченных с помощью декоратора @log, будут свободны от любых издержек.

const DEBUG = false;

const logDebug = function(_target: any, key: string, descriptor: PropertyDescriptor): any {
    console.log("log(): called");

    const originalMethod = descriptor.value;
    descriptor.value = function(...args: any[]) {
        const functionName = key;
        console.log(functionName + "(" + args.join(", ") + ")");
        const result = originalMethod.apply(this, args);
        console.log("=> " + result);
        return result;
    };
    return descriptor;
};
const logNoop = function() {};
const log = DEBUG ? logDebug : logNoop;

class Test {
    @log
    test(a: number, b: number) {
        console.log("test(): called", a, b);
    }
}

new Test().test(1, 2);
new Test().test(3, 5);

Фрагмент скомпилированного JS, чтобы показать, что издержки действительно минимальны:

var Test = /** @class */ (function () {
    function Test() {
    }
    Test.prototype.test = function (a, b) {
        console.log("test(): called", a, b);
    };
    __decorate([
        log
    ], Test.prototype, "test", null);
    return Test;
}());
...