You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Playwright浏览器上下文中导入本地模块?

解决Playwright page.evaluate中导入本地TypeScript模块的问题

这个场景我太熟悉了——在page.evaluate里直接导入本地TS文件肯定会报错,毕竟浏览器上下文和你的Node.js开发环境完全是两个独立的运行环境,浏览器根本不知道../src/Foo/Bar这个本地路径指向哪里。下面给你几个靠谱的解决办法:

方法一:把模块打包成浏览器可运行的脚本(最推荐)

这是最规范的做法,用前端打包工具(比如Vite、Webpack、esbuild)把../src/Foo/Bar.ts打包成一个IIFE或UMD格式的脚本。打包后的文件会把导出的内容挂载到window对象上,这样就能在浏览器上下文里直接访问了。

步骤大概是这样:

  1. 配置打包工具,把Bar.ts作为入口,输出一个浏览器友好的脚本(比如dist/bar.bundle.js)
  2. 在Playwright代码里先注入这个打包后的脚本:
await page.addScriptTag({ path: './dist/bar.bundle.js' });
  1. 然后在page.evaluate里直接使用导出的内容:
await page.evaluate(async () => {
  // 假设打包后namedExportExample挂载到了window上
  const result = window.namedExportExample.connectWebSocket();
  // 后续逻辑...
});

方法二:内联模块代码到evaluate上下文

如果你的模块代码量不大,不想额外配置打包工具,可以把模块代码直接读取并注入到浏览器里:

  1. 先在Node端读取Bar.ts的内容(记得先把TS转成JS,比如用tsc预编译,或者用esbuild实时转译)
  2. 把代码作为参数传给page.evaluate,然后用data: URL的方式导入:
const fs = require('fs');
const esbuild = require('esbuild');

// 读取并转译TS为JS
const barTsCode = fs.readFileSync('../src/Foo/Bar.ts', 'utf8');
const { code: barJsCode } = await esbuild.transform(barTsCode, {
  loader: 'ts',
  target: 'es2020'
});

await page.evaluate(async (jsCode) => {
  // 用data URL导入模块
  const { namedExportExample } = await import(`data:text/javascript,${encodeURIComponent(jsCode)}`);
  // 执行你的逻辑...
}, barJsCode);

这种方法适合快速测试,但代码量多的话会显得杂乱,不适合生产环境。

方法三:传递序列化后的函数(局限性大)

如果你的模块导出的函数不依赖浏览器API,可以在Node端先导入模块,再把函数序列化后传给page.evaluate。但注意:如果函数里用到了WebSocket这类浏览器专属API,Node端导入时会直接报错,所以这个方法只适用于纯逻辑函数。

// 先转译TS为JS,再导入
const { namedExportExample } = require('../src/Foo/Bar.js');

await page.evaluate(async (func) => {
  func();
}, namedExportExample);

总结一下,方法一是最稳定、可维护的方案,符合前端工程化的思路;方法二适合快速验证;方法三只能用于特殊场景。

内容的提问来源于stack exchange,提问作者Dois

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 18:33:15