TypeScript 阻止文件成为模块?

TypeScript stop file from becoming a module?

我正在使用导入和导出,因为据说引用已过时。但是,我想编译成一个文件,并且我正在使用“系统”模块,但即使没有导出任何内容,它也会将所有内容都变成一个模块。如果导入任何内容,则不执行代码,但如果未导入或导出任何内容,则执行代码。我需要导入文件才能使用它们,但我不能,因为代码变成了模块函数。

这是我的 tsconfig.json:

{
    "compilerOptions": {
        "module": "system",
        "noImplicitAny": true,
        "removeComments": true,
        "preserveConstEnums": true,
        "sourceMap": false,
        "outFile": "{PATH}"
    }
}

我的 TypeScript 代码:

import { Button } from "UI/Button";

new Button("Hello World!");
console.log("HELLO!");

编译后的代码变成这样:

System.register("Main/main", ["UI/Button"], function (exports_4, context_4) {
    "use strict";
    var Button_1;
    var __moduleName = context_4 && context_4.id;
    return {
        setters: [
            function (Button_1_1) {
                Button_1 = Button_1_1;
            }
        ],
        execute: function () {
            new Button_1.Button("Hello World!");
            console.log("HELLO!");
        }
    };
});

如果我删除导入并只保留 console.log:

console.log("HELLO!");

它删除了所有没有导入的东西,甚至是以前的模块,因为我猜它没有检测到它们被使用。

我假设我误解了 import/export 系统的工作原理?我希望能够 运行 函数和 import/export 文件,但截至目前看来我只能 import/export 文件,而不是 运行 它们。我也希望所有这些都编译成一个文件。如有任何帮助,我们将不胜感激!

您需要从您的 HTML 文件中 运行 这些脚本,使用 SystemJS 调用它们(如在您的 tsconfig.json 中)。

importexport 的存在是 TypeScript 可以推断您是否正在编写 的方式之一。编译输出的巨大变化来自于 TypeScript 将您的文件解释为一个模块,当且仅当它具有 importexport 语句时。

模块背后的思想,来自 Mozilla 的 cartoon introduction:

Modules give you a better way to organize these variables and functions. With modules, you group the variables and functions that make sense to go together.

This puts these functions and variables into a module scope. The module scope can be used to share variables between the functions in the module.

But unlike function scopes, module scopes have a way of making their variables available to other modules as well. They can say explicitly which of the variables, classes, or functions in the module should be available.

模块背后的整个想法是,您可以推迟作为 UI/Button 模块(或您编写的任何其他模块)的一部分发生的加载,直到您需要它为止。 UI/Button 初始化只发生一次,并且只允许您访问您 export 的变量、函数和 类。 (也就是说,模块也可能像您的 console.log 一样具有“副作用”:这些不是导出值,它们只是执行模块时发生的可见事件。)此外,每个模块都在自己的内部执行命名空间(这里是它自己的 execute 函数),所以如果一个模块定义了一个 counter 变量,它不会干扰另一个模块的 counter 变量。

您选择了 system TypeScript 模块格式,也称为 SystemJS. In doing so, you're signing up to have SystemJS manage your module loading, which would allow you to call System.import to load your Main/main module from the compiled Javascript you've posted. At that point you would see the output you expect because you've specifically requested it. When specifying an outFile as you have, you can also pick AMD (which will also require specifying your "entry point") or "None" (which will )。

一旦你对模块有了更好的理解,你就可以研究像 Webpack 这样的“捆绑器”。这些系统遍历您的所有模块——可能是一个文件,也可能是多个文件——并将它们捆绑到一个文件中,如您所描述的。您甚至可以告诉 Webpack 您打算将哪个模块作为入口点,它会 运行 在脚本加载后立即自动执行——就像老式的 JS 脚本一样。