如何将typescript声明与puppetier exposeFunction和webpack一起使用



我正在为一个项目组合使用puppeteer和webpack。我将我的文件编译成一个捆绑包,然后在puppeteer上使用addScriptTag方法,将该文件添加到浏览器中。此外,我正在使用exposeFunction功能,这样我就可以从浏览器向nodejs发送/接收数据,更具体地说,这样我可以进行一些数据库调用。我的困境是typescript无法识别这些函数,因为它们从未在我的bundle中实际声明过,而是在nodejs端声明过,就像这样:

await page.exposeFunction("getPlayerFromDB", async (options) => {
// Some database call
return DB.players.get(options);
});

然后在我的文件中,我这样引用它:

const player = await getPlayerFromDB(options)

当然,这会引发一个打字错误:"找不到名称"getPlayerFromDB">

一开始我只是@ts忽略了,但由于我有更多的exposedFunction,而且它们的道具有点复杂,如果能从typescript的自动完成和类型检查中受益,那就太好了。因此,我发现了.d.ts文件和声明函数,但我遇到了更多的问题,我将在下面解释。

  1. .d.ts文件出现问题:找不到模块
export declare function getPlayerFromDB(
options: Partial<Pick<Player, "name" | "auth" | "ip">>
): Promise<DBUser> | null;

和导入类似:

import { getPlayerFromDB } from "../utils/puppeteer";

作为参考/utilts/poputeer是我正在进行所有exposeFunction函数声明的文件。

我想webpack找不到.d.ts文件?即使我进入编译器选项并添加.d.ts扩展名,或者引用以.d结尾的导入,它仍然找不到模块。

  1. 删除了.d.ts、扩展名并仅使用.ts

现在typescript正在编译,但我的代码不起作用,我收到错误:"puppeteer_1.getPlayerFromDB(不是函数";我猜这是因为webpack正在将其转换为模块,但puppeteer只期望函数名。

所以我的问题是我该如何解决这个问题?每次使用exposedFunctions时,我总是可以@ts忽略它,或者每次使用它时,我可以在文件中写入函数声明,但这并不实用。

我终于找到了解决这个问题的方法。并不是说这是最终的解决方案,但这让我可以:

  • 有一个文件,我在其中声明所有函数,重复声明
  • 保留模块化系统
  • 允许intellisense和typescript注释
  • 不忽略

从本质上讲,我创建了一个模块,该模块的函数将作为我的木偶师函数的包装器。我注意到,当函数名嵌套在另一个函数中时,webpack根本不会更改它们。然后我遇到了一个问题,我会有相同的函数名,因为我会有一个这样的函数:

// Puppeteer exposeFunction
declare function getUser(options): DBUser
export default module DB {
export async function getUser(options): DBUser {
return await getUser(options)
}
}

为了解决这个问题,我将所有的木偶师函数重命名为包含下划线,这样我就可以很容易地识别我所有的原生木偶师函数。像这样:

// Puppeteer exposeFunction
declare function _getUser(options): DBUser
export default module Database {
export async function getUser(options): DBUser {
return await _getUser(options)
}
}

现在,每当我创建exposeFunction时,我的过程就是

  1. 以下划线开头
  2. 在我的Database.ts文件中声明函数
  3. 在我的Database.ts文件中导出的模块中,导出一个exposeFunction名称减去下划线的函数
  4. 让那个函数返回我的exposeFunction

最新更新