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 pathconst filePath = '/xxx/xx/xx.ts';// tsconfig.json pathconst configPath = path.resolve(__dirname, './tsconfig.exe.json');// eval stringconst 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
