Typescript 2.9 引入了一个新的 --resolveJsonModule
编译器选项,允许我们在 Typescript 中导入 JSON 模块。
假设我们有个用 Typescript 写的 Node 应用,需要导入下面的 JSON 文件:
{
"server": {
"nodePort": 8080
}
}
在 Node 中,我们可以像其他 CommonJS 模块一样通过 require
导入 JSON 文件:
const config = require("./config.json");
JSON 会自动反序列化为 Javascript 对象。这使得我们很容易访问该配置对象的属性:
"use strict";
const express = require("express");
const config = require("./config.json");
const app = express();
app.listen(config.server.nodePort, () => {
console.log(`Listening on port ${config.server.nodePort} ...`);
});
目前为止都很好。
现在我们要使用原生的 ECMAScript 模块而不是 CommonJS 模块。这意味着我们需要使用静态 import
声明来替代 require
调用:
// We no longer need the "use strict" directive since
// all ECMAScript modules implicitly use strict mode.
import * as express from "express";
import * as config from "./config.json";
const app = express();
app.listen(config.server.nodePort, () => {
console.log(`Listening on port ${config.server.nodePort} ...`);
});
我们会在第二行发现一个报错。Typescript 默认并不允许我们像这样直接导入 JSON 模块。这是 Typescript 团队有意做出的设计决定:导入一个大的 JSON 文件很可能会消耗大量的内存。所以需要显式地使用 --resolveJsonModule
编译选项来允许导入:
Having people to consciously opt into this would imply the user understands the cost.
让我们打开 tsconfig.json 文件,然后开启 resolveJsonModule
选项:
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"strict": true,
"moduleResolution": "node",
"resolveJsonModule": true
}
}
开启 resolveJsonModule
选项后,在我们的 Typescript 文件中不再报错。甚至我们可以得到类型检查和自动补全功能。
如果我们编译上面的 Typescript 代码,我可以得到以下的 Javascript 输出:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express = require("express");
const config = require("./config.json");
const app = express();
app.listen(config.server.nodePort, () => {
console.log(`Listening on port ${config.server.nodePort} ...`);
});
注意,输出和我们之前的 require
版本非常相似:
"use strict";
const express = require("express");
const config = require("./config.json");
const app = express();
app.listen(config.server.nodePort, () => {
console.log(`Listening on port ${config.server.nodePort} ...`);
});
好了,这就是如何在 Typescript 中导入 JSON 模块,只需要一个编译选项就能搞定。