【发布时间】:2018-06-06 21:14:45
【问题描述】:
所以我最近正在研究一个大型 Typescript 项目 (https://github.com/BabylonJS/Babylon.js),我注意到他们不需要导入任何东西,他们只需使用他们的命名空间,其余的就是(看似)魔法。
这让我想到我想为自己使用类似的东西,所以我开始了一个简单的打字稿项目来尝试一下。
tsconfig.json
{
"compilerOptions": {
"baseUrl": "src",
"outFile": "server.js"
}
}
src/main.ts
module Test {
console.log('Main started')
const server:Server = new Server()
}
src/Server.ts
// import * as http from 'http'
module Test {
export class Server {
constructor() {
console.log('Server initialized')
}
}
}
如果我构建这个 Typescript 项目,那么我会得到如下输出:
// import * as http from 'http'
var Test;
(function (Test) {
var Server = /** @class */ (function () {
function Server() {
console.log('Server initialized');
}
return Server;
}());
Test.Server = Server;
})(Test || (Test = {}));
var Test;
(function (Test) {
console.log('Main started');
var server = new Test.Server();
})(Test || (Test = {}));
到目前为止,一切都很好。问题是我想利用一些外部模块,在这种情况下是 http 模块,所以我取消了上面的导入行,现在 Typescript 报告:
src/server/Server.ts(1,1): error TS6131: Cannot compile modules using option 'outFile' unless the '--module' flag is 'amd' or 'system'.
Node 使用 commonjs 模块系统,因此显然设置这些标志中的任何一个都不会对我有太大帮助。我仍然尝试过它们以及其他各种标志组合,但无济于事。我注意到 BabylonJS 并没有真正使用这样的外部导入,而是选择将它们声明为外部并在执行时将它们作为脚本标签全局提供。有没有类似 Node 的东西?
【问题讨论】:
-
module语法已弃用,typescriptlang.org/docs/handbook/modules.html。出于多种原因,最好显式地导入内容。使用 outFile 唯一明显的好处是您可以跳过捆绑,这与 Node 应用程序无关,因为它自然使用不需要进一步捆绑的 CommonJS 模块。 -
有趣的是编译器没有提到这一点,但似乎
namespace关键字是等效的并且仍然受支持。我正在使用outFile,因为否则每个输入的打字稿文件都会被翻译成一个输出的 Javascript 文件,然后它们必须全部执行或捆绑起来才能工作。如果有一个构建工具可以帮助支持我感兴趣的配置,那么我愿意接受建议! -
那么它们必须全部执行或捆绑起来才能工作 - 这就是通常的做法。您将它们编译到
dist文件夹并作为常规 Node js 应用程序执行。不需要捆绑。您可以使用 ts-node 透明地执行此操作。 -
很抱歉给您带来了困惑。我的意思是他们必须进一步处理才能工作。使用
outFile,Server.ts的内容被连接起来并在main.ts的内容之前运行,所以一切正常。使用outDir会有单独的文件,运行main.js是不够的。 -
它是 Node 应用程序,不是吗?
import语句被转译为require,因此如果您明确声明模块依赖关系,则运行入口点就足够了。
标签: node.js typescript commonjs