<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Playwright | 锤子前端</title><description>Now vibe coding, so learning hammer FE ?</description><link>https://channel.meo-ai.com</link><item><title>《Playwright Fixtures 的&quot;魔法&quot;实现原理》</title><link>https://channel.meo-ai.com/posts/662</link><guid isPermaLink="true">https://channel.meo-ai.com/posts/662</guid><pubDate>Fri, 12 Jun 2026 09:14:37 GMT</pubDate><content:encoded>&lt;span class=&quot;post-title-source&quot;&gt;《&lt;/span&gt;&lt;mark class=&quot;highlight&quot;&gt;&lt;span class=&quot;post-title-source&quot;&gt;Playwright&lt;/span&gt;&lt;/mark&gt;&lt;span class=&quot;post-title-source&quot;&gt; Fixtures 的&quot;魔法&quot;实现原理》&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;标签：&lt;a href=&quot;/search/result?q=%23%E6%B5%8B%E8%AF%95&quot; title=&quot;#测试&quot;&gt;#测试&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23Playwright&quot; title=&quot;#Playwright&quot;&gt;#Playwright&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23JavaScript&quot; title=&quot;#JavaScript&quot;&gt;#JavaScript&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23API%E8%AE%BE%E8%AE%A1&quot; title=&quot;#API设计&quot;&gt;#API设计&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90&quot; title=&quot;#源码分析&quot;&gt;#源码分析&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;总结：&lt;br /&gt;作者深入剖析 &lt;mark class=&quot;highlight&quot;&gt;Playwright&lt;/mark&gt; 的 Fixtures API 如何通过 &lt;code&gt;Function.prototype.toString()&lt;/code&gt; 在测试运行前&quot;偷看&quot;函数参数，实现按需懒加载。文章揭示了这一巧妙但略带&quot;魔法&quot;的设计：&lt;mark class=&quot;highlight&quot;&gt;Playwright&lt;/mark&gt; 强制要求测试函数使用对象解构语法（如 `async ({ page }) =&amp;gt;`），然后通过正则解析源码字符串提取 fixture 名称，从而只初始化测试真正需要的依赖。作者还验证了该方案对不同函数类型、压缩工具（Terser/esbuild）的兼容性，并坦诚讨论了其&quot;神奇感&quot;与潜在局限性。&lt;br /&gt;&lt;br /&gt;文章要点：&lt;br /&gt;1. &lt;b&gt;懒加载是核心卖点**：&lt;/b&gt;&lt;mark class=&quot;highlight&quot;&gt;&lt;b&gt;Playwright&lt;/b&gt;&lt;/mark&gt;&lt;b&gt; 的 fixtures 按需初始化，不用就不创建，能节省测试执行时间；但传统 Proxy/getter 方案会导致异步 fixture 需要 `await`，破坏 API 体验&lt;br /&gt;2. &lt;/b&gt;&quot;偷看&quot;函数参数是关键**：&lt;mark class=&quot;highlight&quot;&gt;Playwright&lt;/mark&gt; 在不调用测试函数的情况下，就能知道它需要哪些 fixture，这解决了&quot;鸡生蛋&quot;难题——要知道用哪些 fixture 才能准备它们，但准备前又不能运行测试&lt;br /&gt;3. **`Function.prototype.toString()&lt;code&gt; 是秘密武器**：&lt;mark class=&quot;highlight&quot;&gt;Playwright&lt;/mark&gt; 把测试函数转成字符串，用正则提取解构参数，因此强制要求 `async ({ page }) =&amp;gt;&lt;/code&gt; 这种写法，否则直接抛错&quot;First argument must use the object destructuring pattern&quot;&lt;br /&gt;4. **解析逻辑相当 robust**：源码展示了 &lt;code&gt;innerFixtureParameterNames&lt;/code&gt; 的实现，能正确处理普通函数、async 函数、生成器函数、箭头函数等多种声明方式，还能处理带默认值的复杂解构&lt;br /&gt;5. **压缩工具不会破坏它**：实测 Terser 和 esbuild 的 minify 只会把参数名缩短（如 &lt;code&gt;foo&lt;/code&gt; → `o`），不会改解构语法，所以 &lt;mark class=&quot;highlight&quot;&gt;Playwright&lt;/mark&gt; 的正则解析依然能工作&lt;br /&gt;6. **魔法有代价**：函数组合（如 `noThrow(fn)&lt;code&gt; 包装后传入）会失效，因为 `toString()&lt;/code&gt; 拿到的是包装函数的源码而非原始函数；这种&quot;黑魔法&quot;虽然 DX 很好，但违反了&quot;最小惊讶原则&quot;&lt;br /&gt;7. **作者态度很诚实**：认可 &lt;mark class=&quot;highlight&quot;&gt;Playwright&lt;/mark&gt; 团队的选择非常适合测试框架场景，但坦言这种魔法比个人期望的多了一点，想不出其他库有同样充分的理由采用此方案&lt;br /&gt;&lt;br /&gt;URL：&lt;br /&gt;&lt;a href=&quot;https://ivakin.dev/blog/how-playwright-fixtures-work&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; title=&quot;https://ivakin.dev/blog/how-playwright-fixtures-work&quot;&gt;https://ivakin.dev/blog/how-playwright-fixtures-work&lt;/a&gt;&lt;a class=&quot;tgme_widget_message_link_preview&quot; href=&quot;https://ivakin.dev/blog/how-playwright-fixtures-work&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; title=&quot;Exploring the API design behind Playwright fixtures, and how a simple test API hides a surprisingly magical implementation.&quot;&gt;
  
  &lt;div class=&quot;link_preview_site_name accent_color&quot;&gt;ivakin.dev&lt;/div&gt;
  
  &lt;div class=&quot;link_preview_title&quot;&gt;Uncovering the Magic Behind &lt;mark class=&quot;highlight&quot;&gt;Playwright&lt;/mark&gt;&apos;s Fixtures API&lt;/div&gt;
  &lt;div class=&quot;link_preview_description&quot;&gt;Exploring the API design behind &lt;mark class=&quot;highlight&quot;&gt;Playwright&lt;/mark&gt; fixtures, and how a simple test API hides a surprisingly magical implementation.&lt;/div&gt;
