惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
Martin Fowler
Martin Fowler
P
Palo Alto Networks Blog
MongoDB | Blog
MongoDB | Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
博客园_首页
量子位
小众软件
小众软件
F
Full Disclosure
Vercel News
Vercel News
爱范儿
爱范儿
Engineering at Meta
Engineering at Meta
F
Fortinet All Blogs
博客园 - 聂微东
V
V2EX
Blog — PlanetScale
Blog — PlanetScale
罗磊的独立博客
WordPress大学
WordPress大学
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tor Project blog
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence
L
Lohrmann on Cybersecurity
H
Hacker News: Front Page
Spread Privacy
Spread Privacy
AI
AI
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CERT Recently Published Vulnerability Notes
D
Docker
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Recorded Future
Recorded Future
L
LINUX DO - 热门话题
Microsoft Azure Blog
Microsoft Azure Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Latest news
Latest news
W
WeLiveSecurity
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 司徒正美
博客园 - 叶小钗
T
Threat Research - Cisco Blogs
P
Privacy International News Feed
O
OpenAI News
Help Net Security
Help Net Security
aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
博客园 - Franky

木匣子

以 Maildir 方式备份邮件 后疫情之中国行 我的 Covid 经历 创建自签名 SSL 证书 写在 2021 年末 在 macOS 上使用 eGPU 的体验 动森二维码生成器:服装类(后篇) 动森二维码生成器:服装类(前篇) 动森二维码生成器 for Aseprite 动森图鉴+开发笔记 给 Apollo-Link 打补丁 「攻略」JetBrains Quest S1E3 「攻略」JetBrains Quest S1E2 「攻略」JetBrains Quest S1E1 助你同时维护多个项目的终端神器:Tmux 中文博客的字体选型 使用 Webpack Loader 加载 Icon Font 映射 写在 2019 年末 Edge 浏览器无法访问 VirtualBox 内的网站
给 Apollo-Link 打补丁 II
Lingjia · 2020-08-31 · via 木匣子

继上回给 Apollo Link 打补丁过去了几个月,本想翻看一下之前的那个 Pull Request 是否已经被 Merge,结果没想到原来的 Apollo Link 库已经被弃用了。新版的 Apollo Link 被重构后集成到了 @apollo/client 包中。不过并没有修复前面 PR 提到的问题。更糟糕的是之前使用的打补丁的方式无法起作用了。新的 selectHttpOptionsAndBody() 函数被专门放置到一个独立的 module 文件中。并且在提供的 cjs bundle 里,它直接被 createHttpLink 函数引用。所以之前的替换方法没办法在函数被引用前进行「狸猫换太子」。

那么是否有其它成本比较低的方式进行补救?于是我简单的搜索了一下 Webpack 的官方文档,很快找到了一个叫 NormalModuleReplacementPlugin 的内置插件。使用它可以非常方便地替换指定的模块文件。

new webpack.NormalModuleReplacementPlugin(
  resourceRegExp,
  newResource
);

于是我们将 @apollo/client 包中的 selectHttpOptionsAndBody.js 复制一份,并作以下修改:

  1. 在头部导入 stripIgnoredCharacters ;
  2. 在生成 body.query 的地方使用 stripIgnoredCharacters 压缩 graphql 查询;

Diff 结果如下:

3d2
< import { stripIgnoredCharacters } from "graphql";
38c37
<         body.query = stripIgnoredCharacters(print(query));
---
>         body.query = print(query);

将修改后的文件放到 /path/to/project/patch/selectHttpOptionsAndBody.js 然后在 Webpack 配置中增加一个插件:

plugins: {[
    ..., 
    new webpack.NormalModuleReplacementPlugin(
      /\/node_modules\/@apollo\/client\/link\/http\/selectHttpOptionsAndBody\.js/,
      path.resolve(process.cwd(), './patch/selectHttpOptionsAndBody.js'),
    ),
]},

重新运行 Webpack 构建,但发现并未能如愿将补丁打上。检查 Sourcemap 发现 Webpack 引入的是 @apollo/client 打包好的 commonjs 模块(*.cjs.js)而非实际的源码。

经过一番排查,发现 @apollo/client/link/httppackage.json 描述如下:

{
  "name": "@apollo/client/link/http",
  "main": "http.cjs.js",
  "module": "index.js",
  "types": "index.d.ts"
}

可见当前 Webpack 使用的是 main 字段的入口,而非 module 字段的入口。根据 Webpack 的 resolve 配置说明,我们可以使用 #resolvemainfields 来修改入口顺序。于是在 Webpack 配置中找到 mainFields 并作如下调整:

resolve: {
    mainFields: ['module', 'browser', 'main', 'jsnext:main'],
    ...,
}

调整的依据:

  1. 优先使用 es module,虽然会稍微增加一些构建时间,但可以利用 tree-shaking 减小包的体积;
  2. 对于不支持 es module 的库,尝试使用 browser 或 main 入口,即预编译的浏览器包或者 commonjs 的入口;

再次构建,检查 Sourcemap 后发现 selectHttpOptionsAndBody.js 已经变成我们打了补丁的版本了。

最后为了保证依赖的一致性,将 @apollo/client 的版本锁定。下次升级时需要检查补丁是否需要修订。