nodejs
esModule -> JSON -> object
有时候需要获取某个文件的导出内容,再用于别处,也就是获取文件中 exports 的内容。由于需要自由传递并共享,所以需要转化为 json 格式。
又因为需要支持直接导出 esmodule,甚至是 typescript 的内容。所以需要使用 ts-node 来进行执行。
基于 base config 生成一份 检查宽松 的执行用 json,相当于关闭部分检查,只做执行操作(这份配置也可用于debug):
// tsconfig.dev.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitAny": false,
"noEmit": false
},
"exclude": ["node_modules"]
}
然后 基于 devconfig,生成执行用 config,并添加 ts-node配置,跳过 type-check
// tsconfig.exe.json
{
// This is an alias to @tsconfig/node12: https://github.com/tsconfig/bases
"extends": "../tsconfig.dev.json",
// Most ts-node options can be specified here using their programmatic names.
"ts-node": {
"transpileOnly": true
},
"compilerOptions": {
"outDir": ".ts-node",
"noEmit": false
// typescript options here
}
}
具体的执行逻辑:
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import * as process from 'child_process';
// es module path
const filePath = '/xxx/xx/xx.ts';
// tsconfig.json path
const configPath = path.resolve(__dirname, './tsconfig.exe.json');
// eval string
const execStr = `import r from '${filePath}'; console.log(JSON.stringify(r))`;
function execToGetDefaultInfo() {
const resStr = process.execSync(
`ts-node --project ${configPath} --eval "${execStr}"`,
{
encoding: 'utf-8',
},
);
return JSON.parse(resStr);
}
通过 ts-node 来执行 eval 操作,eval 的字符串中,import 文件地址,再通过 console.log 打印出 JSON.stringify 后的 JSON 字符串,这样外部的 stdout 就能接收到,继而 execSync 返回,之后再 JSON.parse 就能还原 源文件的 export default 的内容,通过这样的方式,能成功获取 任意esmodule 的export object。当然只是可被 JSON 化的内容。
此方法仅用于 export 为 plain-object 的场景,且属性中的函数会被剔除:
function a() {
return 1;
}
const t = { a, d: { b: 1, c: '2' } };
export default t;
若 export defult 为函数,json string 会解析为 undefined。
如需要可先转化 function ,先调用 toString