我怎样才能避免总是必须在 Typescript 中导入我自己的代码?
How can I avoid always having to import my own code in Typescript?
所以我最近正在研究一个大型 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 模块系统,因此显然设置这些标志中的任何一个都不会对我有太大帮助。我已经 none 尝试了 less 以及其他各种标志组合,但无济于事。我注意到 BabylonJS 并没有像那样真正使用外部导入,而是选择将它们声明为外部导入,并在执行时将它们作为脚本标签全局提供。是否有类似的 Node?
你不能同时拥有这两个东西,即
How can I avoid always having to import my own code in Typescript?
和
I want to take advantage of some external modules
您只能通过不使用外部模块来避免导入,结果将是一个巨大的脚本文件,它只能将外部依赖项用作通过 script
标记加载的脚本创建的全局变量,正如您已经注意到的那样。
该语言不允许您在执行此操作时使用外部模块。如果你在顶层导入了外部模块,你的文件就变成了一个模块,如果不导入它们,它就无法使用其他文件中的代码。 AFAIK 不允许在命名空间中导入外部模块。
也就是说,我认为您的问题 - "How can I avoid always having to import my own code in Typescript?" - 没有有效前提。 CommonJS 模块系统是防止大型项目变得无法维护的混乱的解决方案。项目的某些部分是您自己的代码还是某些外部依赖项并不重要——如果它是具有定义良好接口的独立部分,则应将其打包并作为模块使用。
对我有用的解决方案是:
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 在正确方向上的推动。
所以我最近正在研究一个大型 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 模块系统,因此显然设置这些标志中的任何一个都不会对我有太大帮助。我已经 none 尝试了 less 以及其他各种标志组合,但无济于事。我注意到 BabylonJS 并没有像那样真正使用外部导入,而是选择将它们声明为外部导入,并在执行时将它们作为脚本标签全局提供。是否有类似的 Node?
你不能同时拥有这两个东西,即
How can I avoid always having to import my own code in Typescript?
和
I want to take advantage of some external modules
您只能通过不使用外部模块来避免导入,结果将是一个巨大的脚本文件,它只能将外部依赖项用作通过 script
标记加载的脚本创建的全局变量,正如您已经注意到的那样。
该语言不允许您在执行此操作时使用外部模块。如果你在顶层导入了外部模块,你的文件就变成了一个模块,如果不导入它们,它就无法使用其他文件中的代码。 AFAIK 不允许在命名空间中导入外部模块。
也就是说,我认为您的问题 - "How can I avoid always having to import my own code in Typescript?" - 没有有效前提。 CommonJS 模块系统是防止大型项目变得无法维护的混乱的解决方案。项目的某些部分是您自己的代码还是某些外部依赖项并不重要——如果它是具有定义良好接口的独立部分,则应将其打包并作为模块使用。
对我有用的解决方案是:
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 在正确方向上的推动。