如何避免总是在Typescript中导入我自己的代码?

时间:2018-06-05 20:32:59

标签: node.js typescript commonjs

所以我最近攻击了一个大型的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类似?

2 个答案:

答案 0 :(得分:1)

你不能同时拥有这两件事,即

  

如何避免总是在Typescript中导入我自己的代码?

  

我想利用一些外部模块

您可以仅通过不使用外部模块来避免导入,结果将是一个巨大的脚本文件,只能将外部依赖项用作通过script标记加载的脚本创建的全局变量,正如您已经注意到的那样。

执行此操作时,该语言不允许您使用外部模块。如果您在顶层导入外部模块,则您的文件将成为一个模块,并且无法在不导入其他文件的情况下使用其他文件中的代码。并且不允许在命名空间内导入外部模块AFAIK。

那就是说,我不会想你的问题 - "我怎样才能避免总是必须在Typescript中导入我自己的代码?" - 有一个有效的前提。 CommonJS模块系统是防止大型项目变得难以维护的混乱的解决方案。如果项目的某些部分是您自己的代码或某些外部依赖项并不重要 - 如果它是具有定义良好的接口的单独部分,则应将其打包并作为模块使用。

答案 1 :(得分:0)

对我有用的解决方案是:

Server.ts

declare var http: any;

namespace Test {
  export class Server {
    constructor() {
      console.log('Server initialized')
      const server = http.createServer()
      server.listen()
    }
  }
}

然后我只是在运行时提供http,例如通过在输出前加var http = require('http')。感谢artem在正确的方向上轻推。