&lt;/a&gt;</content:encoded></item><item><title>《Obscura：专为AI代理和爬虫打造的轻量级无头浏览器》</title><link>https://channel.meo-ai.com/posts/625</link><guid isPermaLink="true">https://channel.meo-ai.com/posts/625</guid><pubDate>Thu, 07 May 2026 02:07:37 GMT</pubDate><content:encoded>&lt;span class=&quot;post-title-source&quot;&gt;《Obscura：专为AI代理和爬虫打造的轻量级无头浏览器》&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;标签：&lt;a href=&quot;/search/result?q=%23%E5%90%8E%E7%AB%AF&quot; title=&quot;#后端&quot;&gt;#后端&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23Rust&quot; title=&quot;#Rust&quot;&gt;#Rust&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23HeadlessBrowser&quot; title=&quot;#HeadlessBrowser&quot;&gt;#HeadlessBrowser&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23WebScraping&quot; title=&quot;#WebScraping&quot;&gt;#WebScraping&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23AI_Agent&quot; title=&quot;#AI_Agent&quot;&gt;#AI_Agent&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23Chrome_DevTools_Protocol&quot; title=&quot;#Chrome_DevTools_Protocol&quot;&gt;#Chrome_DevTools_Protocol&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23Puppeteer&quot; title=&quot;#Puppeteer&quot;&gt;#Puppeteer&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23Playwright&quot; title=&quot;#Playwright&quot;&gt;#Playwright&lt;/a&gt; &lt;a href=&quot;/search/result?q=%23Anti_Detection&quot; title=&quot;#Anti_Detection&quot;&gt;#Anti_Detection&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;总结：&lt;br /&gt;Obscura是一款基于Rust编写的开源无头浏览器引擎，专为大规模网页抓取和AI自动化场景设计。它通过内置V8引擎运行真实JavaScript，完整支持Chrome DevTools Protocol，可直接替代Puppeteer和Playwright依赖的Headless Chrome，在内存占用（30MB vs 200MB+）、启动速度和反检测能力上具有显著优势。&lt;br /&gt;&lt;br /&gt;文章要点：&lt;br /&gt;- **极致轻量，资源友好**：相比Headless Chrome动辄200MB+的内存占用和300MB+的体积，Obscura仅需30MB内存和70MB二进制文件，启动几乎瞬时完成，页面加载速度提升约6倍&lt;br /&gt;- **零依赖，开箱即用**：无需安装Chrome或Node.js，单个二进制文件即可运行，支持Linux、macOS（Intel/Apple Silicon）和Windows平台&lt;br /&gt;- **无缝兼容现有生态**：完整实现Chrome DevTools Protocol，可作为Puppeteer和Playwright的底层浏览器直接连接使用，现有爬虫脚本迁移成本低&lt;br /&gt;- **内置隐身模式**：自带反指纹追踪（随机化GPU、屏幕、Canvas等参数）和3520个域名级别的追踪器拦截，无需额外配置即可绕过常见反爬机制&lt;br /&gt;- **并行爬取能力**：提供`obscura scrape`命令支持多URL并发抓取，配合`--concurrency`参数可灵活控制worker数量，适合批量数据采集场景&lt;br /&gt;- **开源承诺与商业化路径**：核心引擎采用Apache 2.0协议且承诺永不功能阉割，同时正在开发托管版Obscura Cloud提供代理和基础设施服务&lt;br /&gt;&lt;br /&gt;文章URL：&lt;br /&gt;&lt;a href=&quot;https://github.com/h4ckf0r0day/obscura&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; title=&quot;https://github.com/h4ckf0r0day/obscura&quot;&gt;https://github.com/h4ckf0r0day/obscura&lt;/a&gt;&lt;a class=&quot;tgme_widget_message_link_preview&quot; href=&quot;https://github.com/h4ckf0r0day/obscura&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; title=&quot;The headless browser for AI agents and web scraping - h4ckf0r0day/obscura&quot;&gt;
  
  &lt;div class=&quot;link_preview_site_name accent_color&quot;&gt;GitHub&lt;/div&gt;
  &lt;img class=&quot;link_preview_image&quot; alt=&quot;GitHub - h4ckf0r0day/obscura: The headless browser for AI agents and web scraping&quot; src=&quot;/static/https://cdn4.telesco.pe/file/gChSsl6aMr4ytvpAYe2sqt4326N2b2LchfrOxhI-lQn4e2QmfwcwYB8w99V7JTZJuiTDtJFoZzH41lvUZSsjFss5icuIDdnpi98TWsu_P0rR0KpKh9f6w4_BEMqpNknE-qhcB73aRW4wYxYYTBAehJ_2umG_p3BN-NlywNU9GkH2DlTD98kfRItAavVgFYRYe5F16FNZrpPgE4XC4KOoEylumyNW-BVjM_f7bxJq0_Q2FOHF1vR_N9yNMoZP5YuNyhxvsk_6orbVKo4UYZUsjwebaOcWFERVhJYVH5hih9bwOy35thfkI7MVnWQaS5w91P2llAdftVa_6AeovKUGfA.jpg&quot; width=&quot;1200&quot; height=&quot;630&quot; loading=&quot;eager&quot; /&gt;
  &lt;div class=&quot;link_preview_title&quot;&gt;GitHub - h4ckf0r0day/obscura: The headless browser for AI agents and web scraping&lt;/div&gt;
  &lt;div class=&quot;link_preview_description&quot;&gt;The headless browser for AI agents and web scraping - h4ckf0r0day/obscura&lt;/div&gt;
&lt;/a&gt;</content:encoded></item></channel></rss>