如何在AngularJs应用程序中为TS模块配置TypeScript编译

时间:2018-01-27 15:38:03

标签: angularjs typescript

我通过下面描述的测试发现,显然,TypeScript 2.6.2要求在new中实际引用模块之前在require中使用导入的元素。

以下两段代码,在撰写本文时从官方的TypeScript文档中提取,构成了我正在讨论的测试的基础。

ZipCodeValidator.ts:

export interface StringValidator {
    isAcceptable(s: string): boolean;
}

export const numberRegexp = /^[0-9]+$/;

class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator };

SimpleModule.ts:

import { ZipCodeValidator } from "./ZipCodeValidator";

class Test {
    constructor(validator: ZipCodeValidator) {
        let myValidator = new ZipCodeValidator(); // <- NOTE THIS LINE.
        let x = 1;
    }
}

tsconfig.json:

{
    "compilerOptions": {
        "declaration": false,
        "emitDecoratorMetadata": false,
        "experimentalDecorators": false,
        "module": "CommonJS",
        "moduleResolution": "classic",
        "noFallthroughCasesInSwitch": false,
        "noImplicitAny": false,
        "noImplicitReturns": false,
        "outDir": "dist/scripts",
        "removeComments": false,
        "sourceMap": false,
        "strictNullChecks": false,
        "target": "es3"
    },
    "include": [
        "app/ts/**/*.ts"
    ],
    "compileOnSave": true,
    "buildOnSave": true
}

Transpiled ZipCodeValidator.js:

"use strict";
exports.__esModule = true;
exports.numberRegexp = /^[0-9]+$/;
var ZipCodeValidator = /** @class */ (function () {
    function ZipCodeValidator() {
    }
    ZipCodeValidator.prototype.isAcceptable = function (s) {
        return s.length === 5 && exports.numberRegexp.test(s);
    };
    return ZipCodeValidator;
}());
exports.ZipCodeValidator = ZipCodeValidator;
exports.mainValidator = ZipCodeValidator;

Transpiled SimpleModule.js(突出显示的行保持原样 - 可以看到有一个require调用):

"use strict";
exports.__esModule = true;
var ZipCodeValidator_1 = require("./ZipCodeValidator");
var Test = /** @class */ (function () {
    function Test(validator) {
        var myValidator = new ZipCodeValidator_1.ZipCodeValidator();
        var x = 1;
    }
    return Test;
}());

Transpiled SimpleModule.js(突出显示的行已注释掉 - require调用已消失):

"use strict";
exports.__esModule = true;
var Test = /** @class */ (function () {
    function Test(validator) {
        //let myValidator = new ZipCodeValidator();
        var x = 1;
    }
    return Test;
}());

对我来说,这是有问题的,因为我已经将AngularJs应用程序转换为TypeScript而我使用的是模块而不是命名空间,因为我想使用Webpack在每个模块中构建可重用的组件。我没有new件事:AngularJs为我做了这件事。我转换为使用TS编写的模块的目的是最终获得快速启动时间和动态模块加载的好处。

因此,即使require存在,但已编译的JS代码也没有exports s。由Webpack构建的bundle.js文件太小,实际上不包含所需的所有内容。

是否有办法或设置让已存在的import {ServiceXYZ} from "./ServiceXYZ" TypeSscript说明变为适当的require来电?

2 个答案:

答案 0 :(得分:1)

使require出现在生成代码中的唯一方法是在运行时实际使用一些导入的值,可以是new,也可以是代码中的其他方式。

TypeScript documentation says

  

编译器检测是否在发出的模块中使用了每个模块   JavaScript的。如果模块标识符仅用作类型的一部分   注释,永远不作为表达,然后不需要调用   为该模块发射。

所以,这是记录的功能,有些人是relying upon it,我担心没有简单的方法。

答案 1 :(得分:1)

此行为为specific to TypeScript imports。它删除了可能未使用的代码片段,并且在大多数情况下都是受欢迎的。

只要ServiceXYZ未使用,

import {ServiceXYZ} from "./ServiceXYZ" 

将被忽略。如果可能使用模块导出,但它也提供副作用并且应该以任何方式导入,则应重复导入:

import "./ServiceXYZ";
import {ServiceXYZ} from "./ServiceXYZ"