如何 运行 将 TypeScript 应用程序编译成带有 AMD 模块的单个文件?

How to run a TypeScript app compiled into a single file with AMD modules?

我确定我在这里遗漏了一些完全微不足道的东西,但我终究无法弄清楚。直到最近我才开始使用 AMD (RequireJS)。我的应用程序将(将)运行 在浏览器中。


设置

在 TypeScript 1.8 中,当使用 AMD 时,它是 possibletsc 由外部模块组成的整个项目到单个输出文件中。

出于这个原因,我最终决定留下内部模块并将我的所有 VS2015 项目 .ts.tsx 文件制作为外部模块,然后使用以下编译器将它们编译成一个文件参数:

--module AMD --outFile main.js

输出

单个输出main.js文件按预期创建,其中列出了属于项目的所有模块:

main.js

define("Project/MainModule", ["require", "exports" ...], function (require, exports ...) {
    "use strict";
    console.log("MainModule defined");
    // ...
});

...    

用法 (?)

现在,我如何从 Project/MainModule 到 运行 - 例如 - index.html(以便它记录 "MainModule defined"进入控制台)?我加载了 RequireJS 来处理 AMD 语法,以及指定用于立即加载的 main.js 文件:

index.html

<script data-main="main" src="Require.js"></script>

这会正确加载 main.js,我通过在该文件(外部模块)中的大量定义列表之后包含对 console.log 的调用来确保这一点。请原谅我,如果这是一个微不足道的问题,我找不到任何关于如何使用这种方法 使用 编译的应用程序的信息(也许我没有使用正确的 keywords? ).


编辑:我尝试通过模块名称请求模块:

index.html

<script>
    window.onload = function () {
        require(["Project/MainModule"], function () {
            // this
        });
    }
</script>

...但是不行,RequireJS找不到模块

TypeScript 编译器仅生成 define 次调用。要触发模块加载,您至少需要一个顶级 require 调用。

当使用 RequireJS 的 r.js 进行捆绑时,option 因为这个原因很好。

不确定如何使用 --outFile 来实现此目的。我相信您需要直接在 .ts.js 中使用 RequireJS API,就像在 index.html 中那样。只调用 require(["Project/MainModule"]); 就足够了。

您不想或不能将解决方案与 r.js, browserify or webpack 一起使用是有原因的吗?

对于高级 RequireJS 用户来说,这确实是一个微不足道的错误。


使用 AMD 语法和 --outFile 编译时创建的模块定义被命名为模块,according to RequireJS

要使用命名模块,必须通过将模块名称映射到模块路径来在 RequireJS 配置中定义它。在这种情况下,我们需要定义命名模块Project/MainModule在模块(文件)main:

index.html

<script>
    require.config({
        paths: {
            "Project/MainModule": "main"
        }
    });
</script>

然后按名称请求模块,现在可以从分配给它的文件中查找:

index.html

<script>
    require(["Project/MainModule"], function () {
        console.log("app loaded");
    });
</script>

注意:包含Require.js时必须省略data-main属性,否则模块将被加载两次(或者,至少上面的例子记录了两次)。

注2:这只是完整解决方案的一部分。必须为 TypeScript 编译器发出的 all 模块指定 module -> file 映射,这根本不可行。然而,这个相关问题有一个适用的

您应该通过脚本标签加载构建的文件:

<head>
    <script src="bower_components/dojo/dojo.js"></script>
    <script src="built/run.js"></script>
</head>

然后你可以使用 require:

加载模块
<body>
    <script>require(["app"], run => run());</script>
</body>

tsconfig.json:

{
    "compilerOptions": {
        "declaration": false,
        "module": "amd",
        "target": "es5",
        "noImplicitAny": true,
        "sourceMap": false,
        "out": "./built/run.js",
        "moduleResolution": "node"
    },
    "exclude": [
        "bower_components"
    ]
}

有关 dojo 示例,请参阅 https://github.com/ca0v/ags-lab/blob/master/index.html

有关 requirejs 示例,请参阅 https://github.com/ca0v/react-lab/blob/master/rawgit.html

有关杏仁的示例,请参阅 https://github.com/ca0v/html-playground/blob/master/playground/svg/svgeditor/index.html

或者,您可以使用 data-main 加载 requirejs 配置。该配置可以将构建的脚本指定为依赖项。例如:

requirejs.config({
    paths: {
        "openlayers": "bower_components/ol3/ol",
        "jquery": "bower_components/jquery/dist/jquery.min"
    },
    deps: ["built/run"],
    callback: () => {
        requirejs(["app"], run => run());
    }
});

并使用 data-main 加载它:

<head>
    <script src="bower_components/requirejs/require.js" data-main="config.js"></script>
</head>

https://github.com/ca0v/ol3-lab/blob/master/index.html

我已经为这个确切的用例编写了 SAMD:https://github.com/morris/samd

它提供了一个最小的 AMD 实现,足以支持通过常规脚本标签包含的 TypeScript AMD 包和依赖项。