TypeScript AMD无法解析自定义require.config baseUrl的外部模块

5
我在使用 TypeScript + RequireJS 时遇到了一些问题。 我有两个项目(主要项目和单元测试项目)。 它看起来像这样: moduleA.ts:(接下来应该是代码示例,但未提供)
export class A {
    constructor(someThing: string) {
        this.someThing = someThing;
    }
    someThing: string;
}
export var aInst = new A("hello from module A");


moduleB.ts:

import moduleA = require('moduleA');

export class B {
    private a: moduleA.A;

    constructor(a: moduleA.A) {
        this.a = a;
    }

    getSomeThing() {
        return this.a.someThing;
    }
}

export var bInst = new B(moduleA.aInst);


requireConfig.js:

require.config({
    baseUrl: "/app",
});


myTest.ts:

import moduleB = require('moduleB');

QUnit.test('my test', () => {
    QUnit.equal("hello from module A", moduleB.bInst.getSomeThing());
});


testRequreConfig.js:

require.config({
    baseUrl: "../Base/app",
});


index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">

    <link rel="stylesheet" href="Content/qunit.css" type="text/css" />
    <script type="text/javascript" src="Scripts/qunit.js"></script>

    <script src="Scripts/require.js"></script>
    <script src="test/testRequreConfig.js"></script>
</head>
<body>
    <h1 id="qunit-header">Unit Tests</h1>
    <h2 id="qunit-banner"></h2>
    <h2 id="qunit-userAgent"></h2>
    <ol id="qunit-tests"></ol>
    <div id="qunit-fixture">test markup, will be hidden</div>

    <script type="text/javascript">
        (function () {
            QUnit.config.autostart = false;
            require(['test/myTest.js'], QUnit.start);
        }());
    </script>
</body>
</html>

我们无法改变“基础”项目。 我们希望能够在“测试”项目中使用“moduleB”(通过'requirejs'按'moduleB'字符串加载)。 我们拥有:
unable to load
TypeScript编译器无法解析外部模块(因为它不知道在哪里查找它)。 如果我们放置:

declare module "moduleB" {
 
    export  ...
}

在*.d.ts文件中声明 - 然后我们就能够使用它。但在实际项目中,我们有很多TypeScript文件,不可能为每个文件手动编写'declare'。 有没有处理它的方法? 主要问题是事实上,由于某些原因,我们无法编辑require.config。
是否有可能让tsc.exe了解require.config?

目前的解决方法是为每个模块编写一个 .d.ts 文件,例如 declare module "moduleB" {...} 并使用自定义名称(相对于 require.config baseUrl)。是否有可能让 tsc.exe 生成带有自定义名称字符串的环境模块声明的 .d.ts 文件?如果我们可以在 tsc 生成的 .d.ts 文件的内容周围添加 declare module %some_string% {} (并删除所有内部的 declare 关键字),那将是非常棒的。 - Valery Petrov
好的,已经完成了“构建后”事件和通过tsc生成的.d.ts文件的更正(使用declare module包装,并与require.config中的baseUrl相对路径对应)。 这是一个可行的解决方法,但仍然只是一个解决方法。继续寻找更好的解决方案。 - Valery Petrov
2个回答

3

是否有可能让tsc.exe知道require.config?

很遗憾,不行。您有两个选择:创建def文件告诉typescript关于配置,或使用完整的相对路径。


完整路径对我来说不是解决方案,因为在项目中我们有模块依赖项,这些依赖项在运行时由requirejs解析,并具有自定义的baseUrl(我们导入模块,该模块又导入另一个模块,以此类推)。 - Valery Petrov
@ValeryPetrov 完整的相对路径 - basarat
1
相对路径和绝对路径都不是我们问题的解决方案,因为我们在require.config中有自定义的baseUrl。因此,如果我们在**import ... = require(...)结构中放置完整的相对路径,requirejs将无法找到任何模块。 所有问题都是由于自定义的baseUrl - tsc对此一无所知,如果我们在require(...)**中放置正确的requirejs路径(相对于baseUrl和其他require.config),它也找不到任何模块。 - Valery Petrov
1
@ValeryPetrov,你有找到解决方法吗?我也在苦苦挣扎着。 - Yngvar Kristiansen
1
@YngvarKristiansen 相对路径始终相对于当前文件,并且不应受 baseUrl 的影响。我使用这个(并与其他人一起维护):https://github.com/grunt-ts/grunt-ts#transforms - basarat
@basarat 这并不完全正确,至少对于我在Visual Studio 2013中的项目来说不是这样。我可以从任何文件夹中执行“import myModule = require('src/whatever')”。 “src”是“/Front_End”的子文件夹,后者是baseUrl。 在此处查看代码:http://tinyurl.com/q8w2kvj(main.ts用于配置,module.ts作为导入示例)。 我不知道Visual Studio或TS编译器如何找到这些文件夹。感谢您提供的链接,看起来非常有趣。 - Yngvar Kristiansen

0
我找到了一个解决方法,可能也能帮到你。
我注意到在jquery.d.ts文件的底部有以下代码:
declare module "jquery" {
    export = $;
}
declare var jQuery: JQueryStatic;
declare var $: JQueryStatic;

当 TypeScript 遇到 import x=require(<module string>); 语句时,会发现环境模块声明。

使用这种技术,您可以定义自己的类型,然后添加一个环境模块声明,导出这些类型并在 require 中被识别。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接