首页 > 解决方案 > TypeScript outFile 通过 Requirejs 未按预期运行

问题描述

我目前正在尝试设置和学习 TypeScript,但我无法让模块以理智的方式运行。

语境

我有两个 ts 文件,main.tstypes.ts. main.ts是我的单一入口点,types.ts只是一个带有几个接口的测试文件。我还有一个tsconfig.json文件,其中定义了目标 (ES6)、模块 (AMD) 和 outFile。

我的目标是能够将我的整个项目转储到单个 JavaScript 文件中,而不是需要将一大堆脚本标签添加到我的 html 中。

// types.ts
export interface Time {
    unix: number;
}
// main.ts
import {Time} from "types";
document.addEventListener("DOMContentLoaded", () => {
    let x: Time = { unix: 12345 };
    alert(x.unix);
});
<!-- index.html -->
<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="static/styles/styles.css" />
    <script data-main="static/scripts/timeapp" src="static/scripts/require.js" async></script>
</head>
<body>
    <header></header>
    <main></main>
    <footer></footer>
</body>

问题

tsc将我的项目编译成单个文件时,因为我的main.ts文件有一个导入(因为它当然有),它也被归类为一个模块。这显然导致require.js......不做任何事情。我的代码都没有被执行。没有错误,没有输出,什么都没有。我的两个文件最终都被包裹在define块中,我真的不知道该怎么做。

define("types", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
});
define("main", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    document.addEventListener("DOMContentLoaded", () => {
        let x = {
            unix: 12345
        };
        alert(x.unix);
    });
});
//# sourceMappingURL=time.js.map

我发现顶级导入将文件分类为模块是非常不合理的。出口是肯定的,但单独进口对我来说毫无意义。也许有人也可以详细说明?

标签: javascripttypescriptrequirejs

解决方案


好吧,我终于想通了,我有点生气。requirejs 网站上的任何地方或我在 SO、博客等上阅读的任何内容都没有人清楚地解释它是如何工作的。

首先,推荐的方法是完全没用的,因为异步使得无法保证加载哪些文件,并且该DOMContentLoaded事件仅触发一次,因此如果您的文件加载有点晚并且您依赖该保证,您的代码将只是从不执行。所以这里是你如何使用这个东西:

  1. 将您的 ts 代码编译到您的单个 js 文件中,该文件充满了定义。
  2. 创建一个小 js 文件,用作您的...入口点的入口点。
  3. 尽管您读过的所有内容都告诉您这是错误的方式,但在您的 html 中同步加载您的 js 文件。
// app.js
define("types", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
});
define("app", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    let x = {
        unix: 12345
    };
    alert(x.unix);
});
//# sourceMappingURL=app.js.map
// main.js
document.addEventListener("DOMContentLoaded", () => {
    require(["app"], () => {});
});
<!-- index.html -->
<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="static/styles/styles.css" />
    <script src="static/scripts/require.js"></script>
    <script src="static/scripts/app.js"></script>
    <script src="static/scripts/main.js"></script>
</head>
<body></body>

如果有人可以为我提供更好的答案,我会全力以赴。


推荐阅读