nodejs

esModule -> JSON -> object

有时候需要获取某个文件的导出内容,再用于别处,也就是获取文件中 exports 的内容。由于需要自由传递并共享,所以需要转化为 json 格式。
又因为需要支持直接导出 esmodule,甚至是 typescript 的内容。所以需要使用 ts-node 来进行执行。
基于 base config 生成一份 检查宽松 的执行用 json,相当于关闭部分检查,只做执行操作(这份配置也可用于debug):

  1. // tsconfig.dev.json
  2. {
  3. "extends": "./tsconfig.json",
  4. "compilerOptions": {
  5. "target": "esnext",
  6. "module": "commonjs",
  7. "noUnusedLocals": false,
  8. "noUnusedParameters": false,
  9. "noImplicitAny": false,
  10. "noEmit": false
  11. },
  12. "exclude": ["node_modules"]
  13. }

然后 基于 devconfig,生成执行用 config,并添加 ts-node配置,跳过 type-check

  1. // tsconfig.exe.json
  2. {
  3. // This is an alias to @tsconfig/node12: https://github.com/tsconfig/bases
  4. "extends": "../tsconfig.dev.json",
  5. // Most ts-node options can be specified here using their programmatic names.
  6. "ts-node": {
  7. "transpileOnly": true
  8. },
  9. "compilerOptions": {
  10. "outDir": ".ts-node",
  11. "noEmit": false
  12. // typescript options here
  13. }
  14. }

具体的执行逻辑:

  1. import * as fs from 'fs';
  2. import * as path from 'path';
  3. import * as os from 'os';
  4. import * as process from 'child_process';
  5. // es module path
  6. const filePath = '/xxx/xx/xx.ts';
  7. // tsconfig.json path
  8. const configPath = path.resolve(__dirname, './tsconfig.exe.json');
  9. // eval string
  10. const execStr = `import r from '${filePath}'; console.log(JSON.stringify(r))`;
  11. function execToGetDefaultInfo() {
  12. const resStr = process.execSync(
  13. `ts-node --project ${configPath} --eval "${execStr}"`,
  14. {
  15. encoding: 'utf-8',
  16. },
  17. );
  18. return JSON.parse(resStr);
  19. }

通过 ts-node 来执行 eval 操作,eval 的字符串中,import 文件地址,再通过 console.log 打印出 JSON.stringify 后的 JSON 字符串,这样外部的 stdout 就能接收到,继而 execSync 返回,之后再 JSON.parse 就能还原 源文件的 export default 的内容,通过这样的方式,能成功获取 任意esmodule 的export object。当然只是可被 JSON 化的内容。
此方法仅用于 export 为 plain-object 的场景,且属性中的函数会被剔除:

  1. function a() {
  2. return 1;
  3. }
  4. const t = { a, d: { b: 1, c: '2' } };
  5. export default t;

image.png
若 export defult 为函数,json string 会解析为 undefined。
image.png
如需要可先转化 function ,先调用 toString
image.png