【问题标题】:How to configure TypeScript compilation for TS modules in an AngularJs application如何在 AngularJs 应用程序中为 TS 模块配置 TypeScript 编译
【发布时间】:2018-01-27 15:38:02
【问题描述】:

我通过下面描述的测试发现,显然,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
}

转译的 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;

转译的 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;
}());

转译的 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 编写的模块的目的是为了获得快速启动时间和动态模块加载的好处。

因此,即使 exports 存在于其中,转译后的 JS 代码也没有 requires。 Webpack 构建的 bundle.js 文件太小了,实际上无法包含所需的所有内容。

有没有办法或设置将已经存在的import {ServiceXYZ} from "./ServiceXYZ" TypeSscript 指令转换为适当的require 调用?

【问题讨论】:

  • 一种可能的解决方案是导出所有模块 - 如果库中未引用 ZipCodeValidator,则不使用它。一种可能的解决方案是导出所有预期存在于构建库中的内部导入。

标签: angularjs typescript


【解决方案1】:

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

只要ServiceXYZ 未被使用,

import {ServiceXYZ} from "./ServiceXYZ" 

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

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

【讨论】:

    【解决方案2】:

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

    TypeScript documentation says:

    编译器检测每个模块是否在发出的 JavaScript。如果模块标识符仅用作类型的一部分 注释并且从不作为表达式,则不需要调用 为该模块发出。

    所以,这是记录在案的功能,有些人是relying upon it,恐怕没有简单的方法。

    【讨论】:

      猜你喜欢
      • 2013-08-23
      • 1970-01-01
      • 2016-06-17
      • 2018-03-12
      • 2017-02-13
      • 2021-10-16
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      相关资源
      最近更新 更多