<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Arrange]]></title><description><![CDATA[Arrange Myself after reveive the idea of accept boring time.]]></description><link>https://www.songlairui.cn/</link><generator>RSS for Node</generator><lastBuildDate>Mon, 27 May 2019 15:26:39 GMT</lastBuildDate><item><title><![CDATA[What's Code First]]></title><description><![CDATA[一个月前第一次看到   这个关键字. 因为我一直在抄写的 nestjs 文档例子中突然多出来了这么个东西. 我偶尔看到 prisma.io 这个服务商的网站有个界面挺漂亮的博客, 里面出现了 code first 的描述. 在我习惯的网站 zhihu juejin…]]></description><link>https://www.songlairui.cn//20190527-what-is-code-first/</link><guid isPermaLink="false">https://www.songlairui.cn//20190527-what-is-code-first/</guid><pubDate>Mon, 27 May 2019 22:51:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;一个月前第一次看到 &lt;code class=&quot;language-text&quot;&gt;code first&lt;/code&gt; 这个关键字. 因为我一直在抄写的 nestjs 文档例子中突然多出来了这么个东西. 我偶尔看到 prisma.io 这个服务商的网站有个界面挺漂亮的博客, 里面出现了 code first 的描述.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;在我习惯的网站 zhihu juejin 中, 搜索了下 &lt;code class=&quot;language-text&quot;&gt;code first&lt;/code&gt;, 要么 4 年前的回答, 要么没有.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;或者试一下 quora 中搜索 &lt;sup id=&quot;fnref-5&quot;&gt;&lt;a href=&quot;#fn-5&quot; class=&quot;footnote-ref&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;起点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;nestjs 文档 多出来了 code first 部分
[Nestjs:doc Graphql#code-first][^1]&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Primsa Blog 三连发&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;[The Problems of “Schema-First” GraphQL Server Development][^2]&lt;/li&gt;
&lt;li&gt;[Introducing GraphQL Nexus: Code-First GraphQL Server Development][^3]&lt;/li&gt;
&lt;li&gt;[Using GraphQL Nexus with a Database][^4]&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;起手&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;先动手实践一下再翻译吧&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所用到的核心工具 npm 包: &lt;code class=&quot;language-text&quot;&gt;GraphQL Nexus&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;type-graphql&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;相关参考:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;nestjs 文档 &lt;sup id=&quot;fnref-1&quot;&gt;&lt;a href=&quot;#fn-1&quot; class=&quot;footnote-ref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;阿里南京文章: &lt;a href=&quot;https://zhuanlan.zhihu.com/p/56516614&quot;&gt;TypeScript + GraphQL = TypeGraphQL&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;footnotes&quot;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.nestjs.com/graphql/quick-start#code-first&quot;&gt;https://docs.nestjs.com/graphql/quick-start#code-first&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-1&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.prisma.io/blog/the-problems-of-schema-first-graphql-development-x1mn4cb0tyl3&quot;&gt;https://www.prisma.io/blog/the-problems-of-schema-first-graphql-development-x1mn4cb0tyl3&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-2&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-3&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.prisma.io/blog/introducing-graphql-nexus-code-first-graphql-server-development-ll6s1yy5cxl5&quot;&gt;https://www.prisma.io/blog/introducing-graphql-nexus-code-first-graphql-server-development-ll6s1yy5cxl5&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-3&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-4&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.prisma.io/blog/using-graphql-nexus-with-a-database-pmyl3660ncst&quot;&gt;https://www.prisma.io/blog/using-graphql-nexus-with-a-database-pmyl3660ncst&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-4&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-5&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.quora.com/search?q=code+first&quot;&gt;https://www.quora.com/search?q=code+first&lt;/a&gt;&lt;/p&gt;
&lt;a href=&quot;#fnref-5&quot; class=&quot;footnote-backref&quot;&gt;↩&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content:encoded></item><item><title><![CDATA[基本操作之 mutation 之后更新 Apollo Client 缓存]]></title><description><![CDATA[3 个多月之前的原文:  How to update the Apollo Client’s cache after a mutation 自问自疑: 怎么分页? 变量标示页面参数. 怎么处理分页缓存? 全部重置?! 期望: 了解新的分页场景处理方式. 简要译文: The…]]></description><link>https://www.songlairui.cn//20190507-apollo-client/T-update-apollo-client-cache/</link><guid isPermaLink="false">https://www.songlairui.cn//20190507-apollo-client/T-update-apollo-client-cache/</guid><pubDate>Tue, 07 May 2019 22:21:00 GMT</pubDate><content:encoded>&lt;p&gt;3 个多月之前的原文: &lt;a href=&quot;https://medium.freecodecamp.org/how-to-update-the-apollo-clients-cache-after-a-mutation-79a0df79b840&quot;&gt;How to update the Apollo Client’s cache after a mutation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;自问自疑: 怎么分页? 变量标示页面参数. 怎么处理分页缓存? 全部重置?!&lt;br&gt;
期望: 了解新的分页场景处理方式.&lt;/p&gt;
&lt;p&gt;简要译文:&lt;/p&gt;
&lt;h2&gt;The Apollo Client and its cache&lt;/h2&gt;
&lt;p&gt;Apollo Client 能对接各种 GraphQL server 取数据, 体积小, 有很多 awesome feature, 如客户端的自动缓存数据.&lt;/p&gt;
&lt;p&gt;Apollo Client 为你自动审查 &lt;code class=&quot;language-text&quot;&gt;query&lt;/code&gt;s, &lt;code class=&quot;language-text&quot;&gt;mutation&lt;/code&gt;s 的数据传递, 缓存最新的数据, 保证本地缓存最新.&lt;/p&gt;
&lt;h2&gt;A Simple update&lt;/h2&gt;
&lt;p&gt;例子, 查询所有文章&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;graphql&quot;&gt;&lt;pre class=&quot;language-graphql&quot;&gt;&lt;code class=&quot;language-graphql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;query&lt;/span&gt; articles &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  articles &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    id
    title
    published
    author &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      name
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;得到返回数据:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    articles&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;xxx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;TTT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        published&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        author&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;yo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;然后,发起一个 mutation 更改标题&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;grahpql&quot;&gt;&lt;pre class=&quot;language-grahpql&quot;&gt;&lt;code class=&quot;language-grahpql&quot;&gt;// UPDATE_ARTICLE.gql
mutation updateArticle($id: ID!, $title: String) {
    updateArticle(id: $id, title: $title) {
        id
        title
        published
        author {
            name
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$apollo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mutate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    mutation&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;UPDATE_ARTICLE&lt;/span&gt;
    variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;xxx&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;a new title&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;得到结果:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;articles&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;xxx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    title&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a new title&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    published&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    author&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John Doe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;mutation 成功之后, 缓存会自动更新,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;因为:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;响应数据包含了 article id&lt;/li&gt;
&lt;li&gt;响应数据包含了 title&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;保持 mutation result 中有所有的用于更新缓存的必要字段, 就能自动更新缓存.&lt;br&gt;
在最佳实践中, 使用 fragment 来在相关的 query、mutation 的进行定义, 正是利用了这个特性.&lt;/p&gt;
&lt;p&gt;但, 在上例中, 更新 author name 并不能达到同样的效果. 因为 author name 没有平级的 id.&lt;br&gt;
令自动 cache 特性生效, 更改 fragment 为&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;graphql&quot;&gt;&lt;pre class=&quot;language-graphql&quot;&gt;&lt;code class=&quot;language-graphql&quot;&gt;id
title
published
author &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    id
    name
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Extended use cases&lt;/h2&gt;
&lt;p&gt;上面这是个理想化的场景(剧本中的场景), 实际场景远不够, 确实有很多场景,自动 cache 不能覆盖到,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;文章创建&lt;/li&gt;
&lt;li&gt;文章删除&lt;/li&gt;
&lt;li&gt;按条件过滤的文章列表&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;等更多.&lt;/p&gt;
&lt;p&gt;任何需要更新 cache 的场景, 都依赖当前的 cache.&lt;br&gt;
所以有两种的方式更新缓存:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mutation 之后刷新浏览器&lt;/li&gt;
&lt;li&gt;使用 update 方法直接操作 local cache&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;默认采取缓存优先策略, Apollo 推荐使用 update 方式.&lt;/p&gt;
&lt;h2&gt;Use of the update function&lt;/h2&gt;
&lt;p&gt;update 方法能任意操作 cache, 想怎么改怎么改, 改坏了没办法, 改动的逻辑有复杂度.&lt;/p&gt;
&lt;p&gt;(PS: 的确有复杂度. 查询第 5 页,突然发起了个更新第一页某条数据的 mutation 怎么破. 不依靠自动更新缓存,apollo client 设计的操作只能在手动找到缓存的操作基础上,抽取公共操作,并不能消除操作距离. 或者有绝妙的组织方式 )&lt;/p&gt;
&lt;p&gt;这一招很有诱惑——关闭 apollo client 默认开启的缓存, 但这绕过问题, 没正面刚, 不爽.&lt;/p&gt;
&lt;p&gt;一起来认真对待下这个普遍存在每个人都会面对的的挑战吧&lt;/p&gt;
&lt;h1&gt;Use always a try/catch block&lt;/h1&gt;
&lt;p&gt;所有可见例子,包括 Apollo 文档, 都长得像这样:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`{ todos { ... } }`&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;graphql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
    mutation ($text: String!) {
        createTodo(text: $text) { ... }
    }
`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      update&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; createTodo &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; query &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;todos&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;createTodo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;MyComponent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这看起来很棒, 但还没取数据的时候会怎样, 缓存还没如预期的已存在? &lt;code class=&quot;language-text&quot;&gt;proxy.readQuery&lt;/code&gt; 会抛错,让应用挂掉.&lt;/p&gt;
&lt;p&gt;保证理想中的代码安全执行,加个 try/catch :&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;update&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;proxy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; createTodo &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;不然, 就保证查询必然存在.&lt;/p&gt;
&lt;p&gt;这里的话,最好不要作任何假设,就像丹总(Dan Abramov)博客里写的:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;We can’t predict the exact user interactions and their order. At any point in time, our app may be in one of a mind-boggling number of possible states. We do our best to make the result predictable and limited by our design. We don’t want to look at a bug screenshot and wonder “how did that happen.

我们无法预言精准的用户交互动作及交互顺序. 任何时候,我们的应用都可能在一个让我们完全蒙圈的状态. 我们尽最大努力做到结果可预测,设计引用限制可能的结果. 我们不想看到bug截图,并好奇“为什么这样”.

(PS:这段说的应该是排bug时认为我的应用绝对不可能这样的那种难以置信感)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;记心里, &lt;code class=&quot;language-text&quot;&gt;proxy.readQuery&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;proxy.writeQuery&lt;/code&gt; 都可能抛错.&lt;br&gt;
比如, 从 cache 中读一个 query 不抛错, 而写 cache 时可能因为少了一个字段抛错了. 经常漏了 __typename 抛错.&lt;/p&gt;
&lt;h2&gt;Always define the variables used in the query&lt;/h2&gt;
&lt;p&gt;设想现在需要个 mutation 创建一个被标记为已发布的 article.&lt;/p&gt;
&lt;p&gt;通常, 基础例子有一个单 query 索取所有 article, 然后过滤出来已发布的.(比如, articles.filter(article =&gt; article.published))&lt;/p&gt;
&lt;p&gt;简化下需求, 先假定我们有个 query 只查询已发布的 articles.&lt;/p&gt;
&lt;p&gt;这个点上, mutation 添加新文章后, 我们需要用 &lt;code class=&quot;language-text&quot;&gt;published: true&lt;/code&gt; 读写 cache, 来匹配之前的查询:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;update&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; createPublishedArticles &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            published&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;articles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;createPublishedArticles&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; published&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;就酱, 这样的场景还可控, 因为我们只有一个 Boolean 变量. 一旦有更复杂的用例, 包括多个查询和变量, 就棘手了.&lt;/p&gt;
&lt;p&gt;( 以上, 也是我已经体验过的东西, 希望下边能学到新东西)&lt;/p&gt;
&lt;h2&gt;Increasing complexity&lt;/h2&gt;
&lt;p&gt;目前为止,覆盖了基本场景. 开发任何应用缓存管理很快就越来越复杂.&lt;/p&gt;
&lt;p&gt;的确, 实际写应用时, 用 apollo client 更新本地缓存几何倍变复杂, 包括多查询或涉及 apollo 内部更新不及时场景时:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对列表进行添加/删除&lt;/li&gt;
&lt;li&gt;列表中的一条数据移动到另一个列表&lt;/li&gt;
&lt;li&gt;更新列表筛选条件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;( ~~ 分页的缓存就是更改筛选条件这个场景 )&lt;/p&gt;
&lt;h2&gt;Updating more than one query after a mutation&lt;/h2&gt;
&lt;p&gt;一般, 发起一个 mutation 之后需要更新的会是不只一条 query. 比如, 回想下我们在 dashboard 中索取了所有文章, 已发布的和未发布的在两个列表中.&lt;/p&gt;
&lt;p&gt;Apollo client 不只把每个 query 写到 cache 中,查询变量不同,每个存一份 cache.比如:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;graphql&quot;&gt;&lt;pre class=&quot;language-graphql&quot;&gt;&lt;code class=&quot;language-graphql&quot;&gt;// &lt;span class=&quot;token keyword&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;query&lt;/span&gt; articles &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    articles &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        id
        title
        published
        author &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            name
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

// &lt;span class=&quot;token keyword&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;query&lt;/span&gt; articles&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; JSON&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    articles&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        id
        title
        published
        author &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            name
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

/* 缓存里将存俩&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
articles&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;where&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;published&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sort&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;asc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

应用变量时&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;variables&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;published&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;asc&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
*/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;预期的 query 在缓存中可能这么有两份. 当我们想查未发布 article 列表时,需要用变量额外应用 query 2, &lt;code class=&quot;language-text&quot;&gt;where: {published: false, sort: &amp;#39;asc&amp;#39;}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这么做就三个缓存项了:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;articles
articles({&amp;quot;where&amp;quot;:{&amp;quot;published&amp;quot;:true,&amp;quot;sort&amp;quot;:&amp;quot;asc&amp;quot;}})
articles({&amp;quot;where&amp;quot;:{&amp;quot;published&amp;quot;:false,&amp;quot;sort&amp;quot;:&amp;quot;asc&amp;quot;}})&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;为什么这么做,有必要吗?如果我们想添加一个新文章,然后想更新本地缓存,就需要读取不只一个 query,而且每个条件一遍,每套变量一遍.&lt;br&gt;
像这样:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;plain&quot;&gt;&lt;pre class=&quot;language-plain&quot;&gt;&lt;code class=&quot;language-plain&quot;&gt;// STEP #1
// update &amp;#39;articles&amp;#39;
try {
    const dataQuery = proxy.readQuery({
        query: getArticles
    })
    dataQuery.articles.push(newArticle);
    proxy.writeQuery({
        query: getArticles,
        data: dataQuery
    })
} catch() {}

// STEP #2
// articles({&amp;quot;where&amp;quot;:{&amp;quot;published&amp;quot;:true,&amp;quot;sort&amp;quot;:&amp;quot;asc}})
try {
    const dataQuery = proxy.readQuery({
        query: getArticles,
        variables: {
            where: {
                published: true,
                sort: &amp;quot;asc&amp;quot;
            }
        }
    })
    dataQuery.articles.push(newArticle);
    proxy.writeQuery({
        query: getArticles,
        variables: {
            where: {
                published: true,
                sort: &amp;quot;asc
            }
        },
        data: dataQuery
    })
} catch() {}

// STEP #3 抄不下去了我
// articles({&amp;quot;where&amp;quot;:{&amp;quot;published&amp;quot;:false,&amp;quot;sort&amp;quot;:&amp;quot;asc&amp;quot;}})
try {
    const dataQuery=proxy.readQuery){
        query: getArticles,
        variables: {
            where: {
                published: false,
                sort: &amp;quot;asc&amp;quot;
            }
        }
    }
    dataQuery.articles.push(newArticle)
    proxy.writeQuery({
        query: getArticles,
        variables: {
            where: {
                published: false,
                sort: &amp;quot;asc&amp;quot;
            }
        },
        data: dataQuery
    })
} catch(error) {}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;已经看到了,这样做给每个 query/variables 组合加模样差不多的代码, 很多.&lt;/p&gt;
&lt;h2&gt;Variables’ order and values&lt;/h2&gt;
&lt;p&gt;注意下每个变量的顺序很重要.&lt;/p&gt;
&lt;p&gt;这两个查询被认为是不同的,在 cache 中会分开存.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// calling a query&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;graphql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
    query ($width: Int!, $height: Int!) {
        dimensions(width: $width, height: $height) {
            ...
        }
        ...
    }
`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;MyComponent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Calling the same query above, but different order&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;graphql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
    query ($width: Int!, $height: Int!) {
        dimensions(width: $width, height: $height) {
            ...
        }
        ...
    }
`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;MyComponent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这将造成缓存里存两份:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dimensions({&amp;quot;width&amp;quot;:600,&amp;quot;height&amp;quot;:600})
dimensions({&amp;quot;height&amp;quot;:600,&amp;quot;width&amp;quot;:600})&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;重新调用同样的参数,将得到另外一条缓存&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dimensions({&amp;quot;width&amp;quot;:600,&amp;quot;height&amp;quot;:600})
dimensions({&amp;quot;height&amp;quot;:600,&amp;quot;width&amp;quot;:600})
dimensions({&amp;quot;height&amp;quot;:100,&amp;quot;width&amp;quot;:100})&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;要炸了,哈哈? 你看这么 naively 的就超出控制了&lt;/p&gt;
&lt;h2&gt;Edge cases&lt;/h2&gt;
&lt;p&gt;如果这还不够,再来点.
当你定义一个常规的带 variablse 的 query 时,
想一下下边场景:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;graphql&quot;&gt;&lt;pre class=&quot;language-graphql&quot;&gt;&lt;code class=&quot;language-graphql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;query&lt;/span&gt; articles&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$limit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Int&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  articles&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;limit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$limit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    _id
    title
    published
    flagged
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;很有可能这么用&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;graphql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
    &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ABOVE_QUERY&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  `&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        sort&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sort&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        limit&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;limit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;MyComponent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;但当另外一个根本没有 variables 的对象或者空 variables,比如 &lt;code class=&quot;language-text&quot;&gt;variables: {}&lt;/code&gt;传入时. 操作变量传入可能会这样:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;graphql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
    &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ABOVE_QUERY&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  `&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;varObj&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// props.varObj 可能为控对象&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;MyCompoennt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在缓存中这么存 &lt;code class=&quot;language-text&quot;&gt;articles({&amp;quot;sort&amp;quot;:null,&amp;quot;limit&amp;quot;:null})&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;当&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;export default graphql(gql`${ABOVE_QUERY}`)(MyComponent)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;缓存中存 &lt;code class=&quot;language-text&quot;&gt;articles({})&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;上述极端场景远不是想要的场景. 举这样的例子来深化缓存的存储规则.&lt;/p&gt;
&lt;h2&gt;Moving items between cached queries&lt;/h2&gt;
&lt;p&gt;也有这样的场景:我们想 unpublish 一篇 article, 即将数据从已发布查询的缓存中移到未发布中.&lt;/p&gt;
&lt;p&gt;一般操作,我们先保存已发布的列表,然后移除一条,最后把这一条添加到未发布中. 实现代码如下:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; elementToMoveId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;1&apos;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; elementToMove
&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dataQueryFrom &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;已发布 &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    elementToMove &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dataQueryFrom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;articles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; elementToMoveId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    dataQueryFrom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;articles &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dataQueryFrom&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;articles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; elementToMoveId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;覆写dataQueryFrom&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elementToMove&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dataQueryTo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;未发布&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        dataQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;articles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;elementToMove&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        proxy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;覆写dataQuery&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Apollo Cache Updater&lt;/h2&gt;
&lt;p&gt;看, 覆盖常规的场景需要这么复杂的操作.&lt;/p&gt;
&lt;p&gt;得写特别多代码, 而且很容易出错.&lt;/p&gt;
&lt;p&gt;针对这场景, 发布了包 Apollo Cache Updater, 零配置的. 帮我管理缓存时能神志清楚.&lt;/p&gt;
&lt;p&gt;通过 update 变量配置 mutation 结果的缓存行为.&lt;/p&gt;
&lt;p&gt;目标是覆盖上述所有场景.&lt;/p&gt;
&lt;p&gt;用不同的查询条件分页条件执行了多个 query 之后, 迭代传入 ROOT_QUERY 中的每个对象&lt;/p&gt;
&lt;h1&gt;Conclusions&lt;/h1&gt;
&lt;p&gt;任何语言中管理缓存都很麻烦. Apollo Client 给出很多优势, 任何场景都能手动操作. Apollo Cache Updater 缓和了下这个痛处. 期待官方给更加易用的方案.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;简直了, 把我知道的苦的场景描述了一遍, 我还是不知道怎么解决&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Apollo Client]]></title><description><![CDATA[试用了 nestjs prisma server + apollo client 的基本操作, 发现默认的 cache 阻碍了我刷新数据. 以及携带分页时, 手动更新 InMemory…]]></description><link>https://www.songlairui.cn//20190507-apollo-client/</link><guid isPermaLink="false">https://www.songlairui.cn//20190507-apollo-client/</guid><pubDate>Tue, 07 May 2019 22:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;试用了 nestjs prisma server + apollo client 的基本操作, 发现默认的 cache 阻碍了我刷新数据.&lt;br&gt;
以及携带分页时, 手动更新 InMemory 数据, 以我能想象到到思路难以忍受.&lt;br&gt;
想来标准到使用流程上定然有个优雅的方法, 一定有的.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Start: &lt;a href=&quot;https://www.apollographql.com/docs/react/advanced/caching&quot;&gt;Cache&lt;/a&gt;、 &lt;a href=&quot;https://www.apollographql.com/docs/react/features/pagination&quot;&gt;Pagination&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;刷新到的体验一: &lt;code class=&quot;language-text&quot;&gt;nodeConnections&lt;/code&gt;, pageInfo, edges 形式存储分页信息&lt;/p&gt;
&lt;p&gt;边阅读边点击链接:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;cache&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;浏览方式: 快速浏览
关键点:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;reset cache&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;cache persistence&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;pagination&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.freecodecamp.org/how-to-update-the-apollo-clients-cache-after-a-mutation-79a0df79b840&quot;&gt;article in blog&lt;/a&gt;, 翻译到: &lt;a href=&quot;/T-update-apollo-client-cache-6582944a9c262754c1b736b24b91a5e1.md&quot;&gt;更新 Apollo Client 缓存&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;针对文章中的各种缓存管理复杂场景, 使用 fetchMore 能解决问题&lt;/p&gt;
&lt;p&gt;使用 fetchMore, 按照定义的变量,将已有的缓存续起来.&lt;/p&gt;
&lt;p&gt;根据分页机制具体做法不同&lt;/p&gt;
&lt;h2&gt;Offset-based 分页机制&lt;/h2&gt;
&lt;p&gt;通过 offset、 limit 控制分页范围&lt;/p&gt;
&lt;p&gt;例子:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;FEED_QUERY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;`
  query Feed($type: FeedType!, $offset: Int, $limit: Int) {
    currentUser {
      login
    }
    feed(type: $type, offset: $offset, limit: $limit) {
      id
      # ...
    }
  }
`&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$apollo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    query&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;FEED_QUERY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$apollo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;queries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetchMore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    variables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        offset&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    updateQuery&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;prev&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fetchMoreResult &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;fetchMoreResult&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; prev&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; prev&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            feed&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;prev&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;fetchMoreResult&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;feed&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;列表中删除或者插入一个新的项时, 会造成已有分页俩表缺一条活着渲染两次.
用 cursor-base 模式能避免&lt;/p&gt;
&lt;h2&gt;Cursor-based 分页机制&lt;/h2&gt;
&lt;p&gt;就那样…&lt;/p&gt;
&lt;h2&gt;Relay-style cursor pagination&lt;/h2&gt;
&lt;p&gt;可以用到指令 @connection.&lt;/p&gt;
&lt;p&gt;指令是什么? 我在 graphql.cn 上没看到过 @connection 呀. 哦,有指令,应该是自定义的一个指令&lt;/p&gt;
&lt;h2&gt;next&lt;/h2&gt;
&lt;p&gt;阅读 Apollo-Vue 中 &lt;a href=&quot;https://vue-apollo.netlify.com/guide/apollo/pagination.html&quot;&gt;fetchMore 部分&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;解决了加载更多的场景, 然后跳转后两页时呢. 不考虑了&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Lary's NoteBook]]></title><description><![CDATA[Stash 完成了基本的查询和新增操作. 部署 Docker 方式 想到了持续化集成
涉及的即使,提交完代码之后,就提交完代码了 持续化部署, 又是啥?
代码提交之后,自动 build docker image? 拆分一下, 持续化集成工具 jenkins travis CI…]]></description><link>https://www.songlairui.cn//20190508-lary-note/</link><guid isPermaLink="false">https://www.songlairui.cn//20190508-lary-note/</guid><pubDate>Tue, 07 May 2019 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Stash&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;完成了基本的查询和新增操作.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;部署 Docker 方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;想到了持续化集成
涉及的即使,提交完代码之后,就提交完代码了&lt;/li&gt;
&lt;li&gt;持续化部署, 又是啥?
代码提交之后,自动 build docker image?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;拆分一下,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;提交代码到重新 build docker image 算是持续集成
image 更新一下,算是持续化部署&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;持续化集成工具&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;jenkins&lt;/li&gt;
&lt;li&gt;travis CI
添加 badge 的感觉真爽
终端真好&lt;/li&gt;
&lt;li&gt;netlify
终端真漂亮&lt;/li&gt;
&lt;li&gt;circleci
终端真好
构建真快&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[React + Apollo 2rd]]></title><description><![CDATA[prisma api 已备好 Step 1 参照之前的 hacker news 教程, 添加 graphql 相关文件 安装依赖 包裹  添加 login signup Resolver Step 2 使用 Antd…]]></description><link>https://www.songlairui.cn//20190330-start-prisma/3-front/</link><guid isPermaLink="false">https://www.songlairui.cn//20190330-start-prisma/3-front/</guid><pubDate>Sun, 31 Mar 2019 11:40:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;prisma api 已备好&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Step 1&lt;/h2&gt;
&lt;p&gt;参照之前的 hacker news 教程, 添加 graphql 相关文件&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装依赖&lt;/li&gt;
&lt;li&gt;包裹 &lt;App/&gt;&lt;/li&gt;
&lt;li&gt;添加 login signup Resolver&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Step 2&lt;/h2&gt;
&lt;p&gt;使用 Antd 创建登陆页面&lt;/p&gt;
&lt;p&gt;页面组件导出变更形式,添加:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;withApollo&lt;/li&gt;
&lt;li&gt;withRouter&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Step 3 Upgrade Auth&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;nestjs 自带有 auth 实践, 将之前教程中简单的校验更改为 nestjs 的实践&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;常规 auth 技巧:&lt;/p&gt;
&lt;p&gt;Auth Service 中有一个 validateUser 用于在 guard 中检查用户是否合法&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;nest g guard guard/jwt-auth
nest g module auth
nest g &lt;span class=&quot;token function&quot;&gt;service&lt;/span&gt;
nest g guard auth/jwt-auth&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[How to Read Document]]></title><description><![CDATA[每次使用 React 都想自己写一下自己的总结. 然而基本上自己的总结都无法超过官方文档. 该怎么办? 访问的便利性 克隆静态站点, 部署到自己可以快速访问的位置. 可行性不高, 现有网站开启 PWA…]]></description><link>https://www.songlairui.cn//20190331-how-to-read-document/</link><guid isPermaLink="false">https://www.songlairui.cn//20190331-how-to-read-document/</guid><pubDate>Sun, 31 Mar 2019 11:34:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;每次使用 React 都想自己写一下自己的总结. 然而基本上自己的总结都无法超过官方文档.&lt;br&gt;
该怎么办?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;访问的便利性&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;克隆静态站点, 部署到自己可以快速访问的位置.&lt;/p&gt;
&lt;p&gt;可行性不高, 现有网站开启 PWA 的情况下, 设备上的缓存已经足够快.&lt;/p&gt;
&lt;p&gt;所以, 快速了解到官方文档, 是主要的起点&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;如何记录个人心得&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;个人新的应与原文档结合来看. 然后就有了这两个场景:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;刻舟求剑, 通过 chrome 插件方式, 为页面添加自定义标注脚注&lt;/li&gt;
&lt;li&gt;个人脚注管理站点,能够总揽自己的脚注. 可以在其他位置, 引用自己的脚注&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Nestjs + Prisma]]></title><description><![CDATA[使用 nestjs 如何获取 prisma generate 的功能呢 ? 创建 nestjs serv 项目  内容: 生成文件 添加 graphql Module  中添加  中定义要生成的 schema 文件路径 添加 prisma module & resolver…]]></description><link>https://www.songlairui.cn//20190330-start-prisma/2-nestjs-prisma/</link><guid isPermaLink="false">https://www.songlairui.cn//20190330-start-prisma/2-nestjs-prisma/</guid><pubDate>Sun, 31 Mar 2019 00:12:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;使用 nestjs 如何获取 prisma generate 的功能呢 ?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;创建 nestjs serv 项目&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;nest new server

yarn add apollo-server-express @nestjs/graphql prisma-binding

&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; .graphqlconfig.yml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;.graphqlconfig.yml&lt;/code&gt; 内容:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;projects&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;schemaPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; src/prisma/prisma&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;types.graphql
    &lt;span class=&quot;token key atrule&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;endpoints&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//localhost&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6644&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;codegen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;generator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; prisma&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;binding
          &lt;span class=&quot;token key atrule&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; typescript
          &lt;span class=&quot;token key atrule&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token key atrule&quot;&gt;binding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; src/prisma/prisma.binding.ts&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;生成文件&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;graphql get-schema --project database
graphql codegen --project database&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;添加 graphql Module&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;app.module.ts&lt;/code&gt; 中添加&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;GraphQLModule&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forRootAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  useClass&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; GraphqlOptions&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;graphql.options.ts&lt;/code&gt; 中定义要生成的 schema 文件路径&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  typePaths&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./**/*.graphql&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  definitions&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src/graphql.schema.d.ts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    outputAs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;class&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;添加 prisma module &amp;#x26; resolver&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;nest g module prisma
nest g service prisma

nest g module posts
nest g resolver posts

nest g module users
nest g resolver users&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;prisma.module 添加 exports [service]&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;prisma service&lt;/code&gt; 应 extends &lt;code class=&quot;language-text&quot;&gt;prisma.binding#Prisma&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Start to use Prisma]]></title><description><![CDATA[Booklets Prisma Doc Basic 基本使用 1. cli prepare 2. docker-compose.yml 其中自定义了一些配置 使用了 postgres 自定义了端口 设置了数据库名 设置了   network 启动: 3. init prisma…]]></description><link>https://www.songlairui.cn//20190330-start-prisma/</link><guid isPermaLink="false">https://www.songlairui.cn//20190330-start-prisma/</guid><pubDate>Sat, 30 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Booklets&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.prisma.io/docs/get-started/01-setting-up-prisma-new-database-TYPESCRIPT-t002/&quot;&gt;Prisma Doc&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Basic&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;基本使用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1. cli prepare&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; i prisma -g&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2. docker-compose.yml&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;3.1&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;prisma&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; prismagraphql/prisma&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.29&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;6644:6644&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;PRISMA_CONFIG&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
        port: 6644
        databases:
          default:
            connector: postgres
            host: db
            port: 5432
            user: postgres
            password: ******
            database: ary-serv
            migrations: true&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; multi&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;compose&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中自定义了一些配置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用了 postgres&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自定义了端口&lt;/li&gt;
&lt;li&gt;设置了数据库名&lt;/li&gt;
&lt;li&gt;设置了 &lt;code class=&quot;language-text&quot;&gt;extenal&lt;/code&gt; network&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;启动:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;docker-compose up -d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;3. init prisma&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;prisma init --endpoint http://localhost:6644&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;将生成 &lt;code class=&quot;language-text&quot;&gt;datamodel.prisma&lt;/code&gt;、 &lt;code class=&quot;language-text&quot;&gt;prisma.yml&lt;/code&gt; 文件&lt;/p&gt;
&lt;h3&gt;4. deploy&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;prisma deploy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;将连接数据库,创建数据表.&lt;/p&gt;
&lt;h3&gt;5. view&lt;/h3&gt;
&lt;p&gt;可访问 Graphql IDE (&lt;code class=&quot;language-text&quot;&gt;http://localhost:6644&lt;/code&gt;)&lt;br&gt;
和 Prisma Admin (&lt;code class=&quot;language-text&quot;&gt;http://localhost:6644/_admin&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;prisma 提供的 admin 面板,能够更方便的显示、添加、修改数据&lt;/p&gt;
&lt;h2&gt;Datamodel&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Prisma 数据模型机制&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1. 更改 &lt;code class=&quot;language-text&quot;&gt;datamode.prisma&lt;/code&gt; 文件&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;graphql&quot;&gt;&lt;pre class=&quot;language-graphql&quot;&gt;&lt;code class=&quot;language-graphql&quot;&gt;type User &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ID&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token directive function&quot;&gt;@unique&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String &lt;span class=&quot;token directive function&quot;&gt;@unique&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Post&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

type Post &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; ID&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token directive function&quot;&gt;@unique&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;published&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Boolean&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token directive function&quot;&gt;@default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; User
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;通过 posts, author 将两表进行关联.&lt;/p&gt;
&lt;h3&gt;2. 更新表结构&lt;/h3&gt;
&lt;p&gt;重新执行 &lt;code class=&quot;language-text&quot;&gt;prisma deploy&lt;/code&gt;, 即可&lt;/p&gt;
&lt;h3&gt;3. 生成客户端代码, 使用 prisma api&lt;/h3&gt;
&lt;p&gt;执行 &lt;code class=&quot;language-text&quot;&gt;prisma generate&lt;/code&gt;, 将自动生成客户端代码&lt;/p&gt;
&lt;h3&gt;4. 体验 datamodel&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;对比自己写的 resolver, 体验 prisma 中不同场景处理, 其处理方式有很多可学习之处. (elegance)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;4.1 关联创建时, 如何处理?&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;gql &quot;&gt;&lt;pre class=&quot;language-gql &quot;&gt;&lt;code class=&quot;language-gql &quot;&gt;mutation {
  createPost(
    data: {
      title: &amp;quot;风乎舞雩&amp;quot;
      published: true
      author: { connect: { email: &amp;quot;songlairui@qq.com&amp;quot; } }
    }
  ) {
    id
    title
    published
    author {
      name
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中 author 字段为 Post 表关联的 User 表数据字段, 此处有 &lt;code class=&quot;language-text&quot;&gt;create&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;connect&lt;/code&gt; 两个传入属性, 对应,关联创建数据和关联已有数据的场景&lt;/p&gt;
&lt;h4&gt;4.2 更改数据&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;gql&quot;&gt;&lt;pre class=&quot;language-gql&quot;&gt;&lt;code class=&quot;language-gql&quot;&gt;mutation modify {
  updateUser(
    data: { email: &amp;quot;songlairui@qq.com&amp;quot; }
    where: { id: &amp;quot;cjtstpc2h000m0760km52wmyv&amp;quot; }
  ) {
    id
    email
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中, payload 中定义 data where 两个属性, 分离数据与条件&lt;/p&gt;
&lt;h4&gt;4.3 支持嵌套数据?&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;gql&quot;&gt;&lt;pre class=&quot;language-gql&quot;&gt;&lt;code class=&quot;language-gql&quot;&gt;{
  users {
    name
    posts {
      author {
        name
        posts {
          title
        }
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;默认支持, 观察创建的数据表, 多出了多个下划线开头的表, 记录了关联关系&lt;/p&gt;
&lt;h3&gt;思考&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;:::
prisma 自带了一个 prisma generate
那么,在 nestjs 中,这个generate 代码怎么使用呢?
:::&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[start react-apollo tutorial]]></title><description><![CDATA[Steps 安装依赖 配置后端,  Prisma docker 文档 配置本地 postgres docker 配置 prisma docker 运行  出现交互提示 如何自己做一个命令行交互提示?
得到使用的库之后, 如何使用得到的配置? … fail to record my…]]></description><link>https://www.songlairui.cn//20190324-how-graphql/</link><guid isPermaLink="false">https://www.songlairui.cn//20190324-how-graphql/</guid><pubDate>Sun, 24 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;plain&quot;&gt;&lt;pre class=&quot;language-plain&quot;&gt;&lt;code class=&quot;language-plain&quot;&gt;关联:

TODO: MicroSoft TODO Item
StickyNote: MicroSoft StickyNote Item

教程网址: https://www.howtographql.com/react-apollo/1-getting-started/&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;安装依赖&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置后端, &lt;a href=&quot;https://www.prisma.io/docs/1.13/tutorials/deploy-prisma-servers/local-(docker)-meemaesh3k&quot;&gt;Prisma docker 文档&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置本地 postgres docker&lt;/li&gt;
&lt;li&gt;配置 prisma docker&lt;/li&gt;
&lt;li&gt;运行 &lt;code class=&quot;language-text&quot;&gt;yarn prisma deplpy&lt;/code&gt;&lt;br&gt;
出现交互提示&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如何自己做一个命令行交互提示?
得到使用的库之后, 如何使用得到的配置?&lt;/p&gt;
&lt;p&gt;… fail to record my acivity&lt;/p&gt;
&lt;h2&gt;Finished the tutorial&lt;/h2&gt;
&lt;p&gt;I learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Query 查询&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;List 数据列表&lt;/li&gt;
&lt;li&gt;Search 根据条件查询数据&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mutation 变更&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create 创建数据&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Authentic 认证&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;React&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Routing 前端路由&lt;/li&gt;
&lt;li&gt;withApollo 包裹组件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pagination 分页&lt;/li&gt;
&lt;li&gt;apollo-client cache 客户端缓存&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Docker&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;prisma deploy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;pgsql&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;psql&lt;/li&gt;
&lt;li&gt;schema: default$default&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;graphql-server&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;resolver&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;我的提交记录:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;16aef65 (HEAD -&gt; master) update local cache update&lt;/li&gt;
&lt;li&gt;45024ff 添加分页&lt;/li&gt;
&lt;li&gt;9ccedcf ignore webpack global version&lt;/li&gt;
&lt;li&gt;f77ba36 添加 subscription&lt;/li&gt;
&lt;li&gt;9d22def 添加 filter&lt;/li&gt;
&lt;li&gt;cd8347c 添加 Votes Mutation 以及本地 updateStore&lt;/li&gt;
&lt;li&gt;80d9680 add apollo-client auth header&lt;/li&gt;
&lt;li&gt;3e94ad0 add login &amp;#x26; signup&lt;/li&gt;
&lt;li&gt;117fdeb add login dom&lt;/li&gt;
&lt;li&gt;1e7055b link after action&lt;/li&gt;
&lt;li&gt;a3d405e add route&lt;/li&gt;
&lt;li&gt;c912baf react query links, create links&lt;/li&gt;
&lt;li&gt;8423958 Initial commit from Create React App&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;个人感想&lt;/h2&gt;
&lt;p&gt;此前看 graphql 官方教程,看完了一遍,缺少实践,难以融会. 跟着教程走完一遍, 会用新轮子了.&lt;/p&gt;
&lt;p&gt;坚持使用, 会自然而然得到更多领悟.&lt;/p&gt;
&lt;h2&gt;再一次回顾&lt;/h2&gt;
&lt;h3&gt;安装依赖&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;based on create-react-app&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;yarn add apollo-boost \
         apollo-cache-inmemory \
         apollo-link-ws \
         apollo-link-context \
         graphql \
         graphql-tag \
         react-apollo \
         react-router \
         react-router-dom \
         subscriptions-transport-ws \
         antd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;包裹 &lt;code class=&quot;language-text&quot;&gt;&amp;lt;App/&amp;gt;&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;ReactDOM&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;BrowserRouter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ApolloProvider&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;App&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ApolloProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;BrowserRouter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;root&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中 client 的 link 参数,传入了 api 来源&lt;/p&gt;
&lt;p&gt;split[‘wsLink’, [‘authLink’, ‘httpLink’]]&lt;/p&gt;</content:encoded></item><item><title><![CDATA[To Use Lerna]]></title><description><![CDATA[npm set registry  https://registry-npm.mypaas.com.cn npm adduser —registry  https://registry-npm.mypaas.com.cn target 1: side depends]]></description><link>https://www.songlairui.cn//20190320-lerna/</link><guid isPermaLink="false">https://www.songlairui.cn//20190320-lerna/</guid><pubDate>Wed, 20 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;npm set registry &lt;a href=&quot;https://registry-npm.mypaas.com.cn&quot;&gt;https://registry-npm.mypaas.com.cn&lt;/a&gt;&lt;br&gt;
npm adduser —registry &lt;a href=&quot;https://registry-npm.mypaas.com.cn&quot;&gt;https://registry-npm.mypaas.com.cn&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;target 1: side depends&lt;/h2&gt;</content:encoded></item><item><title><![CDATA[Resolve with alias within symlink]]></title><description><![CDATA[Excertps  and   has the same content as below, but located in different symlinked dir. Then, import the two module in one file as below, the…]]></description><link>https://www.songlairui.cn//20190319-webpack-alias-resolve/</link><guid isPermaLink="false">https://www.songlairui.cn//20190319-webpack-alias-resolve/</guid><pubDate>Tue, 19 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;!-- TODO: init the basic webpack alias and wordspace with multi dirs --&gt;
&lt;h2&gt;Excertps&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;moduleA.js&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;moduleB.js&lt;/code&gt; has the same content as below, but located in different symlinked dir.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Vue &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;vue&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; Vue&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, import the two module in one file as below, the dest module is &lt;code class=&quot;language-text&quot;&gt;&amp;#39;vue&amp;#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;assert&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; a &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;moduleA&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; b &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;moduleB&quot;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The result is false&lt;/p&gt;
&lt;p&gt;This is euqal to&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; a &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/home/me/projectA/node_modules/vue&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; b &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/home/me/projectB/node_modules/vue&quot;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;the two vue not equal&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Use Gatsby]]></title><description><![CDATA[trying to be ac with Graphql and React targets react eco pkgs following Interesting Nodes zhihu hashnode commands deployment what strategy…]]></description><link>https://www.songlairui.cn//20190316-start-gatsby/</link><guid isPermaLink="false">https://www.songlairui.cn//20190316-start-gatsby/</guid><pubDate>Sat, 16 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;trying to be ac with Graphql and React&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;targets&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;react eco pkgs&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;following&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://hashnode.com/onboarding/follow-nodes&quot;&gt;Interesting Nodes&lt;/a&gt;&lt;br&gt;
zhihu&lt;br&gt;
hashnode&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;commands&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;gatsby new blog
ossutilmac64 &lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; -r oss://xxx
certbot renew&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;deployment&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;what strategy to choose for site deployment&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;static files with index.html on &lt;strong&gt;ali-oss&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;apis &lt;strong&gt;no&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;deploy flow: laptop&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since the domain was redirected to oss, no api address would be provided by the main domain, then all the api will use in the main page should have a cros header.&lt;/p&gt;
&lt;p&gt;the flow was stucked several seconds, for the ossutilmac64 executing.&lt;/p&gt;
&lt;p&gt;But, this strategy would give me the most speed for visiting the site Content.&lt;/p&gt;
&lt;h2&gt;wanna to trace&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;a short video saw&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=v-01hEYF-RQ&quot;&gt;https://www.youtube.com/watch?v=v-01hEYF-RQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ka2AwSuOTpI&quot;&gt;https://www.youtube.com/watch?v=ka2AwSuOTpI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a open course saw&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://open.163.com//movie/2018/8/Q/R/MDPBV80UO_MDPBVMKQR.html&quot;&gt;https://open.163.com//movie/2018/8/Q/R/MDPBV80UO_MDPBVMKQR.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;a TED&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a good answer&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zhihu.com/question/314500394/answer/618136109&quot;&gt;https://www.zhihu.com/question/314500394/answer/618136109&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;my comments,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on &lt;a href=&quot;https://juejin.im&quot;&gt;juejin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;on &lt;a href=&quot;https://zhihu.com&quot;&gt;zhihu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;my game achievement&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mobile PUBG&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;configurable&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;with antd&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;custom style
&lt;a href=&quot;https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less&quot;&gt;All vars in default.less&lt;/a&gt;, &lt;a href=&quot;https://ant.design/docs/react/customize-theme&quot;&gt;theme customize&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;@line-height-base&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.75&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;@font-size-base&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;16&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;@font-family&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&apos;Merriweather&apos;,&apos;Georgia&apos;,serif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;primary-color&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#639&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;link-color&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;#537&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;border-radius-base&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2px&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;@text-color&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;rgba(0, 0, 0, .9)&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item></channel></rss>