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

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

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

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 编译。

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

明显不是我想要的答案。

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

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

跟着链接跳过去

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

再跳

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

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

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

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

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

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

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

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

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

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

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

其实到这里问题已经解决了,但是我手贱,改了默认参数,想看看生成结果,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 直接运行

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

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

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

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

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

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

调整下参数

require('ts-node').register({
  transpileOnly: false,
  emit: true,
  compilerHost: true,
  cwd: __dirname
})

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

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

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

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

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

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

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

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

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

最终代码

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

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

原文链接:https://juejin.cn/post/7248995705292111929 作者:若邪

(1)
上一篇 2023年6月27日 上午10:22
下一篇 2023年6月27日 上午10:32

相关推荐

发表回复

登录后才能评论