将外部 javascript 库导入 Typescript 以与节点一起使用
Importing external javascript libraries into Typescript for use with node
前段时间我们开始使用 Typescript + Electron 编写基于浏览器的桌面应用程序。但是,加载外部 Javascript 库通常是一个瓶颈。我们尽可能多地使用 typings
,这为我们完成了大部分工作,但一些 Javascript 库(目前)还不能通过这种方式使用。
要开始编写新的声明文件,我首先想尝试使用 DefinitelyTyped repository 中已有的声明文件而不是 typings
。这是 abs 库的一个简单示例:
tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true,
"types": [
"node"
]
},
"files": [
"abs.d.ts",
"abs-tests.ts"
]
}
abs.d.ts:
// Type definitions for abs 1.1.0
// Project: https://github.com/IonicaBizau/node-abs
// Definitions by: Aya Morisawa <https://github.com/AyaMorisawa>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "abs" {
/**
* Compute the absolute path of an input.
* @param input The input path.
*/
function Abs(input: string): string;
export default Abs;
}
abs-tests.ts:
/// <reference path="./abs.d.ts" />
import Abs from 'abs';
const x: string = Abs('/foo');
转录和运行输出的Javascript文件节点:
npm install @types/node --save-dev;
npm install abs;
tsc -p tsconfig.json;
node abs-tests.js;
转录的Javascript文件:
"use strict";
var abs_1 = require('abs');
var x = abs_1["default"]('/foo');
//# sourceMappingURL=abs-tests.js.map
节点输出:
<my-path>/abs-tests.js:3
var x = abs_1["default"]('/foo');
^
TypeError: abs_1.default is not a function
at Object.<anonymous> (<my-path>/abs-tests.js:3:25)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.runMain (module.js:590:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
这只是许多不同库失败的测试之一。这里出了什么问题?是否可以就使用外部 Javascript 库正确转录 Typescript 代码以便在节点中使用它给出一些解释?
基本上,export default
不适用于此用例。
Typescript 有特殊的 export =
和 import = require()
syntax 用于处理节点模块。
当节点模块将单个对象或函数分配给其 exports
对象时,可以使用 export =
。这就是 abs
模块在其 index.js:
中所做的
module.exports = abs;
它的类型声明可以这样写:
declare module "abs" {
/**
* Compute the absolute path of an input.
* @param input The input path.
*/
function Abs(input: string): string;
export = Abs;
}
并像这样使用
import Abs = require('abs');
const x: string = Abs('/foo');
(旁注:如果它包含在 tsconfig.json 中的 files
中,您甚至不需要 /// <reference
abs.d.ts)
如果你出于某种原因必须将它用作 export default
,你将无法单独使用打字稿 - 你需要将它编译为 es6 并使用另一个像 Babel 这样的转译器支持 export default
与节点的兼容性。您可以在 typescript issue and this blog post.
中找到详细信息
前段时间我们开始使用 Typescript + Electron 编写基于浏览器的桌面应用程序。但是,加载外部 Javascript 库通常是一个瓶颈。我们尽可能多地使用 typings
,这为我们完成了大部分工作,但一些 Javascript 库(目前)还不能通过这种方式使用。
要开始编写新的声明文件,我首先想尝试使用 DefinitelyTyped repository 中已有的声明文件而不是 typings
。这是 abs 库的一个简单示例:
tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true,
"types": [
"node"
]
},
"files": [
"abs.d.ts",
"abs-tests.ts"
]
}
abs.d.ts:
// Type definitions for abs 1.1.0
// Project: https://github.com/IonicaBizau/node-abs
// Definitions by: Aya Morisawa <https://github.com/AyaMorisawa>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
declare module "abs" {
/**
* Compute the absolute path of an input.
* @param input The input path.
*/
function Abs(input: string): string;
export default Abs;
}
abs-tests.ts:
/// <reference path="./abs.d.ts" />
import Abs from 'abs';
const x: string = Abs('/foo');
转录和运行输出的Javascript文件节点:
npm install @types/node --save-dev;
npm install abs;
tsc -p tsconfig.json;
node abs-tests.js;
转录的Javascript文件:
"use strict";
var abs_1 = require('abs');
var x = abs_1["default"]('/foo');
//# sourceMappingURL=abs-tests.js.map
节点输出:
<my-path>/abs-tests.js:3
var x = abs_1["default"]('/foo');
^
TypeError: abs_1.default is not a function
at Object.<anonymous> (<my-path>/abs-tests.js:3:25)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.runMain (module.js:590:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
at bootstrap_node.js:509:3
这只是许多不同库失败的测试之一。这里出了什么问题?是否可以就使用外部 Javascript 库正确转录 Typescript 代码以便在节点中使用它给出一些解释?
基本上,export default
不适用于此用例。
Typescript 有特殊的 export =
和 import = require()
syntax 用于处理节点模块。
exports
对象时,可以使用 export =
。这就是 abs
模块在其 index.js:
module.exports = abs;
它的类型声明可以这样写:
declare module "abs" {
/**
* Compute the absolute path of an input.
* @param input The input path.
*/
function Abs(input: string): string;
export = Abs;
}
并像这样使用
import Abs = require('abs');
const x: string = Abs('/foo');
(旁注:如果它包含在 tsconfig.json 中的 files
中,您甚至不需要 /// <reference
abs.d.ts)
如果你出于某种原因必须将它用作 export default
,你将无法单独使用打字稿 - 你需要将它编译为 es6 并使用另一个像 Babel 这样的转译器支持 export default
与节点的兼容性。您可以在 typescript issue and this blog post.