【问题标题】:How to use typescript declarations with puppeteer exposeFunction and webpack如何在 puppeteer exposeFunction 和 webpack 中使用 typescript 声明
【发布时间】:2022-02-09 01:20:27
【问题描述】:

我在一个项目中结合使用 puppeteer 和 webpack。我将我的文件编译成一个包,然后在 puppeteer 上使用 addScriptTag 方法,将该文件添加到浏览器中。另外,我使用了exposeFunction功能,所以我可以从浏览器向nodejs发送/接收数据,更具体地说,我可以进行一些数据库调用。 我的困境是打字稿无法识别这些函数,因为它们实际上从未在我的包中声明,而是在 nodejs 端,如下所示:

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

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

const player = await getPlayerFromDB(options)

当然,这会引发打字稿错误: "找不到名称 'getPlayerFromDB'"

一开始我只是@ts-ignore,但是因为我有更多这些暴露的函数,并且因为它们的道具有点复杂,所以从打字稿的自动完成和类型检查中受益会很好。因此,我发现了 .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/puppeteer 是我正在制作我所有的exposeFunction 函数声明的文件。

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

  1. 删除了 .d.ts 扩展名,只保留了 .ts

现在打字稿编译,但我的代码不起作用,我收到错误: “puppeteer_1.getPlayerFromDB) 不是函数” 我猜这是因为 webpack 正在将其转换为模块,但 puppeteer 只需要函数名称。

所以我的问题是如何解决这个问题?每次使用暴露函数之一时,我总是可以只使用@ts-ignore,或者每次使用时我都可以在文件中编写函数声明,但这并不实用。

【问题讨论】:

    标签: node.js typescript webpack puppeteer


    【解决方案1】:

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

    • 在一个文件中声明我的所有函数,重复声明
    • 保持模块化系统
    • 允许智能感知和打字稿注释
    • 没有 ts-忽略

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

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

    为了解决这个问题,我将所有 puppeteer 函数重命名为包含下划线,这样我就可以轻松识别所有原生 puppeteer 函数。像这样:

    // 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 2018-02-17
      • 2020-10-24
      • 2012-10-25
      • 2017-09-26
      • 2018-05-25
      • 2017-05-27
      相关资源
      最近更新 更多