如何在 js 文件中直接调用 ts

背景是这样的,如下图,右边是 vscode 插件打开的一个 webview 界面,已经实现了在页面选择了一个方法,填入参数后,可以加载左边的 materials/blocks/表单/script/index.js 代码并执行里面对应的方法,返回执行结果。

image.png

materials/blocks/表单/script/index.js 内容如下:

module.exports = {
  beforeCompile: context => {
    context.outputChannel.appendLine('compile 表单 start')
  },
  afterCompile: context => {
    context.outputChannel.appendLine('compile 表单 end')
  },
  IntFromOcrText: context => {
    context.outputChannel.appendLine(Object.keys(context))
    context.outputChannel.appendLine(JSON.stringify(context.model))
    context.outputChannel.appendLine(context.params)
    return { ...context.model, name: '测试一下' }
  }
}

ts 写多了,写 js 真的效率低下。就想着能不能把方法里的逻辑单独放到 ts 文件里,这样还能给 context 写上类型声明。

直接问 ChatGPT 怎么在 js 文件直接调用 ts,它告诉我要先用 tsc 编译。

image.png

明显不是我想要的答案。

还好我知识储备丰富?,想到了这个库 TypeStrong/ts-node: TypeScript execution and REPL for node.js (github.com)。认真看了一遍文档,发现都是命令行的用法,我之前也只是在命令行里面用过。拿着 require 关键字去搜(在 js 里调用肯定是用 require),终于发现有用的信息。

image.png

跟着链接跳过去

image.png

再跳

image.png

image.png

就这,怎么用嘛,换个姿势问 ChatGPT

image.png

被它坑过一次,给我一个完全不存在的调用方法,不太相信它,让它给我相关的文章

image.png

image.png

只能去翻翻 issues,还真找到了

image.png

realappie/tsnode-example: This is repository is an example of how to use ts-node programmatically (github.com) 弄到本地成功运行,看起来之前 ChatGPT 没骗我。

image.png

其实到这里问题已经解决了,但是我手贱,改了默认参数,想看看生成结果,index.js 代码如下

require('ts-node').register({


  transpileOnly: false,


  emit: true,

  compilerHost: true
})
const path = require('path')
const handle = require('./handle.ts')
console.log(handle.getTitle('lowcode'))
module.exports = {
  beforeCompile: context => {
    context.outputChannel.appendLine('compile 表单 start')
  },
  afterCompile: context => {
    context.outputChannel.appendLine('compile 表单 end')
  },
  IntFromOcrText: context => {
    context.outputChannel.appendLine(Object.keys(context))
    context.outputChannel.appendLine(JSON.stringify(context.model))
    context.outputChannel.appendLine(context.params)
    context.outputChannel.appendLine(handle.getTitle('lowcode'))
    return { ...context.model, name: '测试一下' }
  }
}

先用 node.js 直接运行

image.png

image.png

还生成了编译后文件,没问题,插件里调用看看

image.png

Error: EPERM: operation not permitted, mkdir ‘H:/Microsoft VS Code/.ts-node’,mac 上也是这个错。那就是 ts-node 的锅了,又去翻 issues,搜到了有个参数cwd 貌似有用

image.png

调整下参数

require('ts-node').register({


  transpileOnly: false,


  emit: true,

  compilerHost: true,
  cwd: __dirname
})

还是一样的报错,然后全部恢复默认参数,依旧报错。

经过漫长的网上冲浪找答案,最终关了 vscode 重新打开居然就好了。

image.png

image.png

然后又发现改了 ts 文件,执行的并不是最新的代码,要重新打开 vscode 才行

image.png

这个问题我熟啊,插件里动态加载 index.js 文件的时候就遇到过,是 node.js 缓存的机制,加一行代码就解决了

delete require.cache[require.resolve(path.join(__dirname, 'handle.ts'))]

image.png

最终代码

require('ts-node').register({


  transpileOnly: false,


  emit: false,
  compilerHost: false, // 和 emit 一起设置为 true,会在 .ts-node 文件夹输出编译后的代码
  cwd: __dirname // 要输出编译后代码必须配置,否则会报错 EROFS: read-only file system, mkdir '/.ts-node'。不输出也要配置不然会出现各种奇奇怪怪的报错
})

const path = require('path')
// 清除缓存,保证每次修改代码后实时生效
delete require.cache[require.resolve(path.join(__dirname, 'handle.ts'))]
const title = require('./handle.ts')
module.exports = {
  beforeCompile: context => {
    context.outputChannel.appendLine('compile 表单 start')
  },
  afterCompile: context => {
    context.outputChannel.appendLine('compile 表单 end')
  },
  IntFromOcrText: context => {
    context.outputChannel.appendLine(Object.keys(context))
    context.outputChannel.appendLine(JSON.stringify(context.model))
    context.outputChannel.appendLine(context.params)
    context.outputChannel.appendLine(title.getTitle('lowcode'))
    return { ...context.model, name: '测试一下' }
  }
}

如果你看到了这里,你可以直接问 ChatGPT

  • 使用 ts-node 在 js 文件中直接调用 ts
  • 使用 babel 在 js 文件中直接调用 ts
  • 使用 swc 在 js 文件中直接调用 ts
  • 使用 esbuild 在 js 文件中直接调用 ts

tempimage1687799160074.gif

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYh3t21W' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片