<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>夜里</title>
        <link>http://www.yanghao717.cn/en/blog</link>
        <description>夜里的小站 Blog</description>
        <lastBuildDate>Tue, 07 Mar 2023 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>© 2026 NightY持续更新, 微信:CodeY777  联系邮箱:2368009927@qq.com</copyright>
        <item>
            <title><![CDATA[Typescript 全栈最值得学习的技术栈 TRPC]]></title>
            <link>http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc</link>
            <guid>http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc</guid>
            <pubDate>Tue, 07 Mar 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[本文介绍了 tRPC 技术以及它与传统 RESTful API 的区别。同时 tRPC 可以帮助人们更快地开发全栈 TypeScript 应用程序，同时无需传统的 API 层，并保证应用程序在快速迭代时的稳定性。]]></description>
            <content:encoded><![CDATA[<p>如果你想成为一个 <strong>Typescript 全栈工程师</strong>，那么你可能需要关注一下 <a href="https://trpc.io/" target="_blank" rel="noopener noreferrer">tRPC</a> 框架。</p>
<p>本文总共会接触到以下主要技术栈。</p>
<ul>
<li><a href="https://nextjs.org/" target="_blank" rel="noopener noreferrer" title="Next.js">Next.js</a></li>
<li><a href="https://trpc.io/" target="_blank" rel="noopener noreferrer" title="TRPC">TRPC</a></li>
<li><a href="https://www.prisma.io/" target="_blank" rel="noopener noreferrer" title="Prisma">Prisma</a></li>
<li><span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/vriad/zod" target="_blank" rel="noopener noreferrer" title="Zod">Zod</a></span></li>
<li><a href="https://authjs.dev/" target="_blank" rel="noopener noreferrer" title="Auth.js">Auth.js</a></li>
</ul>
<p>不是介绍 tRPC 吗，怎么突然出现这么多技术栈。好吧，主要这些技术栈都与 typescript 相关，并且在 trpc 的示例应用中都或多或少使用到，因此也是有必要了解一下。</p>
<p>在线体验地址：<a href="https://trpc.night.cn/" target="_blank" rel="noopener noreferrer">TRPC demo</a></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="end-to-end-typesafe-apis端到端类型安全">End-to-end typesafe APIs(端到端类型安全)<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#end-to-end-typesafe-apis%E7%AB%AF%E5%88%B0%E7%AB%AF%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>在介绍相关技术前，不妨思考一个问题。</p>
<blockquote>
<p>当进行网络请求和 API 调用时，你是否知道本次请求的参数类型以及返回的响应数据类型？知道了请求的数据类型与响应的数据类型，会为得到的 json 数据定义 type/interface，使其有更好的类型提示？还是会在 any 类型下获取属性，但由于没有类型提示，导致写错个单词，最终提示 Cannot read properties of undefined (reading 'xxx')？</p>
</blockquote>
<p>对于大部分前端应用而言，类型往往常被忽略的，这就导致不知道这个请求的提交参数、响应结果有什么数据字段。举个 axios 发送 post 请求的例子</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20230308142331808.png" alt="image-20230308142331808" class="img_ev3q"></p>
<p>这是一个 post 请求用于实现登录的，但是这个响应数据 data 没有任何具体提示（这里的提示是 vscode 记录用户最近输入的提示），这时候如果一旦对象属性拼写错误，就会导致某个数据没拿到，从而诱发 bug。同理提交的请求体 body 不做约束，万一这个请求还有验证码 code 参数，但是我没写上，那请求就会失败，这是就需要通过调试输出，甚至需要抓包比对原始数据包，其过程可想而知。</p>
<p>最主要的是没有类型约束的情况下，非常容易出现访问某个对象属性不存在，js 开发者肯定经常遇到如下错误提示。</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Cannot read properties </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">of</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">undefined</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">reading </span><span class="token string" style="color:hsl(95, 38%, 62%)">'xxx'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>有太多时候就是因为没有类型，无形间诱发 bug，这也是很多做 api 接口都常常忽视的一点。</p>
<blockquote>
<p>因此我个人所认为的未来 Web 框架形态是要满足的前提就是前后端类型统一，即可以将后端的类型无缝的给前端使用，反之同理。而像 Next、Nuxt 这样的全栈框架便是趋势所向。</p>
</blockquote>
<p>当然 axios 是可以通过泛型的方式拿到 data 的数据类型提示，就如下图所示。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20230308142452678.png" alt="image-20230308142452678" class="img_ev3q"></p>
<p>但这样为了更好的类型提示，无形之间又增加了工作量，我需要定义每个接口的 Response 与 Body 类型，就极易造成开发疲惫，不愿维护代码。而本次所要介绍的技术栈 tRPC 就能够帮你省去重复的类型定义的一个 web 全栈框架。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="trpc"><span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/trpc/trpc" target="_blank" rel="noopener noreferrer">tRPC</a></span><a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#trpc" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>tRPC 是一个基于 TypeScript 的远程过程调用框架，旨在简化客户端与服务端之间的通信过程，并提供高效的类型安全。它允许您使用类似本地函数调用的方式来调用远程函数，同时自动处理序列化和反序列化、错误处理和通信协议等底层细节。</p>
<p>借官方 Feature</p>
<ul>
<li>Automatic type-safety（自动类型安全）</li>
<li>Snappy DX（敏捷高效的开发者体验）</li>
<li>Is framework agnostic （不依赖于特定框架）</li>
<li>Amazing autocompletion（出色的自动补全功能）</li>
<li>Light bundle size（轻量级打包大小）</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="什么时候该使用-trpc">什么时候该使用 tRPC<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E8%AF%A5%E4%BD%BF%E7%94%A8-trpc" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>这个问题非常好，因为我在了解到 tRPC，并参阅了一些基本示例与实践一段时间后发现 trpc 和 http 的应用场景可以说非常相似，完全可以使用 trpc 来替代 http，只不过写法上从 <strong>发送 http 请求 ⇒ 调用本地函数</strong>（这在后面会演示到）。</p>
<p>而 trpc 又以类型安全与高效著称，如果你的 Web 应用的程序是基于 typescript，并且需要有高效的性能，那么 tRPC 就是一个很好的选择。</p>
<p>tRPC 可以作为 REST/GraphQL 的替代品，如果前端与后端共享代码的 TypeScript monorepo，trpc 则可以无需任何类型转换，也不太会有心智负担。</p>
<p><strong>请记住，tRPC 只有当您在诸如 Next、Nuxt、SvelteKit、SolidStart 等全栈项目中使用 TypeScript 时，tRPC 才会发挥其优势。</strong></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="trpc-如何进行接口调用">tRPC 如何进行接口调用<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#trpc-%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E6%8E%A5%E5%8F%A3%E8%B0%83%E7%94%A8" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<video src="https://assets.trpc.io/www/v10/v10-dark-landscape.mp4" controls="" width="100%" height="auto"></video>
<p>一图胜千言，你可以点击 <a href="https://trpc.io/#try-it-out" target="_blank" rel="noopener noreferrer" title="这里">这里</a> 在线体验一下 tRPC，并且查看其目录结构，以及调用方式。下面我一步步讲解如何进行接口调用。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="定义服务端">定义服务端<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E5%AE%9A%E4%B9%89%E6%9C%8D%E5%8A%A1%E7%AB%AF" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>这里以 Next.js 的目录结构而定。创建 <code>server/trpc.ts</code>，如下代码。分别导出 router, middleware, procedure</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>server/trpc.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> initTRPC </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'@trpc/server'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> t </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> initTRPC</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">create</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> router </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> t</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">router</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> middleware </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> t</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">middleware</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> publicProcedure </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> t</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">procedure</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>创建项目(根)路由文件 <code>pages/api/trpc/[trpc].ts</code></p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>server/trpc.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">*</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">as</span><span class="token plain"> trpc </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'@trpc/server'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> publicProcedure</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> router </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'./trpc'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> appRouter </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">router</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  greeting</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> publicProcedure</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">query</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'hello tRPC!'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">AppRouter</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">typeof</span><span class="token plain"> appRouter</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>此时已经定义好了一个路由地址 <code>api/trpc/[trpc].ts</code>（这里 endpoint(端点)会在客户端中使用到），以及 <code>greeting</code> 函数，服务端的工作就暂且完毕。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="创建客户端">创建客户端<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E5%88%9B%E5%BB%BA%E5%AE%A2%E6%88%B7%E7%AB%AF" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>创建 <code>utils/trpc.ts</code> 文件，代码如下</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>utils/trpc.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> httpBatchLink </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'@trpc/client'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> createTRPCNext </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'@trpc/next'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> AppRouter </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'../pages/api/trpc/[trpc]'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">getBaseUrl</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">typeof</span><span class="token plain"> window </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'undefined'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// In the browser, we return a relative URL</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">''</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// When rendering on the server, we return an absolute URL</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// reference for vercel.com</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">process</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token constant" style="color:hsl(29, 54%, 61%)">VERCEL_URL</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">https://</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">${</span><span class="token template-string interpolation">process</span><span class="token template-string interpolation punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token template-string interpolation">env</span><span class="token template-string interpolation punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token template-string interpolation constant" style="color:hsl(29, 54%, 61%)">VERCEL_URL</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// assume localhost</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">http://localhost:</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">${</span><span class="token template-string interpolation">process</span><span class="token template-string interpolation punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token template-string interpolation">env</span><span class="token template-string interpolation punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token template-string interpolation constant" style="color:hsl(29, 54%, 61%)">PORT</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:hsl(207, 82%, 66%)">??</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation number" style="color:hsl(29, 54%, 61%)">3000</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> trpc </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:hsl(207, 82%, 66%)">createTRPCNext</span><span class="token generic-function generic class-name operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token generic-function generic class-name" style="color:hsl(29, 54%, 61%)">AppRouter</span><span class="token generic-function generic class-name operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">config</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      links</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token function" style="color:hsl(207, 82%, 66%)">httpBatchLink</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          url</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">getBaseUrl</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'/api/trpc'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>在 <code>_app.tsx</code> 包装一下</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>_app.tsx<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> AppType </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'next/app'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> trpc </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'../utils/trpc'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> MyApp</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">AppType</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> Component</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> pageProps </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain">Component </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token operator" style="color:hsl(207, 82%, 66%)">...</span><span class="token plain">pageProps</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> trpc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">withTRPC</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">MyApp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>有了这个对象后，我们就可以开始尽情调用服务端所定义好了函数了。</p>
<p>当你导入 trpc 并输入 <code>trpc.</code> 时，将会提示出服务端定义好的 <code>greeting</code> 函数，如下图所示。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_YDKc7TixQA.png" alt="" class="img_ev3q"></p>
<p>此时通过 <code>const result = trpc.greeting.useQuery()</code> 便可调用 <code>greeting</code> 函数，其中 <code>result.data</code> 便可拿到 <code>'hello tRPC!'</code> 信息。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="这个过程发生了什么">这个过程发生了什么？<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E8%BF%99%E4%B8%AA%E8%BF%87%E7%A8%8B%E5%8F%91%E7%94%9F%E4%BA%86%E4%BB%80%E4%B9%88" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<blockquote>
<p>文档: <a href="https://trpc.io/docs/useQuery" target="_blank" rel="noopener noreferrer" title="useQuery() | tRPC">useQuery() | tRPC</a></p>
</blockquote>
<p>不妨此时打开控制台面板，看看请求</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_WfW8ehqUKz.png" alt="" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_qicvoGjshx.png" alt="" class="img_ev3q"></p>
<p>不难看出，调用 greeting 函数本质是向 <code>/api/trpc/greeting</code> 发送了 http 请求，并且携带参数 batch 和 input，虽然我们暂时还没有传。默认 input 为 <!-- -->。</p>
<p>要支持传递参数，首先需要在服务端定义传递参数的类型（会有 Zod 对参数效验），这样客户端才有对应的类型提示。然后调用 greeting 函数时，通过通过函数参数的形式来传递请求参数。</p>
<p>举例说明，比如说我们将 appRouter 改写成这样，通过 input 参数指定了 <code>useQuery</code> 需要传递一个 <code>name</code> 为字符串且不为空的对象。</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> z </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'zod'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> appRouter </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">router</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  greeting</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> publicProcedure</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      z</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">object</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> z</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">nullish</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">query</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> input </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        text</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">hello </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">${</span><span class="token template-string interpolation">input</span><span class="token template-string interpolation operator" style="color:hsl(207, 82%, 66%)">?.</span><span class="token template-string interpolation">name </span><span class="token template-string interpolation operator" style="color:hsl(207, 82%, 66%)">??</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation string" style="color:hsl(95, 38%, 62%)">'world'</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>调用 <code>trpc.greeting.useQuery({ name: 'night' })</code> 发送的请求的 query 参数则变为</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/20230307214659.png" alt="" class="img_ev3q"></p>
<p>不仅于此，你如果同时调用了多次 greeting 函数，如</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">pages/index.tsx<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> result1 </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> trpc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">greeting</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">useQuery</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'kuizuo1'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> result2 </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> trpc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">greeting</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">useQuery</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'kuizuo2'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> result3 </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> trpc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">greeting</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">useQuery</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'kuizuo3'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>tRPC 会将这三次函数调用合并成一次 http 请求，并且得到的响应本文也是以多条数据的形式返回</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_ufrhaugaIj.png" alt="" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_cvlDJjhwPl.png" alt="" class="img_ev3q"></p>
<p>分别输出三者 result 也没有任何问题。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_hbL8So_RzB.png" alt="" class="img_ev3q"></p>
<p>这是 tRPC 的一个特性：<strong>请求批处理，将同时发出的请求（调用）可以自动组合成一个请求。</strong></p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="usemutation--trpc"><a href="https://trpc.io/docs/useMutation" target="_blank" rel="noopener noreferrer" title="useMutation() | tRPC">useMutation() | tRPC</a><a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#usemutation--trpc" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>tRPC 同样也支持 post 请求，例如</p>
<p>服务端代码</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>server/trpc.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> appRouter </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">router</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  createUser</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> publicProcedure</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">z</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">object</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> z</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">string</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">mutation</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> user</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> User </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">input</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">name</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> user</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>客户端代码</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>pages/index.tsx<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">IndexPage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> mutation </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> trpc</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">createUser</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">useMutation</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ERROR!</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// mutation.mutate({ name: 'night' });</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">handleCreate</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    mutation</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">mutate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'night'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain">div</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain">button onClick</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">handleCreate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> disabled</span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">mutation</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">isLoading</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        Create</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">button</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">mutation</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">error </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;&amp;</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain">p</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain">Something went wrong</span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">mutation</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">p</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">div</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="theme-admonition theme-admonition-danger admonition_xJq3 alert alert--danger"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"></path></svg></span>danger</div><div class="admonitionContent_BuS1"><p>这里需要注意 <code>mutate</code> 方法无法在外层直接调用，否则将会提示</p><div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Unhandled Runtime Error</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Error</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> Maximum update depth exceeded</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain"> This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain"> React limits the </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">number</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">of</span><span class="token plain"> nested updates to prevent infinite loops</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>主要防止这个组件被其他组件调用，此时自动调用 mutate 函数，导致不可控且循环调用的情况，因此需要通过一个事件（比如点击事件）来触发。</p></div></div>
<p>此时请求变为 post 请求，并且携带的参数也以 body 形式传递。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_-qEI8jR1uM.png" alt="" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_RTdWJn_55p.png" alt="" class="img_ev3q"></p>
<p>通过 useQuery 和 useMutation 就能够用 tRPC 实现最基本的 CRUD。此外还有 useInfiniteQuery 可以用作类似无限下拉查询，类似 <a href="https://swr.bootcss.com/examples/infinite-loading" target="_blank" rel="noopener noreferrer">SWR 无限加载</a>。useQueries 批量查询，使用 <a href="https://trpc.io/docs/subscriptions" target="_blank" rel="noopener noreferrer">Subscriptions</a> 进行订阅 WebSocket 等等。</p>
<p>tRPC 针对 react 项目的查询主要依赖于 <a href="https://tanstack.com/query/v4/docs/react/adapters/react-query" target="_blank" rel="noopener noreferrer" title="@tanstack/react-query">@tanstack/react-query</a>，你也可以到 <a href="https://trpc.io/docs/react-query" target="_blank" rel="noopener noreferrer" title="tRPC React Query documentation">tRPC React Query documentation</a> 查看相关 hook。</p>
<p>从上述例子中你就会发现，tRPC 将 http 请求给我们包装成了函数形式调用，即上文所说的，调用服务端接口的形式由 <strong>发送 http 请求 ⇒ 调用本地函数</strong>。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="不足">不足<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E4%B8%8D%E8%B6%B3" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>不过也并非没有缺点（个人认为）。</p>
<p>首先不如传统的 RESTFUL 来的直观，假设我现在在服务端定义了一个服务，那么我只能通过<code>@trpc/client</code> 创建客户端进行调用。虽然也能用 http 的形式，但调用的很不优雅。</p>
<p>在我印象中，RPC 框架通常是可以跨语言进行调用的，比如 gRPC 框架，然而<strong>tRPC 目前只能在 Typescript 项目中进行调用</strong>，我倒是希望能向 gRPC 那个方向发展，不过不同语言间的类型安全又是个大麻烦。</p>
<p>学习成本与项目成本偏高，tRPC 对整个全栈项目的技术要求比较高，并且限定于 typescript，如果你<del>想</del>将你的项目从传统的 Restful 迁移到 tRPC 上，无疑是个工程量大，且不讨好的事。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="创建工程">创建工程<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E5%88%9B%E5%BB%BA%E5%B7%A5%E7%A8%8B" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>这里选用 <a href="https://create.t3.gg/" target="_blank" rel="noopener noreferrer" title="Create T3 App">Create T3 App</a> 用于创建应用（也可以选择 <span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/trpc/examples-next-prisma-starter" target="_blank" rel="noopener noreferrer" title="trpc/examples-next-prisma-starter">trpc/examples-next-prisma-starter</a></span>），Create T3 App 集成了诸多有关 TypeScript full-stack 相关的技术栈，其中就包括了本文所要介绍的几个技术栈。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_8BUcBPK8In.png" alt="" class="img_ev3q"></p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">pnpm</span><span class="token plain"> create t3-app@latest</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>安装过程如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_ERGzEt2Tq8.png" alt="" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="prisma">prisma<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#prisma" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>此时安装完先别急着 pnpm run dev 启动项目，首先执行</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">npx prisma db push</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>运行结果如下</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Environment variables loaded from .env</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Prisma schema loaded from prisma schema.prisma</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Datasource </span><span class="token string" style="color:hsl(95, 38%, 62%)">"db"</span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">:</span><span class="token plain"> SQLite database </span><span class="token string" style="color:hsl(95, 38%, 62%)">"db.sqlite"</span><span class="token plain"> at </span><span class="token string" style="color:hsl(95, 38%, 62%)">"file:./db.sqlite"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">SQLite database db.sqlite created at file:./db.sqlite</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Your database is now </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">sync</span><span class="token plain"> with your Prisma schema. Done </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> 81ms</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>这会将数据库与 prisma 的 schema 同步，说人话就是将数据库的表与 <code>schema.prisma</code> 文件中的 model 对应。</p>
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed="true"><summary>schema.prisma</summary><div><div class="collapsibleContent_i85q"><div class="language-prisma codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">prisma/schema.prisma<span style="flex:1;text-align:right">prisma</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-prisma codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">generator client {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    provider = "prisma-client-js"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">}</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">datasource db {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    provider = "sqlite"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    url      = env("DATABASE_URL")</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">}</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">model Example {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    id        String   @id @default(cuid())</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    createdAt DateTime @default(now())</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    updatedAt DateTime @updatedAt</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">}</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">// Necessary for Next auth</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">model Account {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    id                String  @id @default(cuid())</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    userId            String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    type              String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    provider          String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    providerAccountId String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    refresh_token     String? // @db.Text</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    access_token      String? // @db.Text</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    expires_at        Int?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    token_type        String?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    scope             String?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    id_token          String? // @db.Text</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    session_state     String?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    user              User    @relation(fields: [userId], references: [id], onDelete: Cascade)</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    @@unique([provider, providerAccountId])</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">}</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">model Session {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    id           String   @id @default(cuid())</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    sessionToken String   @unique</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    userId       String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    expires      DateTime</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    user         User     @relation(fields: [userId], references: [id], onDelete: Cascade)</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">}</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">model User {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    id            String    @id @default(cuid())</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    name          String?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    email         String?   @unique</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    emailVerified DateTime?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    image         String?</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    accounts      Account[]</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    sessions      Session[]</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">}</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">model VerificationToken {</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    identifier String</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    token      String   @unique</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    expires    DateTime</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    @@unique([identifier, token])</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">}</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>create-t3-app 默认使用的 sqlite 数据库，优点就是你无需安装任何数据库的环境，将会在 prisma 目录下创建 <code>db.sqlite</code> 文件来存放数据。但是缺点很明显，性能与部署方面是远不如主流服务级别的数据库。尤其是部署，这在后面会说。</p>
<p>将会创建 <code>Account</code> <code>Example</code> <code>Session</code> <code>User</code> <code>Verification Token</code> 表，这里需要教你一个命令</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">npx prisma studio</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>此时访问 localhost:5555 将会得到一个 prisma 面板，即项目的所有 model 。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_QBXnHdoewh.png" alt="" class="img_ev3q"></p>
<p>关于 prisma 更多命令请参考 <a href="https://www.prisma.io/docs/reference/api-reference/command-reference" target="_blank" rel="noopener noreferrer" title="Prisma CLI Command Reference">Prisma CLI Command Reference</a></p>
<p>prisma 在线体验：<a href="https://playground.prisma.io/" target="_blank" rel="noopener noreferrer">Prisma Playground | Learn the Prisma ORM in your browser</a></p>
<p>由于 create-t3-app 已经封装好了<a href="https://create.t3.gg/en/usage/prisma" target="_blank" rel="noopener noreferrer">数据库的操作</a>，并且导出 prisma 对象，所以你只需要配置好环境变量便可。</p>
<p>主要代码如下</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">server/db.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> PrismaClient </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'@prisma/client'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> prisma </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">PrismaClient</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="类型提示">类型提示<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E7%B1%BB%E5%9E%8B%E6%8F%90%E7%A4%BA" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>在上面所定义的 model，都会被 prisma client 创建对应的 typescript 类型（在<code>node_modules/.prisma/index.d.ts</code>），你就可以直接通过 prisma.modelName 来操作 model，例如 Example（这里就不做注释了）</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> prisma </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'~/server/db'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">prisma</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">post</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">findUnique</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> where</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">prisma</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">post</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">create</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">prisma</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">post</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">update</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">prisma</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">post</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">delete</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">prisma</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">post</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">count</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="数据迁移">数据迁移<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E6%95%B0%E6%8D%AE%E8%BF%81%E7%A7%BB" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>我之前如果做数据库备份的话，我通常会在数据库管理软件（Navicat）将整个数据库转储为 SQL 文件，然后要用的时候在运行该 SQL 文件。而这样做呢虽然方便，但是数据都比较死，而且版本多了 sql 文件也多，导入繁琐。</p>
<p>此时就可以使用 <a href="https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch/relational-databases/using-prisma-migrate-typescript-postgres" target="_blank" rel="noopener noreferrer">Migrate</a>，通过命令的方式自动为我们生成当前版本下的 sql 文件，而需要用到的也通过命令的形式运行 sql 文件。</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="数据生成">数据生成<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E6%95%B0%E6%8D%AE%E7%94%9F%E6%88%90" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>你可以编写一个 <a href="https://www.prisma.io/docs/guides/database/seed-database#example-seed-scripts" target="_blank" rel="noopener noreferrer">seed 脚本</a>，用于插种（生成）自定义数据。</p>
<hr>
<p>prisma 不是本文重点，篇幅略少，但是作为 Typeorm 的长期使用者而言，我认为 prisma 会比 typeorm 友善一些，至少从文档上来说 prisma 大胜一筹，而且很多 node 的 web 框架都优先 prisma 作为 orm 框架（除了 nest.js），但不过这两个仓库的 issues 数量有点惨不忍睹。。。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="next-auth">next-auth<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#next-auth" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>我想先简单介绍一下 next-auth（背后由<a href="https://authjs.dev/" target="_blank" rel="noopener noreferrer" title="Auth.js">Auth.js</a> 提供）。</p>
<p>从名字来看也不难猜出，这是一个 next.js 的 auth 库。该库提供了多种身份验证策略，如基于密码的身份验证，OAuth 等等。并且你只需要简单的几行代码，提供好相关信息便可启用身份验证和授权功能。</p>
<p>你可以到这个网站 <a href="https://next-auth-example.vercel.app/" target="_blank" rel="noopener noreferrer" title="NextAuth.js Example">NextAuth.js Example</a>体验一番。下面是一些代码演示</p>
<p>由于 create-t3-app 默认是 Discord OAuth，因此我这边替换成使用者更多的 Github。（至于如何创建 Github OAuth Apps，在我之前的文章以及外面诸多文章中都有介绍到，这里不在演示了，附上配置图）</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image__B1RYeiFze.png" alt="" class="img_ev3q"></p>
<p>首先在</p>
<p>server/auth.ts 中 导入</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>server/auth.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> CredentialsProvider </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'next-auth/providers/credentials'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> GithubProvider </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'next-auth/providers/github'</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>并在 options 中设置好 providers，如下</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>server/auth.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> authOptions</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> NextAuthOptions </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  callbacks</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function" style="color:hsl(207, 82%, 66%)">session</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> session</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> user </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">session</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        session</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">id </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">id</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// session.user.role = user.role; &lt;-- put other properties on the session here</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> session</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  adapter</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">PrismaAdapter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">prisma</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  providers</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function" style="color:hsl(207, 82%, 66%)">CredentialsProvider</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'Credentials'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      credentials</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        username</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> label</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'Username'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> type</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'text'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> placeholder</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'night'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        password</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> label</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'Password'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> type</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'password'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">async</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">authorize</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">credentials</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Add logic here to look up the user from the credentials supplied</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> user </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'1'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'night'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> email</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'hi@night.cn'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">user</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> user</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function" style="color:hsl(207, 82%, 66%)">GithubProvider</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      clientId</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> env</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token constant" style="color:hsl(29, 54%, 61%)">GITHUB_CLIENT_ID</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      clientSecret</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> env</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token constant" style="color:hsl(29, 54%, 61%)">GITHUB_CLIENT_SECRET</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>不过此时会提示 env 对象没有 GITHUB_CLIENT_ID 属性，需要在 env.mjs 定义好 GITHUB_CLIENT_ID 与 GITHUB_CLIENT_SECRET。类型安全嘛，你可不想 GITHUB 不小心输成 <del>GAYHUB</del> 导致找不到这个值把。</p>
<p>当上述在设置完毕后，点击 Sign in 按钮便可跳转到 next-auth 所提供的简单登录表单。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_9eowvvnwU2.png" alt="" class="img_ev3q"></p>
<p>如果你想自定义修改登录页面，可以参考该视频<a href="https://www.youtube.com/watch?v=kB6YNYZ63fw" target="_blank" rel="noopener noreferrer" title="Create your own next-auth Login Pages - YouTube">Create your own next-auth Login Pages - YouTube</a></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="部署-trpc">部署 tRPC<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E9%83%A8%E7%BD%B2-trpc" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>通常来说 tRPC 会配合全栈框架使用，因此可以非常轻松的部署在 Vercel，Netlify 上。如今 Vercel 应该也已经家喻户晓了，因此这里就不演示如何部署，可到 <a href="https://create.t3.gg/en/deployment/vercel" target="_blank" rel="noopener noreferrer" title="Vercel • Create T3 App">Vercel • Create T3 App</a> 中查看相关步骤。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_BuS1"><p>不过要注意，Vercel 并不提供文件读写操作，即无法实现数据存储，因此你如果需要提供数据读取的操作，那么普通需要一个远程的数据库服务，将 DATABASE_URL 环境变量替换成线上地址。如</p><div class="language-title='env' codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-title='env' codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">DATABASE_URL=postgresql://myuser:mypassword@localhost:5432/mydb</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>这里推荐 <a href="https://railway.app/" target="_blank" rel="noopener noreferrer" title="railway">railway</a> 与 <a href="https://supabase.com/" target="_blank" rel="noopener noreferrer" title="supabase">supabase</a> 都提供远程数据服务，且有免费额度。（不过我比较好奇为啥好多远程数据服务多数都是 postgresql）</p><p>如果你执意要使用 vercel 部署，当你触发数据库服务时便会报错，以下是相关截图。</p><p><img decoding="async" loading="lazy" src="https://img.night.cn/image_7_XKmbuK87.png" alt="" class="img_ev3q"></p></div></div>
<p>至于说自行部署的话，create t3 app 提供了 docker 相关镜像，你可以直接使用 docker 部署，具体步骤可参考 <a href="https://create.t3.gg/en/deployment/docker" target="_blank" rel="noopener noreferrer">Docker • Create T3 App</a>。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="示例">示例<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E7%A4%BA%E4%BE%8B" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>这里我提供了一个简单的示例，你可以 <a href="https://trpc.night.cn/" target="_blank" rel="noopener noreferrer">点我</a> 访问体验一下（项目部署在 Vercel，而数据库服务在腾讯云，登录服务又依赖 Github，所以项目会稍微有那么慢）。整个项目结构大致如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_z_YaR-RnSu.png" alt="" class="img_ev3q"></p>
<p>你可以在 <a href="https://trpc.io/docs/example-apps" target="_blank" rel="noopener noreferrer" title="Example Apps | tRPC">Example Apps | tRPC</a> 查看 trpc 的示例应用。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="结语">结语<a href="http://www.yanghao717.cn/en/blog/typescript-full-stack-technology-trpc#%E7%BB%93%E8%AF%AD" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>如果你是用 Next，Nuxt 等这样的全栈框架，并且你的后端服务使用 Typescript 编写，不妨试试 trpc，你会惊喜地发现，它颠覆了传统的 API 交互，使你的 typescript 全栈应用程序的开发变得更加高效和流畅。</p>
<p>从 JavaScript 到 TypeScript 的演变，全栈应用的端到端类型安全，TypeScript 目前正在逐渐成为前端开发中不可或缺的一部分，也许未来的某一天当人们说起前端三件套时，不再是 HTML，CSS，JavaScript，而是 HTML，CSS，TypeScript。</p>
<p>再说到我为何会去尝试 tRPC，有很大的原因是因为厌倦了传统后端开发，厌倦了 nest.js 开发。然而现实生活中，你所厌倦的，往往是能为你提供收入的。人们总是做着自己不愿做的事，但生活所迫，谁又愿意呢。</p>]]></content:encoded>
            <category>trpc</category>
            <category>next</category>
            <category>prisma</category>
            <category>zod</category>
            <category>auth.js</category>
        </item>
        <item>
            <title><![CDATA[将 Supabase 作为下一个后端服务]]></title>
            <link>http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service</link>
            <guid>http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service</guid>
            <pubDate>Sat, 18 Feb 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[本文介绍了如何使用 Supabase 作为后端服务，使开发人员可以更快地构建和部署应用程序，无需配置数据库或编写复杂的身份验证代码。将使用 Nuxt.js 和 Supabase，以实现一个图床网站为例，来演示如何在前端中使用 Supabase API 和 Storage 服务。]]></description>
            <content:encoded><![CDATA[<p>对于想快速实现一个产品而言，如果使用传统开发，又要兼顾前端开发，同时又要花费时间构建后端服务。然而有这么一个平台（Baas Backend as a service）后端即服务，能够让开发人员可以专注于前端开发，而无需花费大量时间和精力来构建和维护后端基础设施。</p>
<p>对于只会前端的人来说，这是一个非常好的选择。后端即服务的平台使得开发人员能够快速构建应用程序，更快地将其推向市场。当然了，你可以将你的后端应用接入 Baas，这样你就无需配置数据库，编写复杂的身份效验。</p>
<p>如果你想了解 Baas，我想这篇文章或许对你有所帮助。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="什么是-supabase">什么是 <a href="https://supabase.com/" target="_blank" rel="noopener noreferrer" title="Supabase">Supabase</a>?<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E4%BB%80%E4%B9%88%E6%98%AF-supabase" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>在摘要部分也介绍到名词 BaaS (Backend as a Service) ，意思为<strong>后端即服务</strong>。这个概念是在我接触 Serverless 的时候了解到的，更准确来说是腾讯云开发。当时在编写小程序的时候，只需要专注与应用业务逻辑，而不用编写数据存储，身份验证，文件存储等后端服务，这些统统由 BaaS 平台所提供。 通常会配合 Serverless 函数使用，通常也叫 FaaS（Function as a Service）。通常来说，FaaS 会依赖于 BaaS 平台。</p>
<p>而 Supabase 便是 BaaS 的平台之一。Supabase 是一个开源的 Firebase 替代品。使用 Postgres 数据库、身份验证、即时 API、边缘函数、实时订阅和存储启动项目。</p>
<p>你也许听过 Firebase，由 Google 提供的私有云服务，但开发者无法修改和扩展其底层代码。而 Supabase 是开源的，提供了类似 Firebase 的功能，且定价灵活，并且官方自称为 <a href="https://link.juejin.cn/?target=https://firebase.google.com/" target="_blank" rel="noopener noreferrer" title="Firebase">Firebase</a>的替代品。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="baas-与-cms-有何不同">BaaS 与 CMS 有何不同？<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#baas-%E4%B8%8E-cms-%E6%9C%89%E4%BD%95%E4%B8%8D%E5%90%8C" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>BaaS 通常只专注于应用的后端服务，而 CMS 则是专注与内容管理。不过 BaaS 比较依赖云服务，而 CMS 通常只依赖于 web 后端技术。如果你想搭建一个内容站点（视频，音频，文章），并且作为网站管理员，那么 CMS 就是一个很好的选择，并且有相当多的主题模板。反之，不想搭建后端服务，减少运营程序，那么毫不犹豫的选择 BaaS。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="注册-supabase">注册 Supabase<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E6%B3%A8%E5%86%8C-supabase" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>进入 <a href="https://app.supabase.com/sign-in" target="_blank" rel="noopener noreferrer">supabase 登录界面</a> 选择 Continue With Github</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_2yiQ9NHv21.png" alt="" class="img_ev3q"></p>
<p>输入 Github 账号密码进入<a href="https://app.supabase.com/projects" target="_blank" rel="noopener noreferrer" title="主页��面">主页面</a>，新建一个项目</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_0eoOyP8DM2.png" alt="" class="img_ev3q"></p>
<p>为该项目起名，设置数据库密码，以及分配地区。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_BuS1"><p>创建 supabase 项目对密码要求非常严格，像 a123456 这种根本无法通过，像 ●●●●●●●●●● 密码就可以。</p><p>地区方面优先就近原则，而最近的也就是日本与韩国，很无奈 supabase 在大陆和港澳台并未设立服务器。</p></div></div>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_N5CQnx8cnU.png" alt="" class="img_ev3q"></p>
<p>等待片刻，你将拥有一个免费的后端服务！</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_Z33n9aUOC7.png" alt="" class="img_ev3q"></p>
<p>supabase 会提供一个二级域名供开发者访问，也就是这里 Project Configuration 的 URL，对应的这个二级域名 azlbliyjwcxxxxx 也就是你这个项目的唯一标识 Reference ID（下文称 项目 id）。你可以到 <a href="https://app.supabase.com/project/azlbliyjwcemojkwazto/settings/api" target="_blank" rel="noopener noreferrer" title="https://app.supabase.com/project/你的项目id/settings/api">https://app.supabase.com/project/你的项目 id/settings/api</a> 中查看相关配置。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="体验一下">体验一下<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E4%BD%93%E9%AA%8C%E4%B8%80%E4%B8%8B" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>这里参考到了官方文档 <a href="https://supabase.com/docs/guides/database/api" target="_blank" rel="noopener noreferrer" title="Serverless APIs">Serverless APIs</a>。</p>
<p>首先，创建一个 todos 表，并新增字段（列）task 为 varchar 类型，Save 保存。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_Do9LHoUsYo.png" alt="" class="img_ev3q"></p>
<p>Insert row 添加一行记录，id 为 1，task 为 code。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_R9PEyH-spd.png" alt="" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_MLm6_i1Pb-.png" alt="" class="img_ev3q"></p>
<p>现在有了数据后，正常来说我们应该做什么？请求一下数据看看？不不不，应该是设置数据的权限。</p>
<p>打开到下图界面，我们要为 todos 数据新增一个 policy 策略。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_MEKk1-qQFl.png" alt="" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_W-C-pGNh1o.png" alt="" class="img_ev3q"></p>
<p>supabase 针对不同的场景提供了相应的策略方案模板，你也可以根据你的需求进行设置，这里作为演示不考虑太复杂，选择第一个允许任何人都可以请求到 todos 数据。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_Oa_424N4gz.png" alt="" class="img_ev3q"></p>
<p>接着下一步即可</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_wV_MqXQXcK.png" alt="" class="img_ev3q"></p>
<p>此时就新增了一个所有用户都可查询的 todo 的策略，同样的你还可以添加只有授权用户才能够创建更新删除 todo，更新与删除只能操作属于自己的 todo 资源。</p>
<p>这时候设置好了数据的权限后，就可以尝试去请求了，打开下图页面，将 URL 与 apikey 复制下来。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_GDEeyFCI2E.png" alt="" class="img_ev3q"></p>
<p>选择你一个 http 请求工具，这里我选用 <a href="https://hoppscotch.io/" target="_blank" rel="noopener noreferrer" title="hoppscotch">hoppscotch</a>，将信息填写上去，请求将会得到一开始所创建的 todo 数据。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_aSbRfmlwb9.png" alt="" class="img_ev3q"></p>
<p>除了 restful api 风格，还支持 graphql 风格，可查阅文档 <a href="https://supabase.com/docs/guides/database/api#using-the-api" target="_blank" rel="noopener noreferrer" title="Using the API">Using the API</a></p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_R0HtkYmznS.png" alt="" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="使用类库">使用类库<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E4%BD%BF%E7%94%A8%E7%B1%BB%E5%BA%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>正常情况肯定不会像上面那样去使用，而是通过代码的方式进行登录，CRUD。这里使用 <a href="https://supabase.com/docs/reference/javascript/installing" target="_blank" rel="noopener noreferrer" title="Javascript Client Library">Javascript Client Library</a>，替我们封装好了 supabase 的功能。</p>
<p>首先，安装依赖</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">install</span><span class="token plain"> @supabase/supabase-js</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>创建 客户端实例</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> createClient </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'@supabase/supabase-js'</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>此时准备好上述的 URL 与 apikey，用于创建 supabase 实例，不过 supabase 还提供 <a href="https://supabase.com/docs/reference/javascript/typescript-support" target="_blank" rel="noopener noreferrer">type 类型支持</a>，可以将生成的 <code>database.types.ts</code> 导入到实例中，如</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> createClient </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'@supabase/supabase-js'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> Database </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'lib/database.types'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> supabase </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:hsl(207, 82%, 66%)">createClient</span><span class="token generic-function generic class-name operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token generic-function generic class-name" style="color:hsl(29, 54%, 61%)">Database</span><span class="token generic-function generic class-name operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">process</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token constant" style="color:hsl(29, 54%, 61%)">SUPABASE_URL</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> process</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">env</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token constant" style="color:hsl(29, 54%, 61%)">SUPABASE_ANON_KEY</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>此时有了 supabse 对象后，就能够请求数据了，像上述通过 http 的方式获取 todos 数据，在这里对应的代码为</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> error </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> supabase</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">from</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'todos'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">select</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><a href="https://supabase.com/docs/reference/javascript/select" target="_blank" rel="noopener noreferrer">官方的演示例子</a> 非常清晰，这里就不在演示新增更新等示例。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image-20230218182910913.png" alt="image-20230218182910913" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="supabase-主要功能"><a href="https://supabase.com/docs" target="_blank" rel="noopener noreferrer">Supabase 主要功能</a><a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#supabase-%E4%B8%BB%E8%A6%81%E5%8A%9F%E8%83%BD" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="database-数据库">Database 数据库<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#database-%E6%95%B0%E6%8D%AE%E5%BA%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>supabase 基于 PostgreSQL 数据库，因此当你创建完项目后，就自动为你分配好了一个可访问的 PostgreSQL 数据库，你完全可以将其当做一个远程的 PostgreSQL 数据主机。</p>
<p>可以在如下页面中查看到有关数据库连接的信息，当然你看不到密码。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_6uCHh3qrlE.png" alt="" class="img_ev3q"></p>
<p>测试连接，结果如下，并无问题</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_8-JOTiLI0G.png" alt="" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="authentication-身份验证">Authentication 身份验证<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#authentication-%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p><a href="https://supabase.com/docs/guides/auth/overview" target="_blank" rel="noopener noreferrer" title="Auth | Supabase Docs">Auth | Supabase Docs</a></p>
<p>supabase 令我感兴趣的是 <a href="https://supabase.com/docs/learn/auth-deep-dive/auth-row-level-security" target="_blank" rel="noopener noreferrer" title="Row Level Security">Row Level Security</a>，supabase 使用 Postgres 的 Row-Level-Security（行级安全）策略，可以限制不同用户对同一张表的不同数据行的访问权限。这种安全机制可以确保只有授权用户才能访问其所需要的数据行，保护敏感数据免受未授权的访问和操作。</p>
<p>在传统的访问控制模型中，用户通常只有对整个表的访问权限，无法限制他们对表中特定数据行的访问。而行级安全技术则通过将访问权限授予到特定的数据行，从而让不同的用户只能访问他们被授权的行。这种行级安全有一个很经典应用场景-多租户系统：允许不同的客户在同一张表中存储数据，但每个客户只能访问其自己的数据行。</p>
<p>这对于传统后端开发而言，如果不借用一些安全框架，实现起来十分棘手，要么业务代码与安全代码逻辑混杂不堪。</p>
<p>权限细分方面，无需担心，supabase 已经为你做好了准备，就等你来进行开发。</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="第三方登录">第三方登录<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E7%AC%AC%E4%B8%89%E6%96%B9%E7%99%BB%E5%BD%95" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>对于想要提供第三方登录，supabse 集成多数平台（除了国内），只需要提供 Clinet ID, Client Secret, Redirect URL 便可完成第三方登录。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_OvBRJ_elZR.png" alt="" class="img_ev3q"></p>
<p>这里演示下如何使用 Github，首先到打开<span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/settings/applications/new" target="_blank" rel="noopener noreferrer" title="New OAuth Application (github.com)">New OAuth Application (github.com)</a></span> 创建一个 Oauth Apps，其中 Authorization callback URL 由 supabase 提供，如下图。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_QVspy-oxQK.png" alt="" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_jyaUMSDed2.png" alt="" class="img_ev3q"></p>
<p>当你创建完后，会提供 Client ID，与 Client secret，将这两个值填写到 supabase 中，并启用。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_QpRRxpR5o5.png" alt="" class="img_ev3q"></p>
<p>此时打开如下页面，将 Site URL 替换成开发环境，或是线上环境，在 Github 登录后将会跳转到这个地址上</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_zmfXC85ayC.png" alt="" class="img_ev3q"></p>
<p>此时 supabase 支持 github 登录就已经配置完毕，当你在前端触发登录按钮后，借助<a href="https://supabase.com/docs/reference/javascript/auth-signinwithoauth" target="_blank" rel="noopener noreferrer" title="supabase 的js库">supabase 的 js 库</a>，如</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> error </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> supabase</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">auth</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">signInWithOAuth</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  provider</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'github'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>便可完成 Github 第三方登录。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="bucket-存储桶">Bucket 存储桶<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#bucket-%E5%AD%98%E5%82%A8%E6%A1%B6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>接触过对象存储的开发者对 Bucket 应该不陌生，相当于给你一个云盘，这里演示如何使用。</p>
<p>打开如下界面，这里选择公开存储桶，比如说用于图床。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_2Is4Bfwf8f.png" alt="" class="img_ev3q"></p>
<p>点击右上角的 upload files，选择你要上传的图片。你可以为此生成一个访问 URL</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_vkuzeZZVJ_.png" alt="" class="img_ev3q"></p>
<p>你可以访问 <a href="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/publilc/1.png" target="_blank" rel="noopener noreferrer">1.png</a> 来查看这张图片。如果是公开的话 一般都是类似<a href="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/new-bucket/1.png" target="_blank" rel="noopener noreferrer">https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/new-bucket/1.png</a></p>
<p>而私有的为 <a href="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/sign/new-bucket/1.png?token=eyJhbGciOiJIUzI1NiIsInR5cCIxxxxxxxxxxxxxxxxx" target="_blank" rel="noopener noreferrer">https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/sign/new-bucket/1.png?token=eyJhbGciOiJIUzI1NiIsInR5cCIxxxxxxxxxxxxxxxxx</a> 路径稍微变化了下，还有就是多了个 token，如果不携带 token 则访问不了图片。</p>
<p>你可以到<a href="https://supabase.github.io/storage-api/" target="_blank" rel="noopener noreferrer" title="Supabase Storage API">Supabase Storage API</a> 查看 storage 相关 api。</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>现学现用</div><div class="admonitionContent_BuS1"><p>本文中的所有图片数据都来源于 supabase bucket。</p></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="edge-functions-边缘函数">Edge Functions 边缘函数<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#edge-functions-%E8%BE%B9%E7%BC%98%E5%87%BD%E6%95%B0" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>边缘函数可以分布在全球的接近您的用户各个地方，类似与 CDN，但 CDN 主要服务于静态资源，而 Edge Functions 可以将你的后端应用接口，像 CDN 那样部署到全球各地。</p>
<p>有兴趣可自行了解。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="使用-supabase-编写一个简易图床"><strong>使用 Supabase 编写一个简易图床</strong><a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E4%BD%BF%E7%94%A8-supabase-%E7%BC%96%E5%86%99%E4%B8%80%E4%B8%AA%E7%AE%80%E6%98%93%E5%9B%BE%E5%BA%8A" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>如果只单纯看看 supabase 文档，不去动手实践接入一下，总觉得还是差点意思。于是我准备使用 Nuxt 作为前端框架接入 supabase，官方模块 <a href="https://supabase.nuxtjs.org/" target="_blank" rel="noopener noreferrer" title="Nuxt Supabase">Nuxt Supabase</a> 去编写一个应用。</p>
<p>原本我是打算写个 Todo List 的（恼，怎么又是 Todo List），但是看到 <a href="https://supabase.com/docs/guides/resources/examples#official-examples" target="_blank" rel="noopener noreferrer" title="官方示例">官方示例</a>（一堆 Todo List）后我瞬间就没了兴致 🥀。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_1polvJf0q0.png" alt="" class="img_ev3q"></p>
<p>思来想去，不妨就简单做个图床吧。项目地址：<a href="https://image.night.cn/" target="_blank" rel="noopener noreferrer">https://image.night.cn</a> 有兴趣可自行阅读<span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/night/image-hosting" target="_blank" rel="noopener noreferrer">源码</a></span>。（<strong>写的相对匆忙，仅作为演示，随时有可能删除，请勿将此站作为永久图床！</strong>）</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="一些你可能比较好奇的问题">一些你可能比较好奇的问题<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E4%B8%80%E4%BA%9B%E4%BD%A0%E5%8F%AF%E8%83%BD%E6%AF%94%E8%BE%83%E5%A5%BD%E5%A5%87%E7%9A%84%E9%97%AE%E9%A2%98" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="资源">资源<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E8%B5%84%E6%BA%90" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>可以到 <a href="https://app.supabase.com/project/%E9%A1%B9%E7%9B%AEid/settings/billing/usage" target="_blank" rel="noopener noreferrer">https://app.supabase.com/project/项目id/settings/billing/usage</a> 中查看相关资源使用情况，这里我就将截图放出来了。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_Bllhp6XlFz.png" alt="" class="img_ev3q"></p>
<p>说实话，对于个人独立开发者的项目都绰绰有余了。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="费用">费用<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E8%B4%B9%E7%94%A8" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>在 <a href="https://supabase.com/pricing" target="_blank" rel="noopener noreferrer" title="资费标准">资费标准</a> 中可以看到，免费版<strong>最多 2 个项目</strong>，不过在上述的资源，其实已经非常香了，毕竟只需要一个 GIthub 账号就能免费使用，还要啥自行车。</p>
<p><img decoding="async" loading="lazy" src="https://azlbliyjwcemojkwazto.supabase.co/storage/v1/object/public/public/image_MNtdzsdJ2t.png" alt="" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="网速">网速<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E7%BD%91%E9%80%9F" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>国内因为没有 supabase 的服务器节点，然后且有防火墙的存在，所以请求速度偏慢。不过体验下来至少不用梯子，速度慢点但也还在可接受范围。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="域名">域名<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E5%9F%9F%E5%90%8D" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>用过 vercel 的你应该会想是不是也能自定义域名呢? 当然，不过这是 supabase pro 版才支持，一个月$25(美刀)，算了算了，再一眼 azlbliyjwcxxxxx.supabase.co<del>就会爆炸</del>感觉也蛮好记的。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="结语">结语<a href="http://www.yanghao717.cn/en/blog/use-supabase-as-backend-service#%E7%BB%93%E8%AF%AD" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>说句实话，真心感觉 supabase 不错，尤其是对个人/独立开发者而言，没必要自行去购买服务器，去搭建后端服务，很多时候我们只想专注于应用程序的开发和功能实现，而不是花费大量时间和精力在服务器和后端服务的部署和管理上。</p>]]></content:encoded>
            <category>supabase</category>
            <category>nuxt</category>
            <category>project</category>
        </item>
        <item>
            <title><![CDATA[Deno 不只是个 Javascript 运行时]]></title>
            <link>http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime</link>
            <guid>http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime</guid>
            <pubDate>Fri, 20 Jan 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Deno 是一个安全的 JavaScript 和 TypeScript 运行时，作者是 Ryan Dahl（也是 Node.js 的原作者）。Deno 的诞生之初是为了解决 2009 年首次设计 Node.js 时的一些疏忽。我认为这种改造动机很有道理，因为我相信每个程序员都希望有机会能重写他们已有 10 年历史的代码。]]></description>
            <content:encoded><![CDATA[<p>Deno 是一个安全的 JavaScript 和 TypeScript 运行时，作者是 Ryan Dahl（也是 Node.js 的原作者）。Deno 的诞生之初是为了<a href="https://link.juejin.cn/?target=https://www.youtube.com/watch?v=M3BM9TB-8yA" target="_blank" rel="noopener noreferrer">解决 2009 年首次设计 Node.js 时的一些疏忽</a>。我认为这种改造动机很有道理，因为<strong>我相信每个程序员都希望有机会能重写他们已有 10 年历史的代码。</strong></p>
<p>deno 刚出的时候就听闻了，传言 deno 是下一代 node.js。不过如今看来，还革不了 node.js 的命。如果要说两者字面上的区别，Deno 的来源是 Node 的字母重新组合（Node = no + de），表示"拆除 Node.js"（de = destroy, no = Node.js）。</p>
<p>趁着假期学了一段时间的 deno（指<a href="https://deno.land/manual@v1.29.3/introduction" target="_blank" rel="noopener noreferrer" title="文档">文档</a>刷了一遍），想分享本人作为 node 开发者在学习 deno 时认为的一些亮点，以及个人对 deno 与 node 见解。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="开发环境">开发环境<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p><a href="https://deno.land/manual@v1.29.2/getting_started/installation" target="_blank" rel="noopener noreferrer" title="Installation | Manual | Deno">Installation | Manual | Deno</a></p>
<p>默认情况下 deno 会根据不同的系统，选择相应的安装目录，以及依赖目录，你可以<a href="https://deno.land/manual@v1.29.3/getting_started/setup_your_environment#environment-variables" target="_blank" rel="noopener noreferrer" title="配置环境变量">配置环境变量</a>来改变 deno 的默认行为。</p>
<p>这里我选用 vscode 进行开发，安装<a href="https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno" target="_blank" rel="noopener noreferrer" title="deno官方插件">deno 官方插件</a>。此时创建一个项目工程文件夹，打开 vscode，并创建 <code>.vscode/settings.json</code> 内容如下</p>
<div class="language-json codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>.vscode/settings.json<span style="flex:1;text-align:right">json</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-json codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"deno.enable"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"deno.lint"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"editor.formatOnSave"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"[typescript]"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token property" style="color:hsl(355, 65%, 65%)">"editor.defaultFormatter"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"denoland.vscode-deno"</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>在 vscode 中默认会将 ts 代码认为是 node 运行时环境，因此需要在项目工程下手动配置并启用 deno，让 vscode 以 deno 运行时环境来语法解析 ts 代码。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="deno-的一些亮点">deno 的一些亮点💡<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#deno-%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BA%AE%E7%82%B9" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>因为 deno 与 node 一样，都是 javascript 运行时（deno 合理来说是 typescript 运行时）。所以在 javascript 的部分就没什么好说的了，主要对比 deno 相比与 node 的优势，或说我个人觉得一些使用亮点。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="官方所介绍的亮点">官方所介绍的亮点<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E5%AE%98%E6%96%B9%E6%89%80%E4%BB%8B%E7%BB%8D%E7%9A%84%E4%BA%AE%E7%82%B9" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>以下是官方所介绍的<a href="https://deno.land/manual@v1.29.3/introduction#feature-highlights" target="_blank" rel="noopener noreferrer" title="亮点">亮点</a>，我对其做了翻译</p>
<ul>
<li>
<p>提供<a href="https://deno.land/manual@v1.29.3/runtime/web_platform_apis" target="_blank" rel="noopener noreferrer" title="web平台功能">web 平台功能</a>，采用网络平台标准。例如，使用 ES 模块、Web worker 和支持 <code>fetch()</code>。</p>
</li>
<li>
<p>默认安全。除非显式启用，否则无法访问文件、网络或环境。</p>
</li>
<li>
<p>支持开箱即用的 <a href="https://deno.land/manual@v1.29.3/advanced/typescript" target="_blank" rel="noopener noreferrer" title="TypeScript">TypeScript</a>。</p>
</li>
<li>
<p>提供单个可执行文件 （<code>deno</code>）。</p>
</li>
<li>
<p>为编辑器提供内置的开发工具，如代码格式化程序 （<a href="https://deno.land/manual@v1.29.3/tools/formatter" target="_blank" rel="noopener noreferrer" title="deno fmt">deno fmt</a>）、linter （<a href="https://deno.land/manual@v1.29.3/tools/linter" target="_blank" rel="noopener noreferrer" title="deno lint">deno lint</a>）、测试运行程序（<a href="https://deno.land/manual@v1.29.3/basics/testing" target="_blank" rel="noopener noreferrer" title="deno test">deno test</a>）和<a href="https://deno.land/manual@v1.29.3/getting_started/setup_your_environment.md#using-an-editoride" target="_blank" rel="noopener noreferrer" title="语言服务器">语言服务器</a>。</p>
</li>
<li>
<p>拥有<a href="https://deno.land/std@0.172.0" target="_blank" rel="noopener noreferrer" title="一组经过审查（审核）的标准模块">一组经过审查（审核）的标准模块</a>，保证与 Deno 一起使用。</p>
</li>
<li>
<p>可以将脚本<a href="https://deno.land/manual@v1.29.3/tools/bundler" target="_blank" rel="noopener noreferrer" title="捆绑">捆绑</a>到单个 JavaScript 文件或<a href="https://deno.land/manual@v1.29.3/tools/compiler" target="_blank" rel="noopener noreferrer" title="可执行文件">可执行文件</a>中。</p>
</li>
<li>
<p>支持使用现有的 npm 模块</p>
</li>
</ul>
<p>以下会针对部分亮点，进行个人的见解。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="自带实用工具">自带实用工具<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E8%87%AA%E5%B8%A6%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>deno 则是自带代码格式化（<code>deno fmt</code>）、代码风格（<code>deno lint</code>）、代码测试（<code>deno test</code>）、依赖检查器（<code>deno info</code>）等等的功能。而这些在 node 中，你需要通过第三方的库，如 eslint，jest 才能实现。</p>
<p>你可以在项目工程中添加配置文件 <a href="https://deno.land/manual@v1.29.2/getting_started/configuration_file" target="_blank" rel="noopener noreferrer" title="deno.json">deno.json</a>来定制化代码风格（rust 中也有类似的功能），但在 node 中必须要借助第三方的库，或是 IDE 才能实现。</p>
<p>不过也能理解，在当时的编程环境背景下，javascript 还主要作为前端的脚本语言使用，又怎能让 node 来做相关规范呢？（这句话可能有点不妥）</p>
<p><strong>这点我认为对开发者是否选用你这门语言的一个加分项</strong>，并且这些功能也应该作为编程语言所自带的，有官方的背书（保证），对代码风格才更有所保障。</p>
<p>这里有份 <a href="https://deno.land/manual@v1.29.4/references/cheatsheet#nodejs---deno-cheatsheet" target="_blank" rel="noopener noreferrer" title="官方小抄">官方小抄</a> 可以知道通过<code>deno xxx</code>等命令能够做到 node 原本需要通过第三方库才能实现的功能。</p>
<table><thead><tr><th>Node.js</th><th>Deno</th></tr></thead><tbody><tr><td><code>node file.js</code></td><td><code>deno run file.js</code></td></tr><tr><td><code>ts-node file.ts</code></td><td><code>deno run file.ts</code></td></tr><tr><td><code>npm i -g</code></td><td><code>deno install</code></td></tr><tr><td><code>npm i</code> / <code>npm install</code></td><td><em>n/a</em></td></tr><tr><td><code>npm run</code></td><td><code>deno task</code></td></tr><tr><td><code>eslint</code></td><td><code>deno lint</code></td></tr><tr><td><code>prettier</code></td><td><code>deno fmt</code></td></tr><tr><td><code>rollup</code> / <code>webpack</code> / etc</td><td><code>deno bundle</code></td></tr><tr><td><code>package.json</code></td><td><code>deno.json</code> / <code>deno.jsonc</code> / <code>import_map.json</code></td></tr><tr><td><code>tsc</code></td><td><code>deno check</code></td></tr><tr><td><code>typedoc</code></td><td><code>deno doc</code></td></tr><tr><td><code>jest</code> / <code>ava</code> / <code>mocha</code> / <code>tap</code> / etc</td><td><code>deno test</code></td></tr><tr><td><code>nodemon</code></td><td><code>deno run/lint/test --watch</code></td></tr><tr><td><code>nexe</code> / <code>pkg</code></td><td><code>deno compile</code></td></tr><tr><td><code>npm explain</code></td><td><code>deno info</code></td></tr><tr><td><code>nvm</code> / <code>n</code> / <code>fnm</code></td><td><code>deno upgrade</code></td></tr><tr><td><code>tsserver</code></td><td><code>deno lsp</code></td></tr><tr><td><code>nyc</code> / <code>c8</code> / <code>istanbul</code></td><td><code>deno coverage</code></td></tr><tr><td><code>benchmarks</code></td><td><code>deno bench</code></td></tr></tbody></table>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="远程导入"><a href="https://deno.land/manual@v1.29.3/basics/modules#remote-import" target="_blank" rel="noopener noreferrer" title="远程导入">远程导入</a><a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E8%BF%9C%E7%A8%8B%E5%AF%BC%E5%85%A5" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>与 node 不同，使用 node 通常需要从 npm 官方包来下载并导，有 npm 这样的包管理器来统一管理这些包（package），我们通常称这种为中心化，而 deno 与 go 的做法很像，你可以将你的封装好的代码定义成一个包，并将其放在任何网络可访问的地方，比如 github，或是私有地址，然后通过网络读取文件的方式来导入，这种称为去中心化。</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>node 也不一定要用 npm 来下载模块，也可以本地模块或者私有模块。</div></div>
<p>关于中心化与去中心化管理，各有优缺，这里不做细致讨论。</p>
<p>以下是 deno 官方远程导入的代码示例：</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>remote.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> add</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> multiply </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'https://x.nest.land/ramda@0.27.0/source/index.js'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">totalCost</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">outbound</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">number</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> inbound</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">number</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> tax</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">number</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">number</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">multiply</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">outbound</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> inbound</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> tax</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token builtin" style="color:hsl(95, 38%, 62%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">totalCost</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">19</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">31</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1.2</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token builtin" style="color:hsl(95, 38%, 62%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">totalCost</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">45</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">27</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1.15</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token doc-comment comment" style="color:hsl(220, 10%, 40%)">/**</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token doc-comment comment" style="color:hsl(220, 10%, 40%)"> * Output</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token doc-comment comment" style="color:hsl(220, 10%, 40%)"> *</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token doc-comment comment" style="color:hsl(220, 10%, 40%)"> * 60</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token doc-comment comment" style="color:hsl(220, 10%, 40%)"> * 82.8</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token doc-comment comment" style="color:hsl(220, 10%, 40%)"> */</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>而这里的 <code>https://x.nest.land/ramda@0.27.0/source/index.js</code> 可以替换成任何 ES module 特性（import/export）的模块。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="http-的方式运行代码">http 的方式运行代码<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#http-%E7%9A%84%E6%96%B9%E5%BC%8F%E8%BF%90%E8%A1%8C%E4%BB%A3%E7%A0%81" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>既然都能通过 http（cdn）远程导入模块，那远程运行文件自然也不成大问题。有时候像快捷体验一下别人的代码，或是想要在浏览器中运行一下代码，这时候就可以通过 http 的方式来运行代码。</p>
<p>这里我准备了一段代码，并部署到我的站点上，你可以通过如下命令得到该代码的执行结果（如果你有安装 deno 的话），放心这段代码并无危害，就是一段简单的 console.log 输出。</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">deno run https://deno.night.cn/main.ts</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>在第一次使用时下载并缓存代码，你可以通过</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">deno info http://deno.night.cn/main.ts</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>来查看文件信息，如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image_deb0_lGYRA.png" alt="" class="img_ev3q"></p>
<p>deno info 还可以查看 deno 的相关配置，默认缓存都设置在 C 盘，你也可以设置<strong>DENO_DIR</strong> 环境变量来更改 deno 目录，可以到 <a href="https://deno.land/manual@v1.29.3/getting_started/setup_your_environment#environment-variables" target="_blank" rel="noopener noreferrer" title="Set Up Your Environment">Set Up Your Environment</a> 查看 deno 相关环境变量。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="依赖管理">依赖管理<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>经常使用 node 的开发者应该对 node 的依赖感到无比厌烦，关于这部分强烈建议看 <a href="https://juejin.cn/post/6914508615969669127" target="_blank" rel="noopener noreferrer">node_modules 困境</a>，你就能知道 node 的 node_modules 设计的是有多少问题。看完你也就能知道为啥越来越多的 node 项目都使用 <a href="https://pnpm.io/" target="_blank" rel="noopener noreferrer">pnpm</a> 作为包管理。</p>
<p>虽然 node 有了 pnpm 包管理器这种情况会好一些，但本质在项目目录还是需要 node_modules 文件。也许你用过其他语言的包管理器，你会发现基本都是将所有用到的依赖全局缓存起来，当不同的项目工程需要用到依赖时，直接去全局缓存中找，而不是像 npm 一样，下载到项目工程目录下，存放在 node_modules 里。</p>
<p>而 deno 也是采用这种这种方式，<code>no npm install</code>，<code>no package.json</code>，<code>no node_modules/</code> ，<a href="https://deno.land/manual@v1.29.3/node/npm_specifiers#using-npm-packages-with-npm-specifiers" target="_blank" rel="noopener noreferrer" title="使用npm包">使用 npm 包</a>可以像下面这样，当你使用 deno run 时便会下载好依赖置全局缓存中。</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_"><span></span>app.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// @deno-types="npm:@types/express@^4.17"</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> express </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'npm:express@^4.17'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> app </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">express</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'/'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">send</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'Hello World'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">app</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">listen</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">3000</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token builtin" style="color:hsl(95, 38%, 62%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'listening on http://localhost:3000/'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>deno 刚发布的时候，甚至还不支持 NPM 软件包，这无非是要告诉用户 deno 社区没有轮子，要求用户自己去造一个。不过 deno 团队还是做出了比较正确的选择，支持 npm 软件包，并且还非常友好。</p>
<p>不过如果你在 deno 中使用了 npm 包，可能会存在一些兼容性问题，万一遇到了，也可以通过添加 <code>--node-modules-dir</code> 标识，在当前运行目录下创建 <code>node_modules</code> 文件夹。详见 <a href="https://deno.land/manual@v1.29.4/node/npm_specifiers#--node-modules-dir-flag" target="_blank" rel="noopener noreferrer" title="--node-modules-dir flag">--node-modules-dir flag</a></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="安全">安全<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E5%AE%89%E5%85%A8" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p><a href="https://deno.land/manual@v1.29.4/basics/permissions" target="_blank" rel="noopener noreferrer" title="Permissions">Permissions</a></p>
<p>在 2022 年 npm 出现过一些恶性的库，如 lodash-utils, faker.js, chalk-next。万一你不小心安装了上面，轻则项目无法运行，输出无意义乱码，重则删除本地文件。</p>
<p>又因为 npm 几乎没有代码审计的机制，任何开发者只需要有一个 npm 的账号就能在上面随意发布他想发布的包。通常来说电脑病毒都是通过随意读取与写入本地文件来达到病毒的目的，但在 deno 中，代码如果尝试写入与读入文件，都需要询问开发者是否允许操作。并且在 linux 系统，你可以指定像 /usr /etc 这样非 root 角色来操作该文件，避免真是病毒文件导致删除不该删除的文件。</p>
<p>此外像命令执行，网络访问，环境变量这些极易危害电脑的权限，deno 都会检测到，并做出提示告诫开发者是否允许执行。总之你能想到的电脑安全隐患，deno 都为你做好了。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="内置浏览器环境运行时">内置浏览器环境（运行时）<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E5%86%85%E7%BD%AE%E6%B5%8F%E8%A7%88%E5%99%A8%E7%8E%AF%E5%A2%83%E8%BF%90%E8%A1%8C%E6%97%B6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>这是我认为 deno 最大的亮点。</p>
<p>总所周知，浏览器的 js 代码有很大概率是无法直接在 node 中跑起来的，原因就是 node 的全局对象中没有浏览器的对象，如 window，document，甚至连<code>localStorage</code> 都有！</p>
<p>这说明什么，往常如果你从别的网站扣了一段代码下来，想在 node 运行会发现什么 window is not defined，xxx is not defined。如果想在 node 运行，你必须需要补齐浏览器的环境，此外可以借助 js-dom，happy-dom 等 npm 包。而 window，xxx 这些全局只有浏览器才定义的全局对象在 deno 的运行时同样定义了，可以到<a href="https://deno.land/manual@v1.29.3/runtime/web_platform_apis#using-web-platform-apis" target="_blank" rel="noopener noreferrer" title="这里">这里</a>查看支持的 Web 平台 API。</p>
<p>虽说与真实浏览器全局对象有些许差异，但这也足够让开发者少做很多工作。比如 Web 逆向者通常要扣取浏览器的 js 代码，并补齐环境使其能够在 node 中运行，而有了 deno 这将变得非常轻松！</p>
<p><strong>与其说是 javascript/typescript 运行时，我更愿意说是浏览器运行时！</strong></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="web-框架">Web 框架<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#web-%E6%A1%86%E6%9E%B6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>你可以在 <a href="https://deno.land/manual@v1.29.2/getting_started/web_frameworks" target="_blank" rel="noopener noreferrer" title="Web Frameworks">Web Frameworks</a> 中看到 deno 官方所推荐的 Web 框架，其中 <a href="https://deno.land/manual@v1.29.2/getting_started/web_frameworks#fresh" target="_blank" rel="noopener noreferrer" title="Fresh">Fresh</a> 也是最为推荐使用的（后续我也会尝试使用该框架）。</p>
<p>而在 node 社区中，你会看到像 express，koa，nestjs 等等这种非 Node 官方或大背景的 web 框架（而且还很多），而这时对于初学者而言，就有点不知道该如何做出抉择。</p>
<p>而像 java 中你完全可以不用担心该学什么，说学 spring 就是在学 java 这可一点都不为过。可能这也是国内 java，尤其是 spring 的开发者尤为诸多的原因。</p>
<p>吐槽归吐槽，但我想表明的是在有官方的支持下，用户和开发者能够统一使用某个框架，一起维护与使用一个更好的框架。而不是个个 Web 框架的都有各自的优缺点，让使用者去选择，搞得这个框架是另一个框架的轮子一般。</p>
<p>所以我认为这种支持是很有必要。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="公共托管服务">公共托管服务<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E5%85%AC%E5%85%B1%E6%89%98%E7%AE%A1%E6%9C%8D%E5%8A%A1" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p><a href="https://dash.deno.com/" target="_blank" rel="noopener noreferrer" title="Project - Deploy (deno.com)">Project - Deploy (deno.com)</a></p>
<p>deno 像 vercel/netfily 一样提供了一个代码托管服务，可以将你的 deno 应用部署上去。对，目前来看还无法部署前端应用，因为要指明一个入门文件（main.ts）。</p>
<p>你可以通过 <a href="https://night.deno.dev/" target="_blank" rel="noopener noreferrer" title="https://night.deno.dev/">https://night.deno.dev/</a> 来访问我使用 deno Deploy 所创建的一个在线项目。将会输出一个<code>Hello World!</code> 的页面。</p>
<p>提供一个免费的线上环境体验，对开发者而言尤为重要，尤其是在将自己的项目成果分享给他人展示时，成就感油然而生。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="node-转-deno-开发的一些帮助">node 转 deno 开发的一些帮助<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#node-%E8%BD%AC-deno-%E5%BC%80%E5%8F%91%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B8%AE%E5%8A%A9" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>deno 相关的亮点我也差不多介绍完了，也许你对 deno 已经有一丝兴趣想尝试一番，以下我整理的对你也许有所帮助。</p>
<ul>
<li>
<p>如果你是一个 Node 用户，考虑切换到 Deno，这里有一个<a href="https://link.juejin.cn/?target=https://deno.land/manual/node/cheatsheet" target="_blank" rel="noopener noreferrer" title="官方小抄">官方小抄</a>来帮助你。</p>
</li>
<li>
<p>如果你不想刷 deno 文档，想快速上手 deno 的话，这里我建议推荐看看 deno 官方所推荐的<a href="https://deno.land/manual@v1.29.4/examples" target="_blank" rel="noopener noreferrer" title="deno代码例子 ">deno 代码例子 </a>，能够非常快速有效了直接了解 deno 标准库以及依赖导入导出。</p>
</li>
<li>
<p>deno 是集成了 node 与 npm 的，也就是说允许直接使用 npm 包与 node 标准库，如果你想用 deno 来写 node，也行，详看<a href="https://deno.land/manual@v1.29.4/node#interoperating-with-nodejs-and-npm" target="_blank" rel="noopener noreferrer" title="Interoperating with Node.js and npm">Interoperating with Node.js and npm</a>。</p>
</li>
<li>
<p>想要在 deno 中连接数据库，可看<a href="https://deno.land/manual@v1.29.4/basics/connecting_to_databases#connecting-to-databases" target="_blank" rel="noopener noreferrer" title="Connecting to Databases">Connecting to Databases</a>。</p>
</li>
<li>
<p>如果想看 deno 如何使用 deno 生态的 Web 框架创建一个 Web 服务，推荐<a href="https://fresh.deno.dev/" target="_blank" rel="noopener noreferrer" title="fresh">fresh</a>框架，并查看该例子<span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/denoland/fresh/tree/main/examples/counter" target="_blank" rel="noopener noreferrer" title="fresh/examples/counter">fresh/examples/counter</a></span></p>
</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="node-火吗">node 火吗?<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#node-%E7%81%AB%E5%90%97" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>关于 deno 就暂且落下笔墨，不妨思考一个问题，node 火吗。</p>
<p>作为 node 开发者，我肯定会说 node 火，不过更多是对 javascript 来说火。</p>
<p>如今 typescript 大势所趋，说 javascript 就等同于说 typescript，而 javascript 和 node 绑定已成事实，而前端也与 javascript 所绑定，如今的前端工程师要是不会 node，都不好意思说自己是个前端工程师。就现阶段看，没了 nodejs，前端技术得倒退十年（不夸张）。</p>
<p>如果是在 Web 前端，Node 确实已经火的一塌糊涂了，然而它的诞生并不是为了 Web 前端，而是希望将 javascript 作为服务器端语言发展。只是后来没有想到的是 Node.js 在前端领域却大放异彩，造就了如今大前端的盛世。</p>
<p>所以在 Web 后端的领域，Node 确实是不温不火，更多的公司都宁可选主流的后端开发语言，而不是优先考虑 Node。不过倒是在 Serverless 领域中，Node 有着一席之地。</p>
<p>所以我想 deno 的出现，不仅是针对 Node.js 的缺陷，更是针对 Node.js 后端开发的不足。至于说 deno 能否完成原先 node 的使命，只有时间能给我们答案。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="总结">总结<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>从上述看来，你应该会发现 deno 并不和 node 一样是一个纯运行时环境。因为他不仅仅做了 javascript/typescript 运行时环境，还做了很多开发者好评的功能，一个为 javascript/typescript 提供更好的开发支持的产品。</p>
<p>但好评并不能直接决定销量，这些功能看似可有可无，没有激起用户从 Node.js 切换过来的杰出之处。就我体验完发现，好像 deno 能做的东西 node 大部分也能做，只是相对繁琐重复一些而已。<strong>但人们更倾向于做一件繁琐重复的事情，而不是做一个新的事情。</strong></p>
<p>扪心自问，我真的很希望 deno 能火，就开发体验而言，比 node 好用太多了，但好用的东西代表不了用的人就多，这个领域中，生态尤为重要。想要让 node 用户转到 deno 开发还有很长一段路要走。</p>
<p>再来反问自己，我现在会将 deno 作为 node 替代品吗，我想我和多数 node 开发者一样，都不会将 deno 作为主力语言(因为有很多项目都已经使用node来进行开发与推动)。但作为个人开发者，尤其是 node 开发者，我认为还是非常有必要去尝试一番 deno，亲手目睹"下一代Node"。</p>
<p>希望本文能对你了解 deno 有所帮助。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="相关推荐文章">相关推荐文章<a href="http://www.yanghao717.cn/en/blog/deno-is-not-only-a-javascript-runtime#%E7%9B%B8%E5%85%B3%E6%8E%A8%E8%8D%90%E6%96%87%E7%AB%A0" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p><a href="https://juejin.cn/post/7168383367602241550" target="_blank" rel="noopener noreferrer" title="Deno vs. Node.js哪个更好 - 掘金 (juejin.cn)">Deno vs. Node.js 哪个更好 - 掘金 (juejin.cn)</a></p>
<p><a href="https://juejin.cn/post/6956461134299955213" target="_blank" rel="noopener noreferrer" title="为什么 Deno 没有众望所归？超越 Node.js 还要做些什么？ - 掘金 (juejin.cn)">为什么 Deno 没有众望所归？超越 Node.js 还要做些什么？ - 掘金 (juejin.cn)</a></p>
<p><a href="https://www.zhihu.com/question/327534747" target="_blank" rel="noopener noreferrer" title="连发明人��都抛弃node.js了，还有前途吗？ - 知乎 (zhihu.com)">连发明人都抛弃 node.js 了，还有前途吗？ - 知乎 (zhihu.com)</a></p>
<p><a href="https://www.zhihu.com/question/517617266" target="_blank" rel="noopener noreferrer" title="已经 2022 年了 Deno 现在怎么样了? - 知乎 (zhihu.com)">已经 2022 年了 Deno 现在怎么样了? - 知乎 (zhihu.com)</a></p>]]></content:encoded>
            <category>deno</category>
            <category>node</category>
            <category>javascript</category>
            <category>typescript</category>
        </item>
        <item>
            <title><![CDATA[深谈个人对新技术的看法]]></title>
            <link>http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion</link>
            <guid>http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion</guid>
            <pubDate>Sat, 15 Oct 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[目前技术圈的发展速度可谓是有目共睹，尤其是前端，每隔一段时间就出新的技术，可以说让很多初学者非常畏惧，没有一个明确的方向不知道从何学起。]]></description>
            <content:encoded><![CDATA[<p>目前技术圈的发展速度可谓是有目共睹，尤其是前端，每隔一段时间就出新的技术，可以说让很多初学者非常畏惧，没有一个明确的方向不知道从何学起。</p>
<p>同时也有很多人，只局限于使用手头已掌握的技术，而不愿去尝试新技术。举个例子，如今 vue3 都已经正式发布，但仍还有停留在 vue2 不愿尝试 vue3 的开发者。而 java 都发布 18 版本了，可还有很多人都还使用着 java8，这种现象可以说是非常常见了。</p>
<p>这里说说我个人编码经验与看法，<strong>仅作为个人观点，没别的意思</strong>。</p>
<p>熟悉我的人应该都知道，我对很多新鲜的技术有一种难以用言语表达的情感，又哭又笑。属于是那种看到感兴趣的就会开始尝试，在之前也许更强烈。</p>
<p>驱使我去接触的原因无非就以下几点：</p>
<ul>
<li>开发体验、性能提升</li>
<li>对已有技术的厌倦感和对新鲜事物的好奇心</li>
<li>更多机会与方向</li>
<li>对未来技术趋势有更好的了解</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="写不完的代码">写不完的代码<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E5%86%99%E4%B8%8D%E5%AE%8C%E7%9A%84%E4%BB%A3%E7%A0%81" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>首先要知道一点，在任何的软件开发迭代中都没有最终形态的代码。说白话就是代码都是不断更新的，永远写不出最好的代码。</p>
<p>你能看到如今很多开源项目或者商业项目都在不断新增代码或者功能，除非作者不维护了，不然这份代码可以说写到世界末日。</p>
<p>究其原因还是因为社会不断在发展，硬件升级，性能提升，不断的业务需求。毕竟人都在进步，社会难道还不能进步。所以必然会有新的技术出现，只是出现的时间快慢，与技术难点突破。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="开发体验性能提升">开发体验、性能提升<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E5%BC%80%E5%8F%91%E4%BD%93%E9%AA%8C%E6%80%A7%E8%83%BD%E6%8F%90%E5%8D%87" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>毋庸置疑，在购买方面，肯定是买新不买旧，同样的在技术（软件更新）方面也是则从用新不用旧。驱使软件和框架更新的原因也就是新增了某些功能（特性），对用户（开发者）的体验有所提升。一般而言比较少的会存在反向更新的操作，这里除了某些国产软件~~（如某信，某 Q 等等）~~</p>
<p>就我对此的看法也是如此，假设一个开发工具启动花费了 5s 钟启动，而在它的最新版只需要 1s 钟就能够启动，你会选择更新尝试吗？。再比如一个框架原先的代码需要 10 行代码才能实现的功能，由于新版本提供一个语言级别的语法糖，使该功能只需一行。</p>
<p>并且我对开发体验非常在意，尤其是不好用，或者不好配置的东西，我基本秉持能不用就不用的原则，像 vue2 与 webpack 就是这样，我跟愿意使用 vue3 或 vite。诸如此类的替换有非常多，便不一一列举。</p>
<p>要我肯定毫不犹豫的更新去使用，但有些人可能对此提升不是很在意，又或者是升级的成本相对较高，也可能是因为这个开发工具（框架）他用的比较少，更新的意义自然就不大。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="对代码厌倦和对新事物的好奇心">对代码厌倦和对新事物的好奇心<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E5%AF%B9%E4%BB%A3%E7%A0%81%E5%8E%8C%E5%80%A6%E5%92%8C%E5%AF%B9%E6%96%B0%E4%BA%8B%E7%89%A9%E7%9A%84%E5%A5%BD%E5%A5%87%E5%BF%83" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>我写代码时常处于三分钟热度的状态，有些东西可能也就一开始的时候感觉比较新奇，然后就不了了之了。我对此的看法主要还是容易对代码产生厌倦感，不想写代码，不愿意学习。当厌倦感产生了，自然而然就放弃编写，也就是三分钟热度的状态。不过也能侧重体验一点，那就是肯定我对此不是那么感兴趣，既然不是那么感兴趣的东西，又何必在写下去呢？</p>
<p>接着过段时间又遇到了一个新的技术，冲击了我的好奇心，开始尝试。 如此重复，就会发现啥都学了一点，但实际是啥都没学到。但至少，让我肯去学习，而不是在原地踏步。而从心底里就想接触的新鲜事物，每次接触到就能满足自己内心的好奇心，就这一点我便知足了。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="重构的艺术">重构的艺术<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E9%87%8D%E6%9E%84%E7%9A%84%E8%89%BA%E6%9C%AF" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>如果回头看看自己 1，2 年前写的代码，会发现原来自己也曾写过丑陋不堪的代码，也成为过自己所讨厌的样子。如果这份代码我将来还会用到，那么我就尝试去重构，也许在当时还不支持某种特性，代码就无法简化。基于现有的水平，便会发现很多代码都有可改善的地方，可以化繁为简。代码重构属于将杂乱摆放的东西，收拾的整整齐齐的样子。重构是在提升观赏度和舒适度的同时，还减少 bug 的诱发概率。</p>
<blockquote>
<p>在编程语言级别水平上，也就是我为什么会想去使用最新的版本（ES2022，TypeScript 4.9），即便是兼容性的问题，我也会去使用，就是因为能够满足我对代码的舒适度，这便足以。</p>
</blockquote>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="生态与解决问题方面">生态与解决问题方面<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E7%94%9F%E6%80%81%E4%B8%8E%E8%A7%A3%E5%86%B3%E9%97%AE%E9%A2%98%E6%96%B9%E9%9D%A2" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>我是很感谢新技术的出现，他实实在在的解决了一些我已有的痛点，提升了我的开发体验。当然它也让我踩了无数的坑，也折磨过我。但不可否认的是，我的自我解决问题的能力也在不断提升，如果我学的是一门比较流行的技术，那么我所遇到的问题，很有可能别人也遇到过，并将他的解决方案分享出来。而我就很容易根据报错描述找他的解决方案来解决我的问题。但在新技术下，用的人自然而然就少了，所分享的问题解决方案也就少了，所以在这种环境下，我就需要自行翻看源码，查阅文档，提出 issues 才能够解决问题。自然而然解决问题的能力也就有所提升。</p>
<p>像流行框架能有这么有问题解决方案，就是因为强大的生态，同时这也是生态好处之一。</p>
<blockquote>
<p>因此也有很多人顾忌使用新技术，就是因为遇到问题不知如何解决。包括我也是，但通常我会观察一段时间，等成熟了我才去尝试，而不是直接上手，避免踩一些不必要且耗时的坑。</p>
</blockquote>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="总是活在舒适圈">总是活在舒适圈<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E6%80%BB%E6%98%AF%E6%B4%BB%E5%9C%A8%E8%88%92%E9%80%82%E5%9C%88" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>在圈内有着熟悉的环境，与认识的人相处，做自己会做的事，所以会感到很轻松、很自在。但是当踏出这个圈子的界限的时候，就马上会面对不熟悉的变化与挑战，因而感到不舒适，很自然的想要退回到舒适圈内。</p>
<p>我在阅读英文博客的时候，我也时常感到不舒适，阅读不下去。我也很想回到舒适圈，使用翻译软件来翻译但是这样就会导致我非常依赖翻译软件，就间接失去了一次英文环境与英语能力的提升。</p>
<p>长时间待在舒适圈，会让自己过得很舒服，但是却很难提升自己。不过想想也是，<strong>提升的过程不就是苦尽甘来</strong>。</p>
<p>以目前来看有一种这样的学习趋势，别人学什么，当下什么技术火，就去学什么。我其实特别反感这种现象，也不推崇这种学习理念。我会做出我的解释：</p>
<p>首先，什么技术会火就学什么，这固然没什么问题，如果一门技术没有热度，没有生态，那么学了的意义不大，一是难有长久稳定的技术发展，二是不能将技术变现。而绝大多数人之所以选择火的技术，有很大一点是因为有前人给他铺了很多“路”，如学习指南，思维导图，视频教程仿佛跟着学就能成为编程大牛似的。可一旦没有这些，就不知道该如何下手。始终都是跟着别人步伐学习，思维很难扩散出去。</p>
<p>并且这种现象必然会导致内卷，首先看看国内的技术，Vue 和 Spring boot 的可以说 10 个 web 开发程序员中有 8 个技术栈是这套，比麻花还是卷了，可薪资呢？</p>
<p>这里我并不想贴相关的薪资图片，你完全可以自行去了解，但是我可以肯定且直接告诉你，React 的薪资普遍会比 Vue 高上一截，而 Java 后端开发，如果技术只停留在 CRUD 的层面，工资普遍也高不了多少。</p>
<p><strong>如果你不去拓展自身的技术栈，不多去了解一些未来的可能会火的技术，还停留在当下，活在舒适圈。那么薪资大概率不变，并且自身会有很大被劝退的概率。</strong></p>
<p>与时俱进，这是我认为不断学习新技术，提升自身技术栈，非常重要的一点。<strong>过得舒服，反而过得难受</strong></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="更多的机会与方向">更多的机会与方向<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E6%9B%B4%E5%A4%9A%E7%9A%84%E6%9C%BA%E4%BC%9A%E4%B8%8E%E6%96%B9%E5%90%91" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>技术更新迭代越来，也带来越多的机会，这对于接触前端的我感到尤为明显。假设当下又出了某某技术，那么必然会引起软件开发者的关注，于此同时就带来了维护者，贡献者，甚至是一些金主投资商。像 <a href="https://tailwindcss.com/" target="_blank" rel="noopener noreferrer">Tailwind CSS</a> 与 <a href="https://vercel.com/" target="_blank" rel="noopener noreferrer">Vercel</a> 就是一个很好的例子，两个前端明星项目，有兴趣可以了解它们的故事。</p>
<p><strong>不过这种机会在国内不太多见，反而在国外特别普遍。</strong></p>
<p>但必须要承认的一个事实，如今技术发展过于迅猛，加上目前就业行情不容乐观，当别人了解过的东西，你却不了解，那么别人所能遇到的机会自然就比你多。说的难听点也就是没有对技术提升的想法，今后项目迭代的过程中使用到一些前沿技术就难以胜任。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="没有目标的学习等同于乱学">没有目标的学习，等同于乱学<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E6%B2%A1%E6%9C%89%E7%9B%AE%E6%A0%87%E7%9A%84%E5%AD%A6%E4%B9%A0%E7%AD%89%E5%90%8C%E4%BA%8E%E4%B9%B1%E5%AD%A6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p><strong>没有一个明确的目标，学任何（新）技术都是乱学，充其量也就只比不学好一点。</strong></p>
<p>这在我初学阶段尤为明显，我一开始也不清楚我以后会从事什么行业，可以说是什么都乱学一顿。在我的一篇年终总结 <a href="http://www.yanghao717.cn/en/blog/2020-year-end-summary">2019.7-2020.7 编程年记</a> 中可以说是尤为明显，尤其是在 <a href="http://www.yanghao717.cn/en/blog/2020-year-end-summary#%E5%AE%9A%E4%B8%80%E4%B8%8B%E6%98%8E%E5%B9%B4%E7%9A%84%E7%9B%AE%E6%A0%87">定一下明年的目标</a> 的段落中，最后我真正深入学习的也就是只有 Web 开发。</p>
<p>我相信很多初学者也会遇到类似的问题，不知道学什么，想学好找工作的但是薪资不高，想学感兴趣的但又不知如何下手。说实话，要我回到当初，我也难以抉择。也有可能处于摆烂状态或是乱学一同，到头来啥都会一点点，但是又好像啥也不会的样子。</p>
<p>这里我是奉劝先定一个短期的目标，为了这个目标我要去学习哪些技术知识。这里就说我未来一年的目标为例：我未来一年想写开源项目，为开源社区做一份微薄贡献，乃至从事开源行业。那么我就需要了解写开源我需要那些预备知识，例如 Github 的使用，项目规范，英文交流等对应开源项目的技能知识，这才是我所该学的，并且能够实实在在用到的，且对我未来有用的。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="对未来技术趋势有更好的了解">对未来技术趋势有更好的了解<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E5%AF%B9%E6%9C%AA%E6%9D%A5%E6%8A%80%E6%9C%AF%E8%B6%8B%E5%8A%BF%E6%9C%89%E6%9B%B4%E5%A5%BD%E7%9A%84%E4%BA%86%E8%A7%A3" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>**当你了解的技术越多，你就越能知道自己适合哪些技术。**并且当你去尝试过后，更能加深你对某个技术的信仰。</p>
<p>在未来技术只会越来越多，因为当下要解决太多问题，有太多的业务需求开发。只要不断有需求，就不断会有技术更新。但技术更新必然是朝着好的方向去发展，即技术趋势方向。而了解的越多，能看到技术趋势也就更远，方向就更难偏移。</p>
<p>像我目前就比较看好未来 js/ts 的发展，这也是使我从逆向和爬虫转到 Web 开发行业上，并且将会长期发展下去。</p>
<p>但很多程序员就缺乏这种对<strong>技术的认可</strong>，甚至眼光比较浅薄，认为自己当下所学的就足以，可没却从未到真正的”外面”去看过。</p>
<p>当有了对未来技术趋势的了解，自身就有相对明确的目标学习，而不是漫无目的学习，跟风学习。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="我是如何了解到这些技术的">我是如何了解到这些技术的？<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E6%88%91%E6%98%AF%E5%A6%82%E4%BD%95%E4%BA%86%E8%A7%A3%E5%88%B0%E8%BF%99%E4%BA%9B%E6%8A%80%E6%9C%AF%E7%9A%84" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>也许有些人并不在意新技术是否学习，而是好奇我是如何知道这些技术的。这个问题非常好，我自己简单总结通过那些途径来获取到这些相关技术的新闻。</p>
<p>主要有以下几种来源：</p>
<ul>
<li>多加技术群，不定时看群聊</li>
<li><strong>多刷技术大佬文章（推特），或者是技术公众号和掘金（最多的也是最有效的）</strong></li>
<li>订阅一些技术周刊，或订阅某个项目</li>
</ul>
<p>没啥技巧，就靠刷技术文章，自然而然的了解也就越来越多了。</p>
<p>尤其是第二点，也是我了解这些新技术的最直接途径。与其自己去主动了解新的技术，将刷抖音的时间改成刷技术文章，了解新技术就是分分钟的事情。可以说我写博客是因为这个契机，记录自己用到的技术的开发过程，并分享个人的开发体验，让更多人了解到这些新技术。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="面对新技术该怎么学">面对新技术该怎么学？<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E9%9D%A2%E5%AF%B9%E6%96%B0%E6%8A%80%E6%9C%AF%E8%AF%A5%E6%80%8E%E4%B9%88%E5%AD%A6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>其实更多时候是比较在意如何去学一门新技术，而不是找一门新技术，当阅历多了，技术自然就了解的多。这里我分享下我对于新技术是如何起步与学习的。</p>
<p>首先我会列举出我近期感兴趣的技术，这一步很关键，我当然不可能每个技术都去尝试一遍，时间精力根本不够。通常在我了解到这个技术的时候，比如文章与视频中，都会介绍到这个的优点与用法，这就足以了。</p>
<p>但想要进一步的学习，还是得依靠实战项目（至少我都是通过实战项目来学习的），这时候我会看看手头的项目，看看有没有能够基于上面所列举出的新技术升级的想法，如果有的话，那正好就当重构与新技术的学习，这是最好的，也是相对比较节省时间的。</p>
<p>但如果没有的话，我通常是会考虑另写一个项目，而这个项目可能是某个灵感的实现，也可能是久违想写的项目，或者是复刻某个感兴趣的站点，总之从上面所列举出来的技术中去选择一个来进行实践。在项目实践中去尝试使用这些新技术，哪怕只是实现一个简单的 demo，也总比单纯的刷文档，看代码来的有效。</p>
<p><strong>在项目实践中学习，永远是最直接也是最有效的</strong>。回想你编写课设或者工作的项目，是不是在项目开发中进步的最快？如果这时候还有点时间紧迫感，进步反而会更快。（当然焦虑和压力也会随之提升）</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="最后感悟">最后感悟<a href="http://www.yanghao717.cn/en/blog/talk-new-technologies-opinion#%E6%9C%80%E5%90%8E%E6%84%9F%E6%82%9F" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>关于本文，必然有引来一些不同看法与见解，每个人都有对不同事物的理解，我只是将我对新技术的看法，以文章的方式输出出来。本文并未带有任何的技术的偏见，我对任何技术都保持一视同仁，并且愿意去尝试学习。</p>
<p>不必抱怨新技术发展的过快，自己来不及学，学不完。或者担心自己学的东西在未来将会淘汰，等同于白学。学习过程就是一个非常好的经验总结，当你回顾整个学习过程，其实都没有白学。反而多一次的学习过程，在未来学习新的东西时，学习的成效也会显著提升。保持不断学习，就永远来的及学习。</p>
<p>更多时候，不应该只学如何使用，而是该想想这东西是在什么样的契机下如何被创造出来的，解决了什么问题。而这个问题在未来有没有什么更好的解决方案可替代，如果有更好的解决方案，那么必将又将发展出新的技术来更好的解决这个问题。这在我曾经的学习中，我是从未考虑到的，只专注于学习，而没去了解为什么。</p>
<p>我是希望越来越多的新技术出现，无论它是为了解决什么，必然能解决某些人的一些需求，那么它的出现就很有意义。至于未来该技术和相关生态发展如何，不得而知。也没人敢笃定未来这个技术必定会火，就去学这门技术。绝大大多情况下都是比较看好这门技术，认为未来可期，同时又感兴趣，就开始学习并使用。</p>]]></content:encoded>
            <category>杂谈</category>
        </item>
        <item>
            <title><![CDATA[一位未曾涉足算法的初学者收获]]></title>
            <link>http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte</link>
            <guid>http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte</guid>
            <pubDate>Fri, 16 Sep 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[正如标题所言，在我四年的编程经历中就没刷过一道算法题，这可能与我所编写的应用有关，算法对我而言提升不是特别大。加上我几乎都是在需求中学习，而非系统性的学习。所以像算法这种基础知识我自然就不是很熟悉。]]></description>
            <content:encoded><![CDATA[<p>正如标题所言，在我四年的编程经历中就没刷过一道算法题，这可能与我所编写的应用有关，算法对我而言提升不是特别大。加上我几乎都是<strong>在需求中学习，而非系统性的学习</strong>。所以像算法这种基础知识我自然就不是很熟悉。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="那我为何会接触算法呢">那我为何会接触算法呢？<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E9%82%A3%E6%88%91%E4%B8%BA%E4%BD%95%E4%BC%9A%E6%8E%A5%E8%A7%A6%E7%AE%97%E6%B3%95%E5%91%A2" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>我在今年暑假期间有一个面试，当时面试官想考察下我的算法能力，而我直接明摆了说我不行（指算法上的不行），但面试官还是想继续考察，于是就出了道斐波那契数列作为考题。</p>
<p>但我毕竟也接触了 4 年的代码，虽说不刷算法，但起码也看过许多文章和代码，斐波那契数列使用递归实现的代码也有印象，于是很快我就写出了下面的代码作为我的答案。</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> n</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>面试官问我还有没有更好的答案，我便摇了摇头表示这 5 行不到的代码难道不是最优解？</p>
<blockquote>
<p>事实上这份代码看起来很简洁，实际却是耗时最慢的解法</p>
</blockquote>
<p>毫无疑问，在算法这关我肯定是挂了的，不过好在项目经验及后续的项目实践考核较为顺利，不然结局就是回去等通知了。最后面试接近尾声时，面试官友情提醒我加强基础知识（算法），强调各种应用框架不断更新迭代，但计算机的底层基础知识是不变的。于是在面试官的建议下，便有了本文。</p>
<p>好吧，我承认我是为了面试才去学算法的。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="对上述代码进行优化">对上述代码进行优化<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E5%AF%B9%E4%B8%8A%E8%BF%B0%E4%BB%A3%E7%A0%81%E8%BF%9B%E8%A1%8C%E4%BC%98%E5%8C%96" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>在介绍我是从何处学习算法以及从中学到了什么，不妨先来看看上题的最优答案是什么。</p>
<p>对于有接触过算法的同学而言，不难看出时间复杂度为 O(n²)，而指数阶属于爆炸式增长，当 n 非常大时执行效果缓慢，且可能会出现函数调用堆栈溢出。</p>
<p>如果仔细观察一下，会发现这其中进行了非常多的重复计算，我们不妨将设置一个 res 变量来输出一下结果</p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> n</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> res </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> res</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>当 n=7 时，所输出的结果如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/202309162220346.png" alt="Untitled" class="img_ev3q"></p>
<p>这还只是在 n=7 的情况下，便有这么多输出结果。而在算法中要避免的就是重复计算，这能够高效的节省执行时间，因此不妨定义一个缓存变量，在递归时将缓存变量也传递进去，如果缓存变量中存在则说明已计算过，直接返回计算结果即可。</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> mem </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> n</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">mem</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> mem</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> res </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> mem</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> mem</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  mem</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> res</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> res</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>此时所输出的结果可以很明显的发现没有过多的重复计算，执行时间也有显著降低。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/202309162220348.png" alt="Untitled" class="img_ev3q"></p>
<p>这便是<strong>记忆化搜索</strong>，时间复杂度被优化至 O(n)。</p>
<p>可这还是免不了递归调用出现堆栈溢出的情况（如 n=10000 时）。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/202309162220349.png" alt="Untitled" class="img_ev3q"></p>
<p>从上面的解法来看，都是从”<strong>从顶至底</strong>”，比方说 n=7，会先求得 n=6 的结果, 而 n=6 又要求得 n=5 的结果，依次类推直至得到底层 n=1 的结果。</p>
<p>事实上我们可以换一种思路，先求得 n=1，n=2 的结果，然后依次类推上去，最终得到 n=6，n=7 的结果，也就是“<strong>从底至顶”</strong>，而这就是<strong>动态规划</strong>的方法。</p>
<p>从代码上来分析，因此我们可以初始化一个 dp 数组，用于存放数据状态。</p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fib</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> dp </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;=</span><span class="token plain"> n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i</span><span class="token operator" style="color:hsl(207, 82%, 66%)">++</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    dp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> dp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> dp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">2</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> dp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>最终 dp 数组的最后一个成员便是原问题的解。此时输出 dp 数组结果。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/202309162220350.png" alt="Untitled" class="img_ev3q"></p>
<p>且由于不存在递归调用，因此你当 n=10000 时也不在会出现堆栈溢出的情况（只不过最终的结果必定超出了 JS 数值可表示范围，所以只会输出 Infinity）</p>
<p>对于上述代码而言，在空间复杂度上能够从 O(n) 优化到 O(1)，至于实现可以参考 <a href="https://www.hello-algo.com/chapter_dynamic_programming/intro_to_dynamic_programming#1414" target="_blank" rel="noopener noreferrer">空间优化</a>，这里便不再赘述。</p>
<p>我想至少从这里你就能看出算法的魅力所在，<strong>这里我强烈推荐 <a href="https://www.hello-algo.com/" target="_blank" rel="noopener noreferrer">hello-algo</a> 这本数据结构与算法入门书</strong>，我的算法之旅的起点便是从这本书开始，同时激发起我对算法的兴趣。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="两数之和">两数之和<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>于是在看完了这本算法书后，我便打开了大名鼎鼎的刷题网站 <a href="https://leetcode.cn/" target="_blank" rel="noopener noreferrer">LeetCode</a>，同时打开了究极经典题目的<a href="https://leetcode.cn/problems/two-sum" target="_blank" rel="noopener noreferrer">两数之和</a>。</p>
<blockquote>
<p>有人相爱，有人夜里开车看海，有人 leetcode 第一题都做不出来。</p>
</blockquote>
<p>题干：</p>
<blockquote>
<p>给定一个整数数组 <code>nums</code>&nbsp; 和一个整数目标值 <code>target</code>，请你在该数组中找出和为目标值 <code>target</code> 的那 <strong>两个</strong> 整数，并返回它们的数组下标。</p>
<p>你可以假设每种输入只会对应一个答案。但是，数组中同一个元素在答案里不能重复出现。</p>
<p>你可以按任意顺序返回答案。</p>
</blockquote>
<p>以下代码将会采用 JavaScript 代码作为演示。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="暴力枚举">暴力枚举<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E6%9A%B4%E5%8A%9B%E6%9E%9A%E4%B8%BE" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>我初次接触该题也只会暴力解法，遇事不决，暴力解决。也很验证了那句话：不论多久过去，我首先还是想到两个 for。</p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">var</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">twoSum</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> n </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">length</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i</span><span class="token operator" style="color:hsl(207, 82%, 66%)">++</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> j </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> j </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> n</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> j</span><span class="token operator" style="color:hsl(207, 82%, 66%)">++</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">j</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">===</span><span class="token plain"> target </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;&amp;</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!==</span><span class="token plain"> j</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> j</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>当然针对上述 for 循环优化部分，比如说让 <code>j = i + 1</code> ，这样就可以有效避免重复数字的循环以及 <code>i ≠ j</code> 的判断。由于用到了两次循环，很显然时间复杂度为 O(n²)，并不高效。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="哈希表">哈希表<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E5%93%88%E5%B8%8C%E8%A1%A8" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>我们不妨将每个数字通过 hash 表缓存起来，将值 <code>nums[i]</code> 作为 key，将 <code>i</code> 作为 value。由于题目的条件则是 <code>x + y = target</code>，也就是 <code>target - x = y</code>，这样判断的条件就可以由 <code>nums[i]+ nums[j] === target</code> 变为 <code>map.has(target - nums[i])</code> 。如果 map 表中有 y 索引，那么显然 <code>target - nums[i] = y</code>，取出 y 的索引以及当前 i 索引就能够得到答案。代码如下</p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">var</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">twoSum</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> map </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Map</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i</span><span class="token operator" style="color:hsl(207, 82%, 66%)">++</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">map</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">has</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">target </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">map</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">target </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    map</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">set</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>而这样由于只有一次循环，时间复杂度为 O(N)。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="双指针算法特殊情况">双指针算法(特殊情况)<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E5%8F%8C%E6%8C%87%E9%92%88%E7%AE%97%E6%B3%95%E7%89%B9%E6%AE%8A%E6%83%85%E5%86%B5" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>假如理想情况下，题目所给定的 nums 是<strong>有序的情况</strong>，那么就可以考虑使用双指针解法。先说原理，假设给定的 nums 为 <code>[2,3,5,6,8]</code>，而目标的解为 9。在上面的做法中都是从索引 0 开始枚举，也就是 2,3,5…依次类推，如果没找到与 2 相加的元素则从 3 开始 3,5,6…依次类推。</p>
<p>此时我们不妨从<strong>最小的数</strong>和<strong>最大的数</strong>开始，在这个例子中也就是 2 和 8，很显然 <code>2 + 8 &gt; 9</code>，说明什么？说明 8 和中间所有数都大于 9 即 3+8 ，5+8 肯定都大于 9，所以 8 的下标必然不是最终结果，那么我们就可以把 8 排除，从 <code>[2,3,5,6]</code> 中找出结果，同样的从最小和最大的数开始，<code>2 + 6 &lt; 9</code> ，这又说明什么？说明 2 和中间这些数相加肯定都下雨 9 即 2+3，2+5 肯定都小于 9，因此 2 也应该排除，然后从 <code>[3,5,6]</code> 中找出结果。就这样依次类推，直到找到最终两个数 <code>3 + 6 = 9</code>，返回 3 与 6 的下标即可。</p>
<p>由于此解法相当于有两个坐标(指针)不断地向中间移动，因此这种解法也叫<strong>双指针算法</strong>。当然，要使用该方式的前提是输入的<strong>数组有序</strong>，否则无法使用。</p>
<p>用代码的方式来实现：</p>
<ol>
<li>定义两个坐标(指针)分别指向数组成员最左边与最右边，命名为 left 与 right。</li>
<li>使用 while 循环，循环条件为 left &lt; right。</li>
<li>判断 <code>nums[left] + nums[right]</code> 与 <code>target</code> 的大小关系，如果相等则说明找到目标(答案)，如果大于则 右指针减 1 <code>right—-</code>，小于则左指针加 1 <code>left++</code>。</li>
</ol>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">twoSum</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> right </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">while</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> right</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> sum </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">left</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> nums</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">right</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sum </span><span class="token operator" style="color:hsl(207, 82%, 66%)">===</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">left</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> right</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sum </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      right</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">sum </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> target</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      left</span><span class="token operator" style="color:hsl(207, 82%, 66%)">++</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<hr>
<p>针对上述两道算法题浅浅的做个分享，毕竟我还只是一名初入算法的小白。对我而言，我的算法刷题之旅还有很长的一段时间。且看样子这条路可能不会太平坦。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="算法对我有用吗">算法对我有用吗？<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E7%AE%97%E6%B3%95%E5%AF%B9%E6%88%91%E6%9C%89%E7%94%A8%E5%90%97" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>在我刷算法之前，我在网上看到鼓吹算法无用论的人，也能看到学算法却不知如何应用的人。</p>
<p>这也不禁让我思考 🤔，算法对我所开发的应用是否真的有用呢？</p>
<p>在我的开发过程中，往往面临着各种功能需求，而通常情况下我会以尽可能快的速度去实现该功能，至于说这个功能耗时 1ms，还是 100 ms，并不在乎。因为对我来说，这种微小的速度变化并不会被感知到，或者说绝大多数情况下，处理的数据规模都处在 n = 1 的情况下，此时我们还会在意 n² 大还是 2ⁿ 大吗？</p>
<p>但如果说到了用户感知到卡顿的情况下，那么此时才会关注性能优化，否则，过度的优化可能会成为一种徒劳的努力。</p>
<p>或许正是因为我都没有用到算法解决实际问题的经历，所以很难说服自己算法对我的工作有多大帮助。但不可否认的是，算法对我当前而言是一种思维上的拓宽。让我意识到一道（实际）问题的解法通常不只有一种，如何规划设计出一个高效的解决方案才是值得我们思考的地方。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="结语">结语<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E7%BB%93%E8%AF%AD" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>借 MIT 教授 Erik Demaine 的一句话</p>
<blockquote>
<p>If you want to become a good programmer, you can spend 10 years programming, or spend 2 years programming and learning algorithms.</p>
</blockquote>
<p>如果你想成为一名优秀的程序员，你可以花 10 年时间编程，或者花 2 年时间编程和学习算法。</p>
<p>这或许就是学习算法的真正意义。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="参考文章">参考文章<a href="http://www.yanghao717.cn/en/blog/discoveries-of-an-algorithm-neophyte#%E5%8F%82%E8%80%83%E6%96%87%E7%AB%A0" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p><a href="https://www.hello-algo.com/chapter_dynamic_programming/intro_to_dynamic_programming" target="_blank" rel="noopener noreferrer">初探动态规划</a></p>
<p><a href="https://www.zhihu.com/question/335097718" target="_blank" rel="noopener noreferrer">学习算法重要吗?</a></p>]]></content:encoded>
            <category>算法</category>
        </item>
        <item>
            <title><![CDATA[Next.js项目搭建与部署]]></title>
            <link>http://www.yanghao717.cn/en/blog/next.js-build-and-deploy</link>
            <guid>http://www.yanghao717.cn/en/blog/next.js-build-and-deploy</guid>
            <pubDate>Wed, 13 Jul 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[官方文档 Getting Started | Next.js (nextjs.org)]]></description>
            <content:encoded><![CDATA[<p>官方文档 <a href="https://nextjs.org/docs/getting-started" target="_blank" rel="noopener noreferrer">Getting Started | Next.js (nextjs.org)</a></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="安装"><a href="https://nextjs.org/docs/getting-started#automatic-setup" target="_blank" rel="noopener noreferrer">安装</a><a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#%E5%AE%89%E8%A3%85" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">npx create-next-app@latest </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># or</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">yarn</span><span class="token plain"> create next-app </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--typescript</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># or</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">pnpm</span><span class="token plain"> create next-app </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--ts</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>运行</p>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">npm run dev</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>访问 <a href="http://localhost:3000/" target="_blank" rel="noopener noreferrer">http://localhost:3000</a></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="项目结构">项目结构<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220712030637300.png" alt="image-20220712030637300" class="img_ev3q"></p>
<table><thead><tr><th>文件</th><th>内容</th></tr></thead><tbody><tr><td>pages</td><td>页面文件</td></tr><tr><td>pages/api</td><td>api 数据接口</td></tr><tr><td>public</td><td>静态资源文件</td></tr><tr><td>styles</td><td>样式文件</td></tr><tr><td>next-env.d.ts</td><td>确保 typescript 支持</td></tr><tr><td>next.config.ts</td><td>next 配置文件</td></tr></tbody></table>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="路由">路由<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#%E8%B7%AF%E7%94%B1" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>nextjs 有一个基于页面概念的文件系统路由器，存放在 pages 下<code>.js</code>, <code>.jsx</code>, <code>.ts</code>, <code>.tsx</code> 文件都将作为组件，即<strong>文件路径 → 页面路由</strong>，例如这里的 index.tsx 映射为 index，<code>pages/about.js</code> 将映射为 <code>/about</code>。</p>
<p>同时还支持动态路由，创建<code>pages/user/[id].tsx</code>文件，然后访问<code>user/1</code>，<code>user/2</code></p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">[id].tsx<span style="flex:1;text-align:right">tsx</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token imports"> useRouter </span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'next/router'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">User</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> router </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">useRouter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> router</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">query</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text">User id:</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain-text"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">User</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>此时访问 <a href="http://localhost:3000/user/1" target="_blank" rel="noopener noreferrer">http://localhost:3000/user/1</a> 便可得到 <code>User ID: 1</code></p>
<p>在 router 对象下没有 param 属性，都是存放在 query 参数中，例如访问 user/1?username=night，此时的 query 值为 <code>{username: 'night', id: '2'}</code></p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_BuS1"><p>不过这里有个比较有意思的点，如果你在上方代码中使用 console.log 打印 query 的话，在 vscode 中会打印出空对象<code>{}</code>，而在浏览器中会打印一次空对象，一次真实的 query 对象（并且打印两遍）</p><p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220712191356587.png" alt="image-20220712191356587" class="img_ev3q"></p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="数据渲染">数据渲染<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#%E6%95%B0%E6%8D%AE%E6%B8%B2%E6%9F%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>如果你打开控制台，查看所返回的页面，你会发现响应中只有 User id:，这不就和 react 的 CSR(客户端)渲染没有区别吗，是的，确实是这样。因为上一部分的代码，并且从输出 query 也可以看的出来而不是 SSR(服务端)渲染。首先我要展示一下两者渲染的代码</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="csr-客户端渲染">CSR 客户端渲染<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#csr-%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%B8%B2%E6%9F%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">[id].tsx<span style="flex:1;text-align:right">tsx</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token imports"> useEffect</span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token imports"> useState </span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'react'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token imports"> useRouter </span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'next/router'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">User</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> router </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">useRouter</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> router</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">query</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> setData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">useState</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    username</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">''</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    email</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">''</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">useEffect</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function" style="color:hsl(207, 82%, 66%)">fetch</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">https://jsonplaceholder.typicode.com/users/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">${</span><span class="token template-string interpolation">id</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">then</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">res </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">then</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token function" style="color:hsl(207, 82%, 66%)">setData</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">catch</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">err </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text">username:</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain-text"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text">email:</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">email</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain-text"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">User</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>经常写 react 的肯定对上面的代码不陌生，前端向后端发送数据请求，接受到数据后赋值给 data，然后渲染出来。因为请求数据是需要耗时的，所以在页面显示完之后，会停顿一会在显示出数据（主要是我这边没写 loadding），并且由于 id 并不是第一时间获取到的（从上面的 id）。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220712193009186.png" alt="image-20220712193009186" class="img_ev3q"></p>
<p>从这里来看，客户端渲染不仅要获取页面组件，还要请求数据，最终再通过 js 渲染出来</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="ssr-服务端渲染">SSR 服务端渲染<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#ssr-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>next 中服务端渲染需要用到 getServerSideProps 函数，而后端的数据获取都是在该函数内来获取，并通过 prop 传入给前端组件中，来看实际代码</p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">[id].tsx<span style="flex:1;text-align:right">tsx</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">User</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> data </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">any</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text">username:</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain-text"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text">email:</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">email</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain-text"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">getServerSideProps</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">context</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> query</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">any</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">query</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 这里context.param也能获取到id</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> res </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fetch</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">https://jsonplaceholder.typicode.com/users/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">${</span><span class="token template-string interpolation">id</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> data </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    props</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>如果从页面显示来看，确实没什么区别，但如果打开控制台就能发现诸多不同。</p>
<p>首先就是请求的页面，是直接包含数据，相当于返回你一个页面，而在客户端渲染则是返回一个组件，需要自己去请求数据来展示。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220712192713634.png" alt="image-20220712192713634" class="img_ev3q"></p>
<p>同时查看控制台中的 Fetch/XHR 的是看不到请求的数据，因为这些数据并不是由前端发送的,而是由后端发送的（故不受跨域请求的限制）。</p>
<p>从这就能看出客户端渲染与服务端渲染的的区别了。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="ssg-静态生成">SSG 静态生成<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#ssg-%E9%9D%99%E6%80%81%E7%94%9F%E6%88%90" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>不过还没完，还有一个静态生成，先来看看代码。</p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">[id].tsx<span style="flex:1;text-align:right">tsx</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">User</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> data </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">any</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text">username:</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain-text"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text">email:</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">email</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain-text"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">p</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">getStaticProps</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">context</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> params</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">any</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">params</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> res </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">fetch</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">https://jsonplaceholder.typicode.com/users/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">${</span><span class="token template-string interpolation">id</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> data </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">await</span><span class="token plain"> res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    props</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">async</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">getStaticPaths</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    paths</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token class-name builtin" style="color:hsl(95, 38%, 62%)">Array</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">20</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">fill</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">map</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">a</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> params</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token known-class-name class-name" style="color:hsl(29, 54%, 61%)">String</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    fallback</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'blocking'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>主要是 getServerSideProps 替换成 getStaticProps，同时增加了一个 getStaticPaths 用于生成静态页面的，而上面的 getStaticPaths 表示生成 id 1 到 20 的页面，那假设如果我访问 id 为 21 的 user 呢？由于这里设置<code>fallback: 'blocking'</code>，所以还是会走服务端渲染的那一部分。但如果设置<code>fallback: fasle</code>，访问 user/21 就会提示 404。</p>
<p>通俗点来说就就是生成一系列静态页面，不需要服务端处理，所以返回的速度更快，其缺点其实也比较明显，数据的任何更改都需要在服务端重新构建，而服务端渲染则是可以动态处理数据，不需要完全重建。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="isr-增量式静态生成">ISR 增量式静态生成<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#isr-%E5%A2%9E%E9%87%8F%E5%BC%8F%E9%9D%99%E6%80%81%E7%94%9F%E6%88%90" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>不做过多介绍，详看文档 <a href="https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration" target="_blank" rel="noopener noreferrer">Data Fetching: Incremental Static Regeneration | Next.js (nextjs.org)</a></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="api-接口">api 接口<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#api-%E6%8E%A5%E5%8F%A3" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>上面的数据都是调用 <a href="http://jsonplaceholder.typicode.com/" target="_blank" rel="noopener noreferrer">JSONPlaceholder</a> 所提供的虚拟数据，在 next 中要提供数据接口的话，只需要在 pages/api 下编写即可，生成的路由规则和组件一样。例如 pages/api/hello.ts 映射为 api/hello，浏览器访问<a href="http://localhost:3000/api/hello" target="_blank" rel="noopener noreferrer">http://localhost:3000/api/hello</a> 就可以得到<code>{"name": "John Doe"}</code></p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">hello.ts<span style="flex:1;text-align:right">tsx</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">NextApiRequest</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">NextApiResponse</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'next'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Data</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">string</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">handler</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">NextApiRequest</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> res</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">NextApiResponse</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">Data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">200</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> name</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'John Doe'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>这里的 req、res 就是同大部分 node 后端框架一样，而这里的写法与 serverless 一致（这里应该就是 serverless）。</p>
<p>上述是 get 请求，那 post 请求呢？无论什么 http 请求方法都将在 handler 处理，通过 req.method 来获取请求方法，要区分的话可以通过如下代码。</p>
<div class="language-tsx codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tsx codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">handler</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">method</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">===</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'POST'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Process a POST request</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Handle any other HTTP method</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="写一个简单的-crud">写一个简单的 CRUD<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#%E5%86%99%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84-crud" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>既然知道了上述的一些作用，不妨来个熟悉的 CRUD。这里以文章 post 为例</p>
<p>这里数据端使用的时 sqlite，配置不做展示，只展示主要核心功能</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">api/post/index.ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> NextApiRequest</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> NextApiResponse </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'next'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> db </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'../../../lib/db'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">handler</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> NextApiRequest</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> res</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> NextApiResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">try</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">method</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">case</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'GET'</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        db</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">all</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">select * from post</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">200</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">case</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'POST'</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> title</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> content </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">body</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        db</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">insert into post(title, content) values(?, ?)</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">title</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> content</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">200</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">500</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">end</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">api/post/[id].ts<span style="flex:1;text-align:right">typescript</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">type</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> NextApiRequest</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> NextApiResponse </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'next'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> db </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'../../../lib/db'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">handler</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> NextApiRequest</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> res</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> NextApiResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> id </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">query</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> title</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> content </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">body</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">try</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain">method</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">case</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'GET'</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        db</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">select * from post where id=$id</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> $id</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> id </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">200</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">break</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">case</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'Put'</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        db</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">update post set title=?,content=? where id=?</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">title</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> content</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">200</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">case</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'DELETE'</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        db</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">delete from post where id=$id</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> $id</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> id </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">err</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">200</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">rows</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">error</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">status</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token number" style="color:hsl(29, 54%, 61%)">500</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token function" style="color:hsl(207, 82%, 66%)">end</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>这里为了符合 RESTFUL 风格，所以 post 下编写了两个文件，这时候请求<a href="http://localhost:3000/api/post/2" target="_blank" rel="noopener noreferrer">http://localhost:3000/api/post</a> 就能获取到所有文章数据，基本的 CRUD 也就实现了。</p>
<p>这里写 sql 是真滴繁琐，没使用 str 或是 typeorm 主要是不想把这个 demo 搞得太复杂，实际项目还是用上比较好。</p>
<p>当然这里只是作为后端 api 接口的演示，至于前端的展示与编写就和普通前端开发没啥大的区别。基本后端框架能做的，next 能做后端很多事情，更多的使用还是作为接口转发，中间件等，毕竟 Next 主要的强项还是服务端渲染的能力。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="打包部署">打包部署<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#%E6%89%93%E5%8C%85%E9%83%A8%E7%BD%B2" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>既然说到部署，那肯定离不开 nextjs 的母公司<a href="https://vercel.com/" target="_blank" rel="noopener noreferrer">Vercel</a>了，关于 Vercel 之前也写过相关文章，关于 Vercel 就不过多介绍。</p>
<p>nextjs 部署到 vercel 实在简单，将项目推送到 github 仓库中，然后在 vercel 中 New Project，接着选择 nextjs 的仓库，点击 Deploy，静等部署即可。关于部署可以看这篇文章 <a href="http://www.yanghao717.cn/develop/Vercel%E9%83%A8%E7%BD%B2%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2" target="_blank" rel="noopener noreferrer">Vercel 部署个人博客</a></p>
<p>现在你可以通过访问 <a href="https://kz-next-app-demo.vercel.app/" target="_blank" rel="noopener noreferrer">kz-next-app-demo.vercel.app</a> 来访问该项目，并尝试访问<code>/api/post</code>，<code>user/1</code>来看看。</p>
<p>只能说不愧是母公司。</p>
<p>至于其他部署？既然都用 nextjs 了，还考虑自建服务器来部署吗？</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="总结">总结<a href="http://www.yanghao717.cn/en/blog/next.js-build-and-deploy#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>这次的整体过程比较简单，后续应该会使用 nextjs 编写一个完整的项目（<del>也有可能是 nuxt.js</del>)。</p>]]></content:encoded>
            <category>next</category>
            <category>react</category>
            <category>ssr</category>
            <category>vercel</category>
        </item>
        <item>
            <title><![CDATA[vite+vue3搭建uniapp开发环境]]></title>
            <link>http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment</link>
            <guid>http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment</guid>
            <pubDate>Sun, 27 Mar 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[使用 vite vue3 搭建 uniapp 开发环境]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" src="https://img.night.cn/uniapp.png" alt="uniapp" class="img_ev3q"></p>
<p>最近想搞个移动端或小程序的 Vue3 项目，所以选择跨端开发平台就显得十分重要。在业内主要有两个跨端开发平台，Taro 与 uniapp，但 uniapp 貌似对 vue3 的支持不是特别友好。所以让我在 Taro 和 uniapp 之间抉择了一段时间，最终还是尝试选择相对熟悉的 uniapp 来进行开发。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>前排提醒：目前 uniapp 对 Vue3 的支持还处于 alpha 版，即开发阶段，大概率是会遇到很多问题的。</div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="开发环境搭建">开发环境搭建<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>建议安装 HBuilderX，主要是 uni cli 在 APP 平台仅支持生成离线打包的 wgt 资源包，不支持云端打包生成 apk/ipa，并且也不便配置一些打包后的参数。</p>
<p>这里建议安装 Alpha 版，后文会说明缘由。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>注意</div><div class="admonitionContent_BuS1"><p>在 HBuilderX 正式版中是无法直接创建 Vue3 项目的，而 Alpha 版有 Vue2 和 3 可供选择，但创建的自带的模板大部分的写法还是 vue2 的写法（无 setup 语法糖），所以这时候要么改代码自建，要么使用官方所提供的 <a href="https://uniapp.dcloud.io/worktile/CLI.html#%E5%88%9B%E5%BB%BA%E5%B7%A5%E7%A8%8B" target="_blank" rel="noopener noreferrer">Vue3 模板</a></p><p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220327000608783.png" alt="image-20220327000608783" class="img_ev3q"></p></div></div>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)"># 创建以 javascript 开发的工程</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">npx degit dcloudio/uni-preset-vue</span><span class="token comment" style="color:hsl(220, 10%, 40%)">#vite my-vue3-project</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)"># 创建以 typescript 开发的工程</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">npx degit dcloudio/uni-preset-vue</span><span class="token comment" style="color:hsl(220, 10%, 40%)">#vite-ts my-vue3-project</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>当然，有可能会下载失败，可以直接访问 <a href="https://gitee.com/dcloud/uni-preset-vue/repository/archive/vite-ts.zip" target="_blank" rel="noopener noreferrer">gitee</a>下载模板。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="项目结构">项目结构<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> src</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">App</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">vue</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> env</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">d</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"> 	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> main</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"> 	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> manifest</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">json</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> pages</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">json</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"> 	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> uni</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">scss</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"> 	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> pages</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"> 	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token plain">   </span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> index</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"> 	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token plain">       </span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">vue</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  	</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">static</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"> 		</span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> logo</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">png</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">html</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">package</span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain">lock</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">json</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">package</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">json</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> postcss</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">config</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> tsconfig</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">json</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token operator" style="color:hsl(207, 82%, 66%)">|</span><span class="token operator" style="color:hsl(207, 82%, 66%)">--</span><span class="token plain"> vite</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">config</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">ts</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>下载完毕，开始安装依赖，接着就可以开始测试了。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="运行编译">运行编译<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E8%BF%90%E8%A1%8C%E7%BC%96%E8%AF%91" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>在运行之前，首先将<strong>vuex</strong>包给移除，不然将会有如下提示，总之就是不推荐使用的意思，而且要使用状态管理也推荐使用 pinia。所以执行 <code>yarn remove vuex</code> 吧</p>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">node</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token number" style="color:hsl(29, 54%, 61%)">26968</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token constant" style="color:hsl(29, 54%, 61%)">DEP0148</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">DeprecationWarning</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">Use</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">of</span><span class="token plain"> deprecated folder mapping </span><span class="token string" style="color:hsl(95, 38%, 62%)">"./"</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> the </span><span class="token string" style="color:hsl(95, 38%, 62%)">"exports"</span><span class="token plain"> field module resolution </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">of</span><span class="token plain"> the </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">package</span><span class="token plain"> at </span><span class="token constant" style="color:hsl(29, 54%, 61%)">F</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain">\</span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">Uniapp</span><span class="token plain">\my</span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain">vue3</span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain">project1\node_modules\vuex\</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">package</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">json</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token property-access maybe-class-name" style="color:hsl(29, 54%, 61%)">Update</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">package</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">json</span><span class="token plain"> to use a subpath pattern like </span><span class="token string" style="color:hsl(95, 38%, 62%)">"./*"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="h5">H5<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#h5" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>运行编译都正常</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="app">APP<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#app" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>使用<code>npm run dev:app</code>后就会发现，终端一直卡在如下界面无法继续。（后面测试发现，除了 H5 能正常运行，其他都会卡住）</p>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">编译器版本：</span><span class="token number" style="color:hsl(29, 54%, 61%)">3.4</span><span class="token number" style="color:hsl(29, 54%, 61%)">.3</span><span class="token plain">（vue3）</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">请注意运行模式下，因日志输出、sourcemap 以及未压缩源码等原因，性能和包体积，均不及发行模式</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">。</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">正在编译中</span><span class="token spread operator" style="color:hsl(207, 82%, 66%)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vite v2</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token number" style="color:hsl(29, 54%, 61%)">8.6</span><span class="token plain"> building </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> development</span><span class="token spread operator" style="color:hsl(207, 82%, 66%)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token constant" style="color:hsl(29, 54%, 61%)">DONE</span><span class="token plain">  </span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">Build</span><span class="token plain"> complete</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token plain"> </span><span class="token property-access maybe-class-name" style="color:hsl(29, 54%, 61%)">Watching</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> changes</span><span class="token spread operator" style="color:hsl(207, 82%, 66%)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">ready </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> 1554ms</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>然后呢？？？</p>
<p>算了，就用 HBuilderX 的 cli 先运行到手机或模拟器，然后后打开 app 的时候提示如下错误，点击忽略后发现应用无法正常运行。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220326224649953.png" alt="image-20220326224649953" class="img_ev3q"></p>
<p>查看了下我本地的 HBuilderX 版本是正式版 v3.3.13，而该 Vue3 的模板的 Alpha 版 v3.4.3</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220326225748608.png" alt="image-20220326225748608" class="img_ev3q"></p>
<p>好家伙，官方提供的模板都直接使用 Alpha 版，无奈只好点击 <a href="https://ask.dcloud.net.cn/article/35627" target="_blank" rel="noopener noreferrer">查看详情</a> 后问题解决办法。最终测试后，建议是使用最新版，即 Alpha 版本，于是替换了本地正式版的 HbuilderX，应用便能正常运行了。</p>
<p>既然开发环境下能正常运行，那就试下打包。由于 uniapp 打包安卓应用只能打包成 APP 资源，要打包成 apk，要么创建一个 Android Studio 工程，然后将 APP 资源放入并打包成 apk，要么使用云打包（而云打包又是只有 HBuilder 才有的功能）。如果本地没有 Android Studio 相关环境，建议还是使用云打包（简单方便），这里就不演示下打包过程了。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="小程序">小程序<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E5%B0%8F%E7%A8%8B%E5%BA%8F" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>这里只测试了微信小程序，在上面 app 的处理完之后，微信小程序也是正常运行，不过至于与上面 Vue3 模板和 HbuilderX 正式版有无关系我就不得而知了，也懒得重装测试了。不过猜测应该与上面无关，毕竟是与手机的 SDK 有关。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="组件库">组件库<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E7%BB%84%E4%BB%B6%E5%BA%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>uniapp 官方中提供了一个 uni-ui 的组件库，但有一个 uniapp 相对知名的组件库 uview，并且相对前者来说更易上手实用，但当我尝试用 HBuilderX 导入时，却出现下方提示。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220327002827115.png" alt="image-20220327002827115" class="img_ev3q"></p>
<p>很显然，uview 并不支持 vue3，但在社区中找到了份同时支持 Vue3.0 和 Vue2.0 的<a href="https://ext.dcloud.net.cn/plugin?name=vk-uview-ui" target="_blank" rel="noopener noreferrer">uView</a>，但测试后最终已失败告终。</p>
<p>在社区中也搜到了 <a href="https://ext.dcloud.net.cn/plugin?id=556" target="_blank" rel="noopener noreferrer">ThorUI 组件库</a> 但貌似需要会员收费，果断放弃且没有测试。</p>
<p>然后想到 Taro 中还有 nutui，于是我便开始尝试了一下，不出所料，支持 Vue3 组件库，肯定是支持的。演示如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20220327005629618.png" alt="image-20220327005629618" class="img_ev3q"></p>
<p>但很遗憾，这里的支持也只是局限于 h5 开发。官方也有声明只能开发 h5</p>
<blockquote>
<p>@nutui/nutui@next 基于 Vue3 视觉风格 JD APP 10.0 规范 ，只能开发 h5 @nutui/nutui-taro 基于 Vue3 视觉风格 JD APP 10.0 规范 ，必须基于 taro + vue3 框架 进行开发多端（多端指一套代码 部署多端环境 微信小程序 h5、等第三方小程序）</p>
</blockquote>
<p>而且想要多端开发，也必须基于 taro + vue3 框架，所以在 uniapp 上的 app 与小程序上自然无法运行（已测试）</p>
<p>所以说一开始在 uniapp 和 taro 中的选择中，为啥不使用 Taro 呢？而且还支持 Vue3（相比 uniapp 而言）？</p>
<p>最终组件库的选择是 uniapp 官方的 uni-ui。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="使用-vscode-开发">使用 VSCode 开发<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E4%BD%BF%E7%94%A8-vscode-%E5%BC%80%E5%8F%91" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>HBuilder 给我代码编写体验并不友好，所以将 uniapp 的项目转 vscode 进行开发，并且使用到 npm 包。</p>
<p>首先创建一个 vite+vue3 项目（或者使用一开始介绍的官方提供的 Vue3 模板，主要是有 cli，需要自行在安装），然后将原 src 目录给删除，替换成 uniapp 创建的项目根目录。但还需要做以下操作</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="安装-sass">安装 sass<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E5%AE%89%E8%A3%85-sass" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>vite 要支持 sass 只需要安装 sass 的依赖即可</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">install</span><span class="token plain"> sass</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="允许-js-文件">允许 js 文件<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E5%85%81%E8%AE%B8-js-%E6%96%87%E4%BB%B6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>由于使用了 ts，如果项目中存在 js 文件，将会警告，可以在 tsconfig.json 中添加<code>"allowJs": true</code>即可</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="组件语法提示">组件语法提示<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E7%BB%84%E4%BB%B6%E8%AF%AD%E6%B3%95%E6%8F%90%E7%A4%BA" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> i @dcloudio/uni-helper-json @types/uni-app @types/html5plus </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-D</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>但发现对于 uni-ui 组件库的代码提示并不友好，大概率是需要局部引用组件，我这里并未使用<a href="https://www.npmjs.com/package/@dcloudio/uni-ui" target="_blank" rel="noopener noreferrer">npm 包</a>的方式导入，而是采用官方的 uni_modules，不过组件库的代码提示的问题不是很大，查阅文档即可解决。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="导入代码块">导入代码块<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E5%AF%BC%E5%85%A5%E4%BB%A3%E7%A0%81%E5%9D%97" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p><span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/zhetengbiji/uniapp-snippets-vscode" target="_blank" rel="noopener noreferrer">uni-app 代码块（vscode） (github.com)</a></span></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="找不到模块appvue或其相应的类型声明">找不到模块“./App.vue”或其相应的类型声明<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E6%89%BE%E4%B8%8D%E5%88%B0%E6%A8%A1%E5%9D%97appvue%E6%88%96%E5%85%B6%E7%9B%B8%E5%BA%94%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>在 src 目录下创建<code>env.d.ts</code>文件，填入以下内容即可</p>
<div class="language-typescript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-typescript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">/// &lt;reference types="vite/client" /&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">declare</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">module</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'*.vue'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> DefineComponent </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'vue'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">const</span><span class="token plain"> component</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> DefineComponent</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(95, 38%, 62%)">any</span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">default</span><span class="token plain"> component</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>然后就是把一些<code>#ifndef VUE3</code>不是 vue3 的代码块，以及部分 js 文件改写成 ts 文件即可。这里把我修改后的模板上传到 github 上，有需要的可自行下载：<span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/night/vite-vue3-uniapp" target="_blank" rel="noopener noreferrer">night/vite-vue3-uniapp (github.com)</a></span></p>
<p>如果不想使用官方的 vue3 模板，这里也有篇文章介绍如何迁移</p>
<p><a href="https://zhuanlan.zhihu.com/p/268206071" target="_blank" rel="noopener noreferrer">迁移 HbuilderX 的 uniapp 项目到主流的前端 IDE 开发（支持 VS Code 等编辑器/IDE）</a></p>
<p>不过最终如果要在 app 或小程序端运行，还是得打开 HBuilder。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="总结">总结<a href="http://www.yanghao717.cn/en/blog/vite-vue3-build-uniapp-environment#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>整个过程下来，其实还是 uniapp 对 Vue3 支持不够友好，加上生态没能及时更新。并且官方提供的 Vue3 模板也存在一定问题。</p>
<p>但最终还是使用 uniapp 来进行开发，一是对 Vue3 足够了解加上使用过 uniapp，二是 Taro 对 Vue3 是支持了，但是又该如何编译成 App 这是我主要需求的，最主要还是不想踩一遍 Taro 的坑了。</p>]]></content:encoded>
            <category>vue</category>
            <category>vite</category>
            <category>uniapp</category>
            <category>develop</category>
        </item>
        <item>
            <title><![CDATA[搭建Electron+Vue3开发环境]]></title>
            <link>http://www.yanghao717.cn/en/blog/electron-vue3-development-environment</link>
            <guid>http://www.yanghao717.cn/en/blog/electron-vue3-development-environment</guid>
            <pubDate>Thu, 17 Mar 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[搭建 Electron Vue3 的开发环境，用于编写跨平台应用]]></description>
            <content:encoded><![CDATA[<p>之前用 electron-vue 写过一个半成品的桌面端应用，但是是基于 Vue2 的，最近又想重写点桌面端应用，想要上 Vue3+TypeScript，于是便有了这篇文章总结下具体的搭建过程。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="vue-cli">Vue Cli<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#vue-cli" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>Vue CLI 有一个插件<code>vue-cli-plugin-electron-builder</code>，可以非常方便的搭建 electron 环境。</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> i @vue/cli </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-g</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vue create my-app</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>根据自己项目的需求选择对应的依赖（例如 Babel，TS，Vuex 等等）</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Vue CLI v5.0.3</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Please pick a preset: Manually </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">select</span><span class="token plain"> features</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Check the features needed </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> your project: Babel, TS, Vuex, CSS Pre-processors, Linter</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Choose a version of Vue.js that you want to start the project with </span><span class="token number" style="color:hsl(29, 54%, 61%)">3</span><span class="token plain">.x</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Use class-style component syntax? Yes</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Use Babel alongside TypeScript </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">required </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> modern mode, auto-detected polyfills, transpiling JSX</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain">? Yes</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Pick a CSS pre-processor </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">PostCSS, Autoprefixer and CSS Modules are supported by default</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain">: Sass/SCSS </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">with dart-sass</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Pick a linter / formatter config: Prettier</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Pick additional lint features: Lint on save</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Where </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">do</span><span class="token plain"> you prefer placing config </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> Babel, ESLint, etc.? In package.json</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">? Save this as a preset </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> future projects? No</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">Vue CLI v5.0.3</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">✨  Creating project </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> F:</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain">Electron</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">\</span><span class="token plain">my-app.</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">🗃  Initializing </span><span class="token function" style="color:hsl(207, 82%, 66%)">git</span><span class="token plain"> repository</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">..</span><span class="token plain">.</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">⚙️  Installing CLI plugins. This might take a while</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">..</span><span class="token plain">.</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="安装-vue-cli-plugin-electron-builder">安装 vue-cli-plugin-electron-builder<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#%E5%AE%89%E8%A3%85-vue-cli-plugin-electron-builder" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p><a href="https://nklayman.github.io/vue-cli-plugin-electron-builder/" target="_blank" rel="noopener noreferrer">Vue CLI Plugin Electron Builder (nklayman.github.io)</a></p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">cd</span><span class="token plain"> my-app</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vue </span><span class="token function" style="color:hsl(207, 82%, 66%)">add</span><span class="token plain"> electron-builder</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>安装过程中会提示你选择 Electron 的版本，选择最新版本即可</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="启动项目">启动项目<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#%E5%90%AF%E5%8A%A8%E9%A1%B9%E7%9B%AE" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> run electron:serve</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>参考文章：<a href="https://juejin.cn/post/6983843979133468708" target="_blank" rel="noopener noreferrer">Electron + Vue3 开发跨平台桌面应用【从项目搭建到打包完整过程】 - 掘金 (juejin.cn)</a></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="坑">坑<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#%E5%9D%91" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">error  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">in</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">src</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">background</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">Module</span><span class="token plain"> build </span><span class="token function" style="color:hsl(207, 82%, 66%)">failed</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword module" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">node_modules</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">ts</span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain">loader</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">js</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token known-class-name class-name" style="color:hsl(29, 54%, 61%)">TypeError</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> loaderContext</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">getOptions</span><span class="token plain"> is not a </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>我测试的时候，<code>@vue/cli-plugin-typescript</code>版本为<code>~5.0.0</code>，就会导致编译类型出错，将 package.json 中改为<code>"@vue/cli-plugin-typescript": "~4.5.15"</code>，即可正常运行（但还是会有 DeprecationWarning）</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="vite">Vite<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#vite" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>上面是使用 Vue Cli 脚手架进行开发，如果想上 Vite 的话，就需要用 Vite 来构建项目，然后安装 electron 的相关依赖。</p>
<p>这个不是作为重点，因为很多大佬都已经写了现成的模板，完全可以自行借鉴学习，就贴几个阅读过的几篇文章</p>
<p><a href="https://dev.to/brojenuel/vite-vue-3-electron-5h4o" target="_blank" rel="noopener noreferrer">Vite + Vue 3 + electron + TypeScript - DEV Community</a></p>
<p><a href="https://zhuanlan.zhihu.com/p/424202065" target="_blank" rel="noopener noreferrer">2021 年最前卫的跨平台开发选择！vue3 + vite + electron - 知乎 (zhihu.com)</a></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="现成的模板">现成的模板<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#%E7%8E%B0%E6%88%90%E7%9A%84%E6%A8%A1%E6%9D%BF" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>均可在 github 上搜索到</p>
<ul>
<li>
<p><span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/caoxiemeihao/vite-react-electron" target="_blank" rel="noopener noreferrer">vite-react-electron</a></span> (推荐)</p>
</li>
<li>
<p><span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/caoxiemeihao/electron-vue-vite" target="_blank" rel="noopener noreferrer">electron-vue-vite</a></span> (推荐)</p>
</li>
<li>
<p><span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/cawa-93/vite-electron-builder" target="_blank" rel="noopener noreferrer">vite-electron-builder</a></span></p>
</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="electron-vite-脚手架推荐">electron-vite 脚手架（推荐）<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#electron-vite-%E8%84%9A%E6%89%8B%E6%9E%B6%E6%8E%A8%E8%8D%90" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>当然也可以使用脚手架，可选择 React 与 Vue，实际上也就是创建上面的前两个模板</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> create electron-vite</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="现有项目使用-electron">现有项目使用 electron<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#%E7%8E%B0%E6%9C%89%E9%A1%B9%E7%9B%AE%E4%BD%BF%E7%94%A8-electron" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>TODO...</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="总结">总结<a href="http://www.yanghao717.cn/en/blog/electron-vue3-development-environment#%E6%80%BB%E7%BB%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>因为 Electron 本质上还是一个浏览器，无论是 Vue 还是 React 开发也好，在传统网页开发的时候都有对应的调试地址，如 <a href="http://127.0.0.1:3000/" target="_blank" rel="noopener noreferrer">http://127.0.0.1:3000</a>，而 electron 的做法无非就是开启一个浏览器，然后和正常的网页开发一样，并提供桌面端的 api 使用。</p>
<p>目前社区两大 Vue+Electron 的脚手架主要是<span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/SimulatedGREG/electron-vue" target="_blank" rel="noopener noreferrer">electron-vue</a></span>和<span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/nklayman/vue-cli-plugin-electron-builder" target="_blank" rel="noopener noreferrer">vue-cli-plugin-electron-builder</a></span>，更多 electron 的开源项目都遵循着前者的项目结构，像上面的模板也就是。</p>
<p>以上就是我所使用 Vue3 来开发 Electron 的环境搭建过程，总体来说从 Electron 除了应用体积过大，对于前端开发者来说是非常友好的，既然环境配置完，那么现在就可以开始好好的编写桌面端应用了。</p>]]></content:encoded>
            <category>electron</category>
            <category>vue</category>
            <category>vite</category>
        </item>
        <item>
            <title><![CDATA[记 ThinkPHP 项目部署]]></title>
            <link>http://www.yanghao717.cn/en/blog/thinkphp-deploy</link>
            <guid>http://www.yanghao717.cn/en/blog/thinkphp-deploy</guid>
            <pubDate>Sat, 25 Sep 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[事情背景]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="事情背景">事情背景<a href="http://www.yanghao717.cn/en/blog/thinkphp-deploy#%E4%BA%8B%E6%83%85%E8%83%8C%E6%99%AF" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>用户花了几百块购买了一份 ThinkPHP 一个后台管理的网站源码，要求更换下部分失效接口，或是重写一个类似这样的网站。我想既然都有源码了，我改改不就完事了，这不比重写一个来的省事。虽说我不是主学 PHP 的，但至少我学过一丢丢的 PHP 语法，接触过 ThinkPHP 项目。不过层面都是局限在本地，部署到生产环境与本地还是有比较大的差别的，于是便有了这篇文章来记录一下自己部署 ThinkPHP 所遇到的一些坑。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="windows-部署">Windows 部署<a href="http://www.yanghao717.cn/en/blog/thinkphp-deploy#windows-%E9%83%A8%E7%BD%B2" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>也可理解为本地部署，本地部署就相对比较简单的了。不过需要一个工具，PHPStudy，来帮助我们配置本地的环境（Apache、Nginx、PHP、Mysql）</p>
<p><a href="https://www.xp.cn/" target="_blank" rel="noopener noreferrer">小皮面板(phpstudy) - 让天下没有难配的服务器环境！ (xp.cn)</a></p>
<p>下载安装打开界面，选择网站，创建网站</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925143601530.png" alt="image-20210925143601530" class="img_ev3q"></p>
<p>由于是本机，所以域名就填写 localhost 或 127.0.0.1，端口的话这边所填写的是 4200，别和其他端口冲突即可。</p>
<p>由于 ThinkPHP 的根目录要选择的是根目录下的 public 目录，不然找不到 index.php 这个文件，所以这里根目录自己指定一下源码的位置，点击确认即可。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="初次启动-not-found">初次启动 Not Found<a href="http://www.yanghao717.cn/en/blog/thinkphp-deploy#%E5%88%9D%E6%AC%A1%E5%90%AF%E5%8A%A8-not-found" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>这时候访问 <a href="http://localhost:4200/" target="_blank" rel="noopener noreferrer">http://localhost:4200</a> 提示如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925143752775.png" alt="image-20210925143752775" class="img_ev3q"></p>
<p>本着不会就百度的原则，很快就找到了解决办法</p>
<p><a href="https://blog.csdn.net/qq_42940241/article/details/112461625" target="_blank" rel="noopener noreferrer">ThinkPHP 报错 The requested URL /index/index/xxx.html was not found on this server</a></p>
<p>在入口文件夹 public 下查看.htaccess 是否存在。不存在则新建，存在的话，那内容替换为下面这串代码 就可以解决 Not Fund 问题</p>
<div class="language-xml codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-xml codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">#</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">IfModule</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">mod_rewrite.c</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">#  Options +FollowSymlinks -Multiviews</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">#  RewriteEngine On</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">#</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">#  RewriteCond %{REQUEST_FILENAME} !-d</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">#  RewriteCond %{REQUEST_FILENAME} !-f</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">#  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">#</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">IfModule</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">IfModule</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">mod_rewrite.c</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">RewriteEngine on</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">RewriteCond %{REQUEST_FILENAME} !-d</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">RewriteCond %{REQUEST_FILENAME} !-f</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">IfModule</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="页面报错-开启-debug">页面报错 开启 Debug<a href="http://www.yanghao717.cn/en/blog/thinkphp-deploy#%E9%A1%B5%E9%9D%A2%E6%8A%A5%E9%94%99-%E5%BC%80%E5%90%AF-debug" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>上面配置完毕后，再次打开出现如下提示。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925144143248.png" alt="image-20210925144143248" class="img_ev3q"></p>
<p>遇到错误是很正常的，现在要做的就是输出报错信息，而不是简短的文字。到根目录下 config/app.php 中，将调试更改为 true（切记，生产环境中一定要更改为 false，不然用户就能查看报错详情以及对应代码）</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925144424361.png" alt="image-20210925144424361" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="配置数据库">配置数据库<a href="http://www.yanghao717.cn/en/blog/thinkphp-deploy#%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>再次访问页面提示</p>
<p><strong><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925144620953.png" alt="image-20210925144620953" class="img_ev3q"></strong></p>
<p>报错信息倒是很全，不过要关注的是报错行和提示，大致意思就是没有定义数据库用户名 ml 以及密码，毕竟数据库啥的都好像没配置，要是能启动起来那估计就真是一个 bug 了，那就先找到配置文件，看看原本的账号密码是多少，数据库配置文件位置<code>config/database.php</code></p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925145740851.png" alt="image-20210925145740851" class="img_ev3q"></p>
<p>不过 PHPstudy 用户名和密码长度都要在 6 位以上（Linux 倒是不用），所以勉为其难，把用户名和密码都改成 ml1234，接着 Mysql 导入源码给定的数据库文件(sql 文件)，什么，你说源码没有给数据库文件，那我建议直接删源码，并且接下来的内容也可以不用看了。</p>
<p>数据库导入完毕后，再次访问便能看到正常的首页了，就此就算部署完毕了，这里就不放首页图了。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="linux-部署">Linux 部署<a href="http://www.yanghao717.cn/en/blog/thinkphp-deploy#linux-%E9%83%A8%E7%BD%B2" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>Linux 部署和 Windows 部署是有一丢丢差别的，这里我也列举一下，环境是 CentOS 7.6，安装了宝塔面板</p>
<p>在宝塔面板出网站，添加网站，如同 PHPstudy，配置大致相同。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210926050508693.png" alt="image-20210926050508693" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="关闭防跨站攻击">关闭防跨站攻击<a href="http://www.yanghao717.cn/en/blog/thinkphp-deploy#%E5%85%B3%E9%97%AD%E9%98%B2%E8%B7%A8%E7%AB%99%E6%94%BB%E5%87%BB" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>情况 1，如图</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925155027023.png" alt="image-20210925155027023" class="img_ev3q"></p>
<p>解决办法：点击网站，设置，将防跨站攻击关闭并保持，如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925155445084.png" alt="image-20210925155445084" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="设置伪静态">设置伪静态<a href="http://www.yanghao717.cn/en/blog/thinkphp-deploy#%E8%AE%BE%E7%BD%AE%E4%BC%AA%E9%9D%99%E6%80%81" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>接着再次访问网站会出现 404 页面不存在报错，在设置中找到伪静态，添加一个 thinkphp 的配置，如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210925155705573.png" alt="image-20210925155705573" class="img_ev3q"></p>
<p>再次访问后，出现的就是数据库配置的问题，配置一下数据库，导入数据，然后再次访问便可。</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>再次提醒，生产环境下请将<code>app_debug</code>设置为 false，不然非法用户可以通过人为试错，查询对应报错代码。</div></div>]]></content:encoded>
            <category>php</category>
            <category>develop</category>
        </item>
        <item>
            <title><![CDATA[使用Vue开发Chrome插件]]></title>
            <link>http://www.yanghao717.cn/en/blog/vue-chrome-extension</link>
            <guid>http://www.yanghao717.cn/en/blog/vue-chrome-extension</guid>
            <pubDate>Sat, 18 Sep 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[使用 Vue2 开发一个 Chrome 插件]]></description>
            <content:encoded><![CDATA[<p>我当时学习开发 Chrome 插件的时候，还不会 Vue，更别说 Webpack 了，所以使用的都是原生的 html 开发，效率就不提了，而这次就准备使用 vue-cli 来进行编写一个某 B 站获取视频信息,评论的功能（原本是打算做自动回复的），顺便巩固下 chrome 开发（快一年没碰脚本类相关技术了），顺便写套模板供自己后续编写 Chrome 插件做铺垫。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="环境搭建">环境搭建<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p><a href="https://vue-web-extension.netlify.app/" target="_blank" rel="noopener noreferrer">Vue Web-Extension - A Web-Extension preset for VueJS (vue-web-extension.netlify.app)</a></p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-g</span><span class="token plain"> @vue/cli</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">install</span><span class="token plain"> </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">-g</span><span class="token plain"> @vue/cli-init</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">vue create </span><span class="token parameter variable" style="color:hsl(207, 82%, 66%)">--preset</span><span class="token plain"> kocal/vue-web-extension my-extension</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token builtin class-name" style="color:hsl(29, 54%, 61%)">cd</span><span class="token plain"> my-extension</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> run server</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>会提供几个选项，如 Eslint，background.js，tab 页，axios，如下图</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210916142751129.png" alt="image-20210916142751129" class="img_ev3q"></p>
<p>选择完后，将会自动下载依赖，通过 npm run server 将会在根目录生成 dist 文件夹，将该文件拖至 Chrome 插件管理便可安装，由于使用了 webpack，所以更改代码将会热更新，不用反复的编译导入。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="项目结构">项目结构<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<div class="language-tree codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-tree codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─src</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─App.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─background.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─main.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─manifest.json</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─views</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |   ├─About.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |   └Home.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─store</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |   └index.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─standalone</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |     ├─App.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |     └main.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─router</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |   └index.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─popup</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |   ├─App.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |   └main.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─override</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |    ├─App.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |    └main.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─options</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |    ├─App.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |    └main.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─devtools</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |    ├─App.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |    └main.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─content-scripts</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |        └content-script.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─components</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |     └HelloWorld.vue</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  ├─assets</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">|  |   └logo.png</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─public</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─.browserslistrc</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─.eslintrc.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─.gitignore</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─babel.config.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─package.json</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─vue.config.js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─yarn.lock</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>根据所选的页面，并在 src 与 vue.config.js 中配置页面信息编译后 dist 目录结构如下</p>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─devtools</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">html</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─favicon</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">ico</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">html</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─manifest</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">json</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─options</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">html</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─override</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">html</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─popup</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">html</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─_locales</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─js</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─icons</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">├─css</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="安装组件库">安装组件库<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E5%AE%89%E8%A3%85%E7%BB%84%E4%BB%B6%E5%BA%93" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="安装-elementui">安装 elementUI<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E5%AE%89%E8%A3%85-elementui" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>整体的开发和 vue2 开发基本上没太大的区别，不过既然是用 vue 来开发的话，那肯定少不了组件库了。</p>
<p>要导入 Element-ui 也十分简单，<code>Vue.use(ElementUI); </code>Vue2 中怎么导入 element，便怎么导入。演示如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210916150154078.png" alt="image-20210916150154078" class="img_ev3q"></p>
<p>不过我没有使用 babel-plugin-component 来按需引入，按需引入一个按钮打包后大约 1.6m，而全量引入则是 5.5 左右。至于为什么不用，因为我需要在 content-scripts.js 中引入 element 组件，如果使用 babel-plugin-component 将无法按需导入组件以及样式（应该是只支持 vue 文件按需引入，总之就是折腾了我一个晚上的时间）</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="安装-tailwindcss">安装 tailwindcss<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E5%AE%89%E8%A3%85-tailwindcss" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>不过官方提供了如何使用 TailwindCSS，这里就演示一下</p>
<p><a href="https://www.tailwindcss.cn/docs/guides/vue-3-vite" target="_blank" rel="noopener noreferrer">在 Vue 3 和 Vite 安装 Tailwind CSS - Tailwind CSS 中文文档</a></p>
<p>推荐安装低版本，最新版有兼容性问题</p>
<div class="language-bash codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-bash codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">npm</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">install</span><span class="token plain"> tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>创建 postcss.config.js 文件</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">postcss.config.js<span style="flex:1;text-align:right">js</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// postcss.config.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">module</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">plugins</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function" style="color:hsl(207, 82%, 66%)">require</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'tailwindcss'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function" style="color:hsl(207, 82%, 66%)">require</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'autoprefixer'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// if you have installed `autoprefixer`</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>创建 tailwind.config.js 文件</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">tailwind.config.js<span style="flex:1;text-align:right">js</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// tailwind.config.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">module</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">purge</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Specify the paths to all of the template files in your project</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">content</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">'src/**/*.vue'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// Whitelist selectors by using regular expression</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">whitelistPatterns</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token regex regex-delimiter" style="color:hsl(95, 38%, 62%)">/</span><span class="token regex regex-source language-regex" style="color:hsl(95, 38%, 62%)">-</span><span class="token regex regex-source language-regex group punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token regex regex-source language-regex" style="color:hsl(95, 38%, 62%)">leave</span><span class="token regex regex-source language-regex alternation keyword" style="color:hsl(286, 60%, 67%)">|</span><span class="token regex regex-source language-regex" style="color:hsl(95, 38%, 62%)">enter</span><span class="token regex regex-source language-regex alternation keyword" style="color:hsl(286, 60%, 67%)">|</span><span class="token regex regex-source language-regex" style="color:hsl(95, 38%, 62%)">appear</span><span class="token regex regex-source language-regex group punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token regex regex-source language-regex group punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token regex regex-source language-regex alternation keyword" style="color:hsl(286, 60%, 67%)">|</span><span class="token regex regex-source language-regex" style="color:hsl(95, 38%, 62%)">-</span><span class="token regex regex-source language-regex group punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token regex regex-source language-regex" style="color:hsl(95, 38%, 62%)">to</span><span class="token regex regex-source language-regex alternation keyword" style="color:hsl(286, 60%, 67%)">|</span><span class="token regex regex-source language-regex" style="color:hsl(95, 38%, 62%)">from</span><span class="token regex regex-source language-regex alternation keyword" style="color:hsl(286, 60%, 67%)">|</span><span class="token regex regex-source language-regex" style="color:hsl(95, 38%, 62%)">active</span><span class="token regex regex-source language-regex group punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token regex regex-source language-regex group punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token regex regex-source language-regex anchor function" style="color:hsl(207, 82%, 66%)">$</span><span class="token regex regex-delimiter" style="color:hsl(95, 38%, 62%)">/</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// transitions</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token plain">data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain">v</span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token operator" style="color:hsl(207, 82%, 66%)">*</span><span class="token operator" style="color:hsl(207, 82%, 66%)">/</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// scoped css</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>在 src/popup/App.vue 中导入样式，或在新建 style.css 在 mian.js 中<code>import "../style.css";</code></p>
<div class="language-vue codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">src/popup/App.vue<span style="flex:1;text-align:right">vue</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-vue codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">style</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token style language-css"></span><span class="token style language-css comment" style="color:hsl(220, 10%, 40%)">/* purgecss start ignore */</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token style language-css"></span><span class="token style language-css atrule rule" style="color:hsl(29, 54%, 61%)">@tailwind</span><span class="token style language-css atrule" style="color:hsl(29, 54%, 61%)"> base</span><span class="token style language-css atrule punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token style language-css"></span><span class="token style language-css atrule rule" style="color:hsl(29, 54%, 61%)">@tailwind</span><span class="token style language-css atrule" style="color:hsl(29, 54%, 61%)"> components</span><span class="token style language-css atrule punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token style language-css"></span><span class="token style language-css comment" style="color:hsl(220, 10%, 40%)">/* purgecss end ignore */</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token style language-css" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token style language-css"></span><span class="token style language-css atrule rule" style="color:hsl(29, 54%, 61%)">@tailwind</span><span class="token style language-css atrule" style="color:hsl(29, 54%, 61%)"> utilities</span><span class="token style language-css atrule punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token style language-css"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token style language-css"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">style</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>从官方例子导入一个登陆表单，效果如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210916152633247.png" alt="image-20210916152633247" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="项目搭建">项目搭建<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E9%A1%B9%E7%9B%AE%E6%90%AD%E5%BB%BA" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="页面搭建">页面搭建<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E9%A1%B5%E9%9D%A2%E6%90%AD%E5%BB%BA" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>页面搭建就没什么好说的了，因为使用的是 element-ui，所以页面很快就搭建完毕了，效果如图</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210918115438700.png" alt="image-20210918115438700" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="悬浮窗">悬浮窗<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E6%82%AC%E6%B5%AE%E7%AA%97" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>悬浮窗其实可有可无，不过之前写 Chrome 插件的时候就写了悬浮窗，所以 vue 版的也顺带写一份。</p>
<p>要注意的是悬浮窗是内嵌到网页的（且在 document 加载前载入，也就是<code>"run_at": "document_start"</code>），所以需要通过 content-scripts.js 才能操作页面 Dom 元素，首先在配置清单 manifest.json 与 vue.confing.js 中匹配要添加的网站，以及注入的 js 代码，如下</p>
<div class="language-json codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">manifest.json<span style="flex:1;text-align:right">json</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-json codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"content_scripts"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">"matches"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"https://www.bilibili.com/video/*"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">"js"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"js/jquery.js"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"js/content-script.js"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">"css"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"css/index.css"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">"run_at"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"document_start"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">"matches"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"https://www.bilibili.com/video/*"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">"js"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"js/jquery.js"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"js/bilibili.js"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token property" style="color:hsl(355, 65%, 65%)">"run_at"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"document_end"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">vue.config.js<span style="flex:1;text-align:right">js</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">contentScripts</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">entries</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token string-property property" style="color:hsl(355, 65%, 65%)">'content-script'</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">'src/content-scripts/content-script.js'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">bilibili</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">'src/content-scripts/bilibili.js'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>由于是用 Vue，但又要在 js 中生成组件，就使用<code>document.createElement</code>来进行创建元素，Vue 组件如下（可拖拽）</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210917142340863.png" alt="image-20210917142340863" class="img_ev3q"></p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_BuS1"><p>如果使用<code>babel-plugin-component</code>按需引入，组件的样式将无法载入，同时自定义组件如果编写了 style 标签，那么也同样无法载入，报错：Cannot read properties of undefined (reading 'appendChild')</p><p>大致就是 css-loader 无法加载对应的 css 代码，如果执意要写 css 的话，直接在 manifest.json 中注入 css 即可</p></div></div>
<details open="" class="details_lb9f alert alert--info details_b_Ee" data-collapsed="false"><summary>完整代码</summary><div><div class="collapsibleContent_i85q"><div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">content-script.js<span style="flex:1;text-align:right">js</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// 注意，这里引入的vue是运行时的模块，因为content是插入到目标页面，对组件的渲染需要运行时的vue， 而不是编译环境的vue （我也不知道我在说啥，反正大概意思就是这样）</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword module" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token imports maybe-class-name" style="color:hsl(29, 54%, 61%)">Vue</span><span class="token plain"> </span><span class="token keyword module" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'vue/dist/vue.esm.js'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword module" style="color:hsl(286, 60%, 67%)">import</span><span class="token plain"> </span><span class="token imports maybe-class-name" style="color:hsl(29, 54%, 61%)">ElementUI</span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token imports"> </span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token imports"> </span><span class="token imports maybe-class-name" style="color:hsl(29, 54%, 61%)">Message</span><span class="token imports"> </span><span class="token imports punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword module" style="color:hsl(286, 60%, 67%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'element-ui'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">Vue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">use</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token maybe-class-name" style="color:hsl(29, 54%, 61%)">ElementUI</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 注意，必须设置了run_at=document_start此段代码才会生效</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">addEventListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'DOMContentLoaded'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'vue-chrome扩展已载入'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">insertFloat</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 在target页面中新建一个带有id的dom元素，将vue对象挂载到这个dom上。</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">insertFloat</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> element </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">createElement</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'div'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> attr </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">createAttribute</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'id'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  attr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">value</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'appPlugin'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  element</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">setAttributeNode</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">attr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getElementsByTagName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'body'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">appendChild</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">element</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> link </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">createElement</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'link'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> linkAttr </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">createAttribute</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'rel'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  linkAttr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">value</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'stylesheet'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> linkHref </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">createAttribute</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'href'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  linkHref</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">value</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'https://unpkg.com/element-ui/lib/theme-chalk/index.css'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  link</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">setAttributeNode</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">linkAttr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  link</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">setAttributeNode</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">linkHref</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getElementsByTagName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'head'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">appendChild</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">link</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> mx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> my </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> onDrag </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">var</span><span class="token plain"> drag </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">inserted</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onmousedown</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">offsetLeft</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">offsetTop</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        mx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientX</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        my </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientY</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">my </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">40</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        onDrag </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onmousemove</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">onDrag</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> nx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientX</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> mx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> left</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> ny </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientY</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> my </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> top</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> width </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientWidth</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> height </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientHeight</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> bodyWidth </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">body</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientWidth</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> bodyHeight </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">body</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientHeight</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">nx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> nx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">ny </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> ny </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">ny </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> bodyHeight </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> height </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;&amp;</span><span class="token plain"> bodyHeight </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> height </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              ny </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> bodyHeight </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> height</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">nx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> bodyWidth </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> width</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">              nx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> bodyWidth </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> width</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">style</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">left</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> nx </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'px'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">style</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">top</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> ny </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'px'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">el</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onmouseup</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">onDrag</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            onDrag </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">kz_vm</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Vue</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">el</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'#appPlugin'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">directives</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">drag</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> drag</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">template</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">      &lt;div class="float-page" ref="float" v-drag&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">        &lt;el-card class="box-card" :body-style="{ padding: '15px' }"&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">          &lt;div slot="header" class="clearfix" style="cursor: move"&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">            &lt;span&gt;悬浮窗&lt;/span&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">            &lt;el-button style="float: right; padding: 3px 0" type="text" @click="toggle"&gt;{{ show ? '收起' : '展开'}}&lt;/el-button&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">          &lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">          &lt;transition name="ul"&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">            &lt;div v-if="show" class="ul-box"&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">              &lt;span&gt; {{user}} &lt;/span&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">            &lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">          &lt;/transition&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">        &lt;/el-card&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">      &lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">      </span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">show</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">list</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">user</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">username</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">''</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">follow</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">title</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">''</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">view</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function" style="color:hsl(207, 82%, 66%)">mounted</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">methods</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token function" style="color:hsl(207, 82%, 66%)">toggle</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">show</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">show</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></details>
<p>因为只能在 js 中编写 vue 组件，所以得用 template 模板，同时使用了 directives，给组件添加了拖拽的功能（尤其是<code>window.onmousemove</code>，如果是元素绑定他自身的鼠标移动事件，那么拖拽鼠标将会十分卡顿），还使用了 transition 来进行缓慢动画效果其中注入的 css 代码如下</p>
<div class="language-css codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-css codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token selector class" style="color:hsl(95, 38%, 62%)">.float-page</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">width</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">400</span><span class="token unit">px</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">border-radius</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">8</span><span class="token unit">px</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">position</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> fixed</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">left</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">50</span><span class="token unit">%</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">top</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">25</span><span class="token unit">%</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">z-index</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">1000001</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token selector class" style="color:hsl(95, 38%, 62%)">.el-card__header</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">padding</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">10</span><span class="token unit">px</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">15</span><span class="token unit">px</span><span class="token plain"> </span><span class="token important" style="color:hsl(220, 14%, 71%);font-weight:bold">!important</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token selector class" style="color:hsl(95, 38%, 62%)">.ul-box</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">200</span><span class="token unit">px</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">overflow</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> hidden</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token selector class" style="color:hsl(95, 38%, 62%)">.ul-enter-active</span><span class="token selector punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token selector" style="color:hsl(95, 38%, 62%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token selector" style="color:hsl(95, 38%, 62%)"></span><span class="token selector class" style="color:hsl(95, 38%, 62%)">.ul-leave-active</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">transition</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> all </span><span class="token number" style="color:hsl(29, 54%, 61%)">0.5</span><span class="token unit">s</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token selector class" style="color:hsl(95, 38%, 62%)">.ul-enter</span><span class="token selector punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token selector" style="color:hsl(95, 38%, 62%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token selector" style="color:hsl(95, 38%, 62%)"></span><span class="token selector class" style="color:hsl(95, 38%, 62%)">.ul-leave-to</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>相关逻辑可自行观看，这里不在赘述了，并不复杂。</p>
<p>也顺带是复习一下 HTML 中鼠标事件和 vue 自定义命令了</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="功能实现">功能实现<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>主要功能</p>
<ul>
<li>
<p>检测视频页面，输出对应 up 主，关注数以及视频标题播放（参数过多就不一一显示了）</p>
</li>
<li>
<p>监控关键词根据内容判断是否点赞，例如文本出现了下次一定，那么就点赞。</p>
</li>
</ul>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="输出相关信息">输出相关信息<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E8%BE%93%E5%87%BA%E7%9B%B8%E5%85%B3%E4%BF%A1%E6%81%AF" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>这个其实只要接触过一丢丢爬虫的肯定都会知道如何实现，通过右键审查元素，像这样</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210918104907148.png" alt="image-20210918104907148" class="img_ev3q"></p>
<p>然后使用 dom 操作，选择对应的元素，输出便可</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">querySelector</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"#v_upinfo &gt; div.up-info_right &gt; div.name &gt; a.username"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">innerText</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'老番茄'</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>当然使用 JQuery 效果也是一样的。后续我都会使用 JQuery 来进行操作</p>
<p>在 src/content-script/bilibili.js 中写下如下代码</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onload</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'加载完毕'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">getInfo</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#v_upinfo &gt; div.up-info_right &gt; div.name &gt; a.username'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> follow </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">#v_upinfo &gt; div.up-info_right &gt; div.btn-panel &gt; div.default-btn.follow-btn.btn-transition.b-gz.following &gt; span &gt; span &gt; span</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> title </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">#viewbox_report &gt; h1 &gt; span</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> view </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#viewbox_report &gt; div &gt; span.view'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">attr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'title'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> follow</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> title</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">getInfo</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>重新加载插件，然后输出查看结果</p>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">加载完毕</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">bilibili</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">js</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token number" style="color:hsl(29, 54%, 61%)">19</span><span class="token plain"> 老番茄 </span><span class="token number" style="color:hsl(29, 54%, 61%)">1606.0</span><span class="token plain">万 顶级画质 总播放数</span><span class="token number" style="color:hsl(29, 54%, 61%)">2368406</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>这些数据肯定单纯的输出肯定是没什么作用的，要能显示到内嵌悬浮窗口，或者是 popup 页面上（甚至发送 ajax 请求到远程服务器上保存）</p>
<p>对上面代码微改一下</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onload</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'加载完毕'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">getInfo</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> username </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#v_upinfo &gt; div.up-info_right &gt; div.name &gt; a.username'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">trim</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> follow </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">#v_upinfo &gt; div.up-info_right &gt; div.btn-panel &gt; div.default-btn.follow-btn.btn-transition.b-gz.following &gt; span &gt; span &gt; span</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> title </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)">#viewbox_report &gt; h1 &gt; span</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">text</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> view </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#viewbox_report &gt; div &gt; span.view'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">attr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'title'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">//console.log(username, follow, title, view);</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">kz_vm</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">user</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      username</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      follow</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      title</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">getInfo</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>其中<code>window.kz_vm</code>是通过<code>window.kz_vm = new Vue()</code> 初始化的，方便我们操作 vm 对象，就需要通过 jquery 选择元素在添加属性了。如果你想的话也可以直接在 content-script.js 上编写代码，这样就无需使用 window 对象，但这样导致一些业务逻辑都堆在一个文件里，所以我习惯分成 bilibili.js 然后注入方式为 document_end，然后在操作 dom 元素吗，实现效果如下</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210918110958104.png" alt="image-20210918110958104" class="img_ev3q"></p>
<p>如果像显示到 popup 页面只需要通过页面通信就行了，不过前提得先 popup 打开才行，所以一般都是通过 background 来进行中转，一般来说很少 content –&gt; popup（因为操作 popup 的前提都是 popup 要打开），相对更多的是 content –&gt; background 或 popup –&gt; content</p>
<p><a href="https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html#content-script%E4%B8%BB%E5%8A%A8%E5%8F%91%E6%B6%88%E6%81%AF%E7%BB%99%E5%90%8E%E5%8F%B0" target="_blank" rel="noopener noreferrer">content-script 主动发消息给后台 我是小茗同学 - 博客园 (cnblogs.com)</a></p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="实现评论">实现评论<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E5%AE%9E%E7%8E%B0%E8%AF%84%E8%AE%BA" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>这边简单编写了一下页面，通过 popup 给 content，让 content 输入评论内容，与点击发送，先看效果</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/bilibili_comment.gif" alt="bilibili_comment" class="img_ev3q"></p>
<p>同样的，找到对应元素位置</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// 评论文本框</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#comment &gt; div &gt; div.comment &gt; div &gt; div.comment-send &gt; div.textarea-container &gt; textarea'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">val</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token string" style="color:hsl(95, 38%, 62%)">'要回复的内容'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 评论按钮</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#comment &gt; div &gt; div.comment &gt; div &gt; div.comment-send &gt; div.textarea-container &gt; button'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">click</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>接着就是写页面通信的了，可以看到是 popup 向 content 发送请求</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">src/content-script/bilibili.js<span style="flex:1;text-align:right">js</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onload</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'content加载完毕'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">comment</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">runtime</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">onMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">addListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">request</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> sender</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> cmd</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> message </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> request</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">cmd </span><span class="token operator" style="color:hsl(207, 82%, 66%)">===</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'addComment'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token string" style="color:hsl(95, 38%, 62%)">'#comment &gt; div &gt; div.comment &gt; div &gt; div.comment-send &gt; div.textarea-container &gt; textarea'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">val</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token string" style="color:hsl(95, 38%, 62%)">'#comment &gt; div &gt; div.comment &gt; div &gt; div.comment-send &gt; div.textarea-container &gt; button'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">click</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token function" style="color:hsl(207, 82%, 66%)">sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'我收到了你的消息！'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">comment</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-html codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockTitle_P25_">src/popup/App.vue<span style="flex:1;text-align:right">html</span></div><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-html codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">template</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-container</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-header</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">height</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">24</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain">B站小工具</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-header</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-main</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-row</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">:gutter</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">5</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-input</span><span class="token tag" style="color:hsl(355, 65%, 65%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag" style="color:hsl(355, 65%, 65%)">            </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">textarea</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag" style="color:hsl(355, 65%, 65%)">            </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">:rows</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">2</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag" style="color:hsl(355, 65%, 65%)">            </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">请输入内容</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag" style="color:hsl(355, 65%, 65%)">            </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">v-model</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">message</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag" style="color:hsl(355, 65%, 65%)">            </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">mb-5</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag" style="color:hsl(355, 65%, 65%)">          </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-input</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">            </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-button</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">@click</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">addComment</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain">评论</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-button</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-row</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-main</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">el-container</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">template</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">  </span><span class="token script language-javascript keyword module" style="color:hsl(286, 60%, 67%)">export</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:hsl(286, 60%, 67%)">default</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">name</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:hsl(95, 38%, 62%)">'App'</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript function" style="color:hsl(207, 82%, 66%)">data</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      </span><span class="token script language-javascript keyword control-flow" style="color:hsl(286, 60%, 67%)">return</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">message</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:hsl(95, 38%, 62%)">''</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">list</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">open</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript function" style="color:hsl(207, 82%, 66%)">created</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      chrome</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">storage</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">sync</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">get</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript string" style="color:hsl(95, 38%, 62%)">'list'</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript parameter">obj</span><span class="token script language-javascript"> </span><span class="token script language-javascript arrow operator" style="color:hsl(207, 82%, 66%)">=&gt;</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">list</span><span class="token script language-javascript"> </span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token script language-javascript"> obj</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token script language-javascript string" style="color:hsl(95, 38%, 62%)">'list'</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript function" style="color:hsl(207, 82%, 66%)">mounted</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      chrome</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">runtime</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">onMessage</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">addListener</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript parameter">request</span><span class="token script language-javascript parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript parameter"> sender</span><span class="token script language-javascript parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript parameter"> sendResponse</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript string" style="color:hsl(95, 38%, 62%)">'收到来自content-script的消息：'</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript">request</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> sender</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> sendResponse</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript function" style="color:hsl(207, 82%, 66%)">sendResponse</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript string" style="color:hsl(95, 38%, 62%)">'我是后台，我已收到你的消息：'</span><span class="token script language-javascript"> </span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token script language-javascript"> </span><span class="token script language-javascript known-class-name class-name" style="color:hsl(29, 54%, 61%)">JSON</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">stringify</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript">request</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">methods</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      </span><span class="token script language-javascript function" style="color:hsl(207, 82%, 66%)">sendMessageToContentScript</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript parameter">message</span><span class="token script language-javascript parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript parameter"> callback</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        chrome</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">tabs</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">query</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">active</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">currentWindow</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript parameter">tabs</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">          chrome</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">tabs</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">sendMessage</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript">tabs</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token script language-javascript number" style="color:hsl(29, 54%, 61%)">0</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">id</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> message</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript parameter">response</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">            </span><span class="token script language-javascript keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript">callback</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript function" style="color:hsl(207, 82%, 66%)">callback</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript">response</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">          </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      </span><span class="token script language-javascript function" style="color:hsl(207, 82%, 66%)">addComment</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">sendMessageToContentScript</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">cmd</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:hsl(95, 38%, 62%)">'addComment'</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:hsl(355, 65%, 65%)">message</span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript property-access">message</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">          </span><span class="token script language-javascript console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token script language-javascript method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token script language-javascript string" style="color:hsl(95, 38%, 62%)">'来自content的回复：'</span><span class="token script language-javascript"> </span><span class="token script language-javascript operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token script language-javascript"> response</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">        </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">      </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">    </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript">  </span><span class="token script language-javascript punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token script language-javascript"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>代码就不解读了，调用 sendMessageToContentScript 方法即可。相关源码可自行下载查看</p>
<p>实现类似点赞功能也是同理的。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="相关模板">相关模板<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E7%9B%B8%E5%85%B3%E6%A8%A1%E6%9D%BF" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p><span style="display:inline-flex;gap:0.25rem"><span></span><a href="https://github.com/antfu/vitesse-webext" target="_blank" rel="noopener noreferrer">vitesse-webext</a></span></p>
<p><a href="https://www.plasmo.com/" target="_blank" rel="noopener noreferrer">plasmo</a></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="整体体验">整体体验<a href="http://www.yanghao717.cn/en/blog/vue-chrome-extension#%E6%95%B4%E4%BD%93%E4%BD%93%E9%AA%8C" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>当时写 Chrome 插件的效率不能说慢，反正不快就是了，像一些 tips，都得自行封装。用过 Vue 的都知道写网页很方便，写 Chrome 插件未尝不是编写一个网页，当时的我在接触了 Vue 后就萌发了使用 vue 来编写 Chrome 的想法，当然肯定不止我一个这么想过，所以我在 github 上就能搜索到相应的源码，于是就有了这篇文章。</p>
<p>如果有涉及到爬取数据相关的，我肯定是首选使用 HTTP 协议，如果在搞不定我会选择使用 puppeteerjs，不过 Chrome 插件主要还是增强页面功能的，可以实现原本页面不具备的功能。</p>
<p>本文仅仅只是初步体验，简单编写了个小项目，后期有可能会实现一个百度网盘一键填写提取码，Js 自吐 Hooke 相关的。（原本是打算做 pdd 商家自动回复的，客户说要用客户端而不是网页端（客户端可以多号登陆），无奈，这篇博客就拿 B 站来演示了）</p>]]></content:encoded>
            <category>chrome</category>
            <category>plugin</category>
            <category>vue</category>
            <category>develop</category>
        </item>
        <item>
            <title><![CDATA[Chrome插件开发]]></title>
            <link>http://www.yanghao717.cn/en/blog/chrome-plugin-development</link>
            <guid>http://www.yanghao717.cn/en/blog/chrome-plugin-development</guid>
            <pubDate>Mon, 28 Sep 2020 00:00:00 GMT</pubDate>
            <description><![CDATA[前言]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Chrome v3 已发布，而本文基于 v2 编写，故本文内容不再具有时效性。</div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="前言">前言<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E5%89%8D%E8%A8%80" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>相关文章 <a href="https://developer.chrome.com/extensions/manifest" target="_blank" rel="noopener noreferrer">谷歌官方文档</a> (需翻墙)</p>
<p><a href="http://blog.haoji.me/chrome-plugin-develop.html" target="_blank" rel="noopener noreferrer">Chrome 插件开发全攻略</a> （强烈推荐看这一篇！）</p>
<p>你只需要看完上面那篇文章和掌握一些前端开发基础，就足以自行编写一个 Chrome 插件。本文也是基于上面文章加上自己之前写的插件所记。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="什么是-chrome-插件">什么是 Chrome 插件<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E4%BB%80%E4%B9%88%E6%98%AF-chrome-%E6%8F%92%E4%BB%B6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>如果你用过 Chrome 浏览器的话，也许会用到过一些插件，其中比较知名的就是油猴插件，通过这些插件能够帮你例如自动完成一些功能，屏蔽广告，相当于一个浏览器内置的脚本。应该来说这是 Chrome 扩展开发，不过说 Chrome 插件更顺口，后文也会说成 Chrome 插件。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="安装-chrome-插件">安装 Chrome 插件<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E5%AE%89%E8%A3%85-chrome-%E6%8F%92%E4%BB%B6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>首先打开 Chrome，如下图即可进入插件的管理页面</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20200922225606159.png" alt="image-20200922225606159" class="img_ev3q"></p>
<p>这时候记得把右上角的开发者模式给勾上，如果不勾上的话你无法直接将文件夹拖入 Chrome 进行安装，就只能安装<code>.crx</code>格式的文件。Chrome 要求插件必须从它的 Chrome 应用商店（需要翻墙）安装，其它任何网站下载的都无法直接安装，所以可以把<code>crx</code>文件解压，然后通过开发者模式直接加载。</p>
<p>然后将写好的 Chrome 插件文件夹拖入到刚刚打开的插件管理页面即可。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="chrome-插件知识">Chrome 插件知识<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#chrome-%E6%8F%92%E4%BB%B6%E7%9F%A5%E8%AF%86" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="manifestjson">manifest.json<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#manifestjson" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>是<code>manifest.json</code>切记不要英文单词打错字，一定要有这个文件，且需要放在根目录上，否则就会出现未能成功加载扩展程序的错误。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="backgroundhtml-和-backgroundjs">background.html 和 background.js<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#backgroundhtml-%E5%92%8C-backgroundjs" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>可以理解为后台，同时这个页面会一直常驻在浏览器中，而主要 background 权限非常高，几乎可以调用所有的 Chrome 扩展 API（除了 devtools），基本很多操作都是放在 background 执行，返回给 content，而且它可以<strong>无限制跨域</strong>，也就是可以跨域访问任何网站而无需要求对方设置<code>CORS</code>。这对我们后面要在 content 中发送跨域请求至关重要！</p>
<p>我习惯的做法是通过<code>”page”："background.html"</code>来导入<code>background.js</code>或其他 js 代码，如下</p>
<div class="language-json codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-json codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// manifest.json</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"> </span><span class="token property" style="color:hsl(355, 65%, 65%)">"background"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token property" style="color:hsl(355, 65%, 65%)">"page"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"background.html"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-html codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-html codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">&lt;!-- background.html --&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token doctype punctuation" style="color:hsl(220, 14%, 71%)">&lt;!</span><span class="token doctype doctype-tag" style="color:hsl(220, 14%, 71%)">doctype</span><span class="token doctype" style="color:hsl(220, 14%, 71%)"> </span><span class="token doctype name" style="color:hsl(220, 14%, 71%)">html</span><span class="token doctype punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">html</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">head</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">title</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain">背景页</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">title</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">meta</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">charset</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">utf-8</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">meta</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">http-equiv</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">Content-Type</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">content</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">text/html; charset=utf-8</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">head</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">body</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">text/javascript</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">src</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">js/jquery.js</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token script"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">text/javascript</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">src</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">js/background.js</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token script"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">body</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">html</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>如果是 scripts 方式导入 js 文件则需要反复修改<code>manifest.json</code>文件。</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="关于乱码">关于乱码<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E5%85%B3%E4%BA%8E%E4%B9%B1%E7%A0%81" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>有时候你在编写代码中出现了中文可能会出现了如下的乱码，</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20200923214834081.png" alt="image-20200923214834081" class="img_ev3q"></p>
<p>我遇到的原因是就是我原先的<code>background.html</code>代码写成如下的情况</p>
<div class="language-html codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-html codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">text/javascript</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">src</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">js/jquery.js</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token script"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">text/javascript</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">src</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">js/background.js</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token script"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">script</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>没错，就只写了这两个行，就出现乱码（将 UTF-8 的编码变为了 windows1252），而只需要把 background.html 代码修改成正常的 HTML 结构，也就是上上面的那个代码即可解决该乱码情况。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="contentjs">content.js<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#contentjs" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>我们主要的向页面注入脚本就依靠这个文件，相当于给页面添加了一个 js 文件，但是<code>content</code>和原始页面<strong>共享 DOM</strong>，但是不共享 JS，如要<strong>访问页面 JS（例如某个 JS 变量）</strong>，只能通过<code>injected js</code>来实现（后文会提到）。并且<code>content</code>不能访问绝大部分<code>chrome.xxx.api</code>，除了下面这 4 种：</p>
<ul>
<li>chrome.extension(getURL , inIncognitoContext , lastError , onRequest , sendRequest)</li>
<li>chrome.i18n</li>
<li>chrome.runtime(connect , getManifest , getURL , id , onConnect , onMessage , sendMessage)</li>
<li>chrome.storage</li>
</ul>
<p>这些 API 绝大部分时候都够用了，非要调用其它 API 的话，你还可以通过通信来实现让 background 来帮你调用。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="injectjs">inject.js<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#injectjs" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>上文也说到了<code>content</code>是<strong>无法访问页面中的 JS</strong>，可以操作 DOM，但是 DOM 却不能调用它，也就是无法在 DOM 中通过绑定事件的方式调用<code>content</code>中的代码（包括直接写<code>onclick</code>和<code>addEventListener</code>2 种方式都不行），但是，<strong>在页面上添加一个按钮并调用插件的扩展 API</strong>是一个很常见的需求，那该怎么办呢？这时候就需要注入 inject.js 这个文件</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">addEventListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'DOMContentLoaded'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">injectCustomJs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 向页面注入JS</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">injectCustomJs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">jsPath</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  jsPath </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> jsPath </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'js/inject.js'</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">var</span><span class="token plain"> temp </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">createElement</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'script'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  temp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">setAttribute</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'type'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'text/javascript'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 获得的地址类似：chrome-extension://ihcokhadfjfchaeagdoclpnjdiokfakg/js/inject.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  temp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">src</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">extension</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getURL</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">jsPath</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  temp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onload</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 放在页面不好看，执行完后移除掉</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">parentNode</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">removeChild</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">head</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">appendChild</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">temp</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>还没有完，因为注入有权限，所以需要在 manifest.json 声明一下这个文件。也就是下面的这行代码</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 普通页面能够直接访问的插件资源列表，如果不设置是无法直接访问的</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token string-property property" style="color:hsl(355, 65%, 65%)">"web_accessible_resources"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"js/inject.js"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>这样你就能调用</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="关于消息通信">关于消息通信<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E5%85%B3%E4%BA%8E%E6%B6%88%E6%81%AF%E9%80%9A%E4%BF%A1" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>Chrome 插件主要就 4 个部分组成，injected，content，popup，background，但这 4 个部分所对应的权限，应用都有可能各自不一，这时候就需要通过消息通信，将对应的数据发送到对应的文件，主要也就如下四种通信方式：</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="popup-和-background">popup 和 background<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#popup-%E5%92%8C-background" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>popup 可以直接调用 background 中的 JS 方法，也可以直接访问 background 的 DOM：</p>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// background.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">test</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">alert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'我是background！'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// popup.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">var</span><span class="token plain"> bg </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">extension</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getBackgroundPage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">bg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">test</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 访问bg的函数</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">alert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">bg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">body</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">innerHTML</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 访问bg的DOM</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><code>background</code>访问<code>popup</code>如下（前提是<code>popup</code>已经打开）：</p>
<div class="language-javascript codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-javascript codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">var</span><span class="token plain"> views </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">extension</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getViews</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">type</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'popup'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">views</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">views</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">location</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">href</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="popup-或-bg-与-content">popup 或 bg 与 content<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#popup-%E6%88%96-bg-%E4%B8%8E-content" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="popup-或-bg-向-content-发送请求">popup 或 bg 向 content 发送请求<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#popup-%E6%88%96-bg-%E5%90%91-content-%E5%8F%91%E9%80%81%E8%AF%B7%E6%B1%82" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h5>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">//background.js或popup.js：</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">sendMessageToContentScript</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">message</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> callback</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">tabs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">query</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">active</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">currentWindow</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">tabs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">tabs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">sendMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">tabs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> message</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">callback</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">callback</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">sendMessageToContentScript</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">cmd</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'test'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">value</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'你好，我是popup！'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'来自content的回复：'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><code>content.js</code>通过监听事件接收：</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">runtime</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">onMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">addListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">request</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> sender</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token comment" style="color:hsl(220, 10%, 40%)">// console.log(sender.tab ?"from a content script:" + sender.tab.url :"from the extension");</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">request</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cmd</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'test'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">alert</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">request</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">value</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'我收到了你的消息！'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="content-向-popup-或-bg">content 向 popup 或 bg<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#content-%E5%90%91-popup-%E6%88%96-bg" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h5>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// content.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">runtime</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">sendMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">greeting</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'你好，我是content呀，我主动发消息给后台！'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'收到来自后台的回复：'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">//background.js 或 popup.js：</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token comment" style="color:hsl(220, 10%, 40%)">// 监听来自content的消息</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">runtime</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">onMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">addListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">request</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> sender</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'收到来自content的消息：'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">request</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'我是后台，我已收到你的消息：'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token known-class-name class-name" style="color:hsl(29, 54%, 61%)">JSON</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">stringify</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">request</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>注意：</p>
<ul>
<li>content_scripts 向<code>popup</code>主动发消息的前提是 popup 必须打开！否则需要利用 background 作中转；</li>
<li>如果 background 和 popup 同时监听，那么它们都可以同时收到消息，但是只有一个可以 sendResponse，一个先发送了，那么另外一个再发送就无效；</li>
</ul>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="injected-和-content">injected 和 content<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#injected-%E5%92%8C-content" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p>主要就是<code>injected</code>向<code>content</code>发送，<code>injected</code>无需监听。</p>
<p><code>content</code>和页面内的脚本（<code>injected</code>自然也属于页面内的脚本）之间唯一共享的东西就是页面的 DOM 元素，有 2 种方法可以实现二者通讯，：</p>
<ol>
<li>可以通过<code>window.postMessage</code>和<code>window.addEventListener</code>来实现二者消息通讯；（推荐）</li>
<li>通过自定义 DOM 事件来实现（我就懒得写了，没怎么用到）；</li>
</ol>
<p><code>injected</code>中：</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">postMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">test</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'你好！'</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'*'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p><code>content script中</code>：</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token dom variable" style="color:hsl(207, 82%, 66%)">window</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">addEventListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token string" style="color:hsl(95, 38%, 62%)">'message'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="injected-与-popup">injected 与 popup<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#injected-%E4%B8%8E-popup" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h4>
<p><code>injected</code>无法直接和<code>popup</code>通信，必须借助<code>content</code>作为中间人。不过一般这种都少，直接和 bg 通信即可。</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="我的模板">我的模板<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E6%88%91%E7%9A%84%E6%A8%A1%E6%9D%BF" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h2>
<p>关于 Chrome 的主要内容也就这些，实际开发如果有个模板就能大大方便开发，在原文章中该作者已经分享了有对应的源代码，这里放上我自写的 Chrome 模板编写过程。</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210820004414785.png" alt="image-20210820004414785" class="img_ev3q"></p>
<p>当然，这里需要提几点地方：</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="配置项与-storage">配置项与 storage<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E9%85%8D%E7%BD%AE%E9%A1%B9%E4%B8%8E-storage" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>首先是配置方面，有时候插件的内的选项是要记录，以便下一次在启动插件的时候还是上一次的配置。先看代码</p>
<div class="language-html codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-html codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">&lt;!-- popup.js --&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">config-item</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">input</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">checkbox</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">id</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">config1</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">box configs</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">label</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">hand</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">for</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">config1</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">title</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">配置1</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain">配置1</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">label</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">config-item</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">input</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">type</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">checkbox</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">id</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">config2</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">box configs</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;</span><span class="token tag" style="color:hsl(355, 65%, 65%)">label</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">hand</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">for</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">config2</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag" style="color:hsl(355, 65%, 65%)"> </span><span class="token tag attr-name" style="color:hsl(29, 54%, 61%)">title</span><span class="token tag attr-value punctuation attr-equals" style="color:hsl(220, 14%, 71%)">=</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag attr-value" style="color:hsl(95, 38%, 62%)">配置2</span><span class="token tag attr-value punctuation" style="color:hsl(220, 14%, 71%)">"</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain">配置2</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">label</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&lt;/</span><span class="token tag" style="color:hsl(355, 65%, 65%)">div</span><span class="token tag punctuation" style="color:hsl(220, 14%, 71%)">&gt;</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// popup.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> configs </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getElementsByClassName</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'configs'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i</span><span class="token operator" style="color:hsl(207, 82%, 66%)">++</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> type </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">type</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">type </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'checkbox'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onchange</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">storage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">sync</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">set</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">          </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">checked</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">storage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">sync</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">items</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">checked</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> items</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">else</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">type </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'text'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> type </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'password'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method-variable function-variable method function property-access" style="color:hsl(207, 82%, 66%)">onblur</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">storage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">sync</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">set</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">value</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">storage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">sync</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">get</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">items</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">value</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> items</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">configs</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">''</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>可能需要多花点时间才能理解上面代码的意思，首先我在需要记录配置的地方添加了一个类<code>configs</code>，然后通过 js 代码遍历类名为<code>configs</code>，接着判断是多选框，还是输入框，input 的 id 为键名，value 为键值，来 set 或 get <code>chrome.storage</code>的值，然后进行事件绑定为修改配置后在记录一下配置。这里需要注意一下，写配置的时候<code>{ [this.id]: this.value }</code>这里的<code>this.id</code>是加了中括号的，原因就是这个 this.id 是变量，如果不加的话默认为字符串，但在这里有.所以是会报错的。</p>
<p>强烈不建议用 localStorage，我当初第一遍学的时候没学明白，我还通过消息通信将配置信息发给<code>content</code>，然后还用 localStorage 记录一遍，现在才发现<code>chrome.storage</code>是针对插件全局的，即使你在<code>background</code>或者<code>popup中</code>保存的数据，在<code>content</code>也能获取到。</p>
<p>当然这种读写配置的也算麻烦了，不像桌面级开发的读写配置。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="悬浮窗">悬浮窗<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E6%82%AC%E6%B5%AE%E7%AA%97" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>首先，一般对于网页端的插件，能提供的页面最好方式就是悬浮窗了，这里我也是通过 DOM 创建元素生成对象。而这个悬浮窗是针对页面的，而不是像 popup 那样。相关的页面初始化代码如下，</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token keyword" style="color:hsl(286, 60%, 67%)">var</span><span class="token plain"> view </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">show</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">true</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">cache</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">count</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">type</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">mouse_x</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">mouse_y</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">initView</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token template-string string" style="color:hsl(95, 38%, 62%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">	&lt;div id="box"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">style="position: fixed;border: 1px double rgb(0,0,0); width: 300px; top: 30px; right: 1%; z-index: 999999; font-size: 15px; background-color: rgb(255,255,255); color: #000000;user-select:none;"&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">&lt;div style="position: relative;"&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">	&lt;button name="show"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">		style="position: absolute;top: 50%;right:1%; margin-top: 7px; line-height: 18px;overflow:hidden;border: 0px double rgb(0,0,0);cursor:pointer;font-size: 18px;background-color: rgb(255,255,255);"&gt;－</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">	&lt;/button&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">&lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">&lt;div id="kz_title" style="height: auto; margin: 5px; font-size: 16px;"&gt;日志&lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="display:inline-block;color:hsl(95, 38%, 62%)"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">&lt;div id="kz_main"&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">	&lt;hr&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">	&lt;form&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">		&lt;div style="margin-top: 5px;overflow-y: auto;"&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">			&lt;button id="kz_id1" name="cleanlog"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">				style="margin-left: 10px;float:left;border-radius:0em;overflow:hidden;border: 1px double rgb(0,0,0);background-color: rgb(255,255,255);"&gt;功能按钮&lt;/button&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">			&lt;button id="kz_id2" name="cleanlog"</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">				style="margin-left: 10px;float:left;border-radius:0em;overflow:hidden;border: 1px double rgb(0,0,0);background-color: rgb(255,255,255);"&gt;功能按钮&lt;/button&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">		&lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">	&lt;/form&gt;&lt;br&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">	&lt;div id="logList"&gt;&lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">&lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">&lt;/div&gt;</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token template-string string" style="color:hsl(95, 38%, 62%)">	</span><span class="token template-string template-punctuation string" style="color:hsl(95, 38%, 62%)">`</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">info</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">find</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#info'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">kz_title</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">find</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#kz_title'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">kz_main</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">find</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#kz_main'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">appendTo</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'body'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">delegate</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'button'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'click'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">stopImmediatePropagation</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">stopPropagation</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    e</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">preventDefault</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> name </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">attr</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'name'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">name </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'show'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">html</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">show</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">?</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'＋'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'－'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">show</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!</span><span class="token plain">view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">show</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">kz_main</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">slideToggle</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">addViewMouseListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'日志输出1'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'日志输出2'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'日志输出3'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">addViewMouseListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">bind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'mousedown'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">x</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">position</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">left</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">y</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">this</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">position</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">top</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">mouse_x</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">originalEvent</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientX</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">mouse_y</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">originalEvent</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientY</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">//console.log(view.cache.mouse_x, view.cache.mouse_y, view.cache.x, view.cache.y)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">bind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'mousemove'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">//计算出现在的位置是多少</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">mouse_x</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">mouse_y</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">y</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">kz_title</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">return</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> new_position_left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">originalEvent</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientX</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">mouse_x</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">x</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      new_position_top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">originalEvent</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">clientY</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">mouse_y</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">y</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">//加上边界限制</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">new_position_top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">//当上边的偏移量小于0的时候，就是上边的临界点，就让新的位置为0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      new_position_top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">//如果向下的偏移量大于文档对象的高度减去自身的高度，就让它等于这个高度</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      new_position_top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&amp;&amp;</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      new_position_top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">height</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token comment" style="color:hsl(220, 10%, 40%)">//右限制</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">new_position_left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">width</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">width</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      new_position_left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">width</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">width</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">new_position_left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token comment" style="color:hsl(220, 10%, 40%)">//左边的偏移量小于0的时候设置 左边的位置为0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      new_position_left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">float</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">css</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">left</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> new_position_left </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'px'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">top</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> new_position_top </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'px'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">bind</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'mouseup'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">mouse_x</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    view</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cache</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">mouse_y</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">msg</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> color</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> date </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">new</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(29, 54%, 61%)">Date</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> t </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> date</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getHours</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">':'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> date</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getMinutes</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">':'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> date</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">getSeconds</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  msg </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> t </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'  '</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> msg</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> div </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'&lt;div class="log"&gt;&lt;/div&gt;'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">css</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token string-property property" style="color:hsl(355, 65%, 65%)">'border-color'</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'rgba(121, 187, 255, 0.2)'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token string-property property" style="color:hsl(355, 65%, 65%)">'background-color'</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'rgba(121, 187, 255, 0.2)'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> log </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'&lt;p&gt;&lt;span style="color: '</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">color </span><span class="token operator" style="color:hsl(207, 82%, 66%)">||</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'#409EFF'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'"&gt;'</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> msg </span><span class="token operator" style="color:hsl(207, 82%, 66%)">+</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'&lt;/span&gt;&lt;/p&gt;'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'.log'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">15</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">let</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(207, 82%, 66%)">=</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">0</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'.log'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token plain"> </span><span class="token number" style="color:hsl(29, 54%, 61%)">15</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">;</span><span class="token plain"> i</span><span class="token operator" style="color:hsl(207, 82%, 66%)">++</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'.log'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain">i</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">remove</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token function" style="color:hsl(207, 82%, 66%)">$</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'#logList'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">append</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">div</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">append</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>然后在 content.js 内容的对页面 url 判断是否需要初始化悬浮窗即可</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token dom variable" style="color:hsl(207, 82%, 66%)">document</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">addEventListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'DOMContentLoaded'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token dom variable" style="color:hsl(207, 82%, 66%)">location</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">host</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">indexOf</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">'chaoxing'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">!=</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">-</span><span class="token number" style="color:hsl(29, 54%, 61%)">1</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token function" style="color:hsl(207, 82%, 66%)">initView</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>如何发挥就看各位了。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="跨域请求">跨域请求<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E8%B7%A8%E5%9F%9F%E8%AF%B7%E6%B1%82" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>关于跨域请求，我当初在学习 Chrome 插件的时候，就是卡在了跨域这个地方，那时候前端学的浅，对跨域都不知道处理，然后放弃学习了 Chrome 插件一段时间，后来有时间了，想在补一补之前没写完的 Chrome 扩展搞完。然而跨域请求非常简单，而我那时候之所以卡住就是因为没好好看文档，搞不定的地方就多看几遍说不准就搞定了。</p>
<p>首先要使 Chrome 插件访问跨域资源，需要在 manifest.json 文件中声明要访问的域如下：</p>
<div class="language-json codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-json codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"permissions"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token string" style="color:hsl(95, 38%, 62%)">"http://www.google.com/"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token string" style="color:hsl(95, 38%, 62%)">"http://*.google.com/"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token string" style="color:hsl(95, 38%, 62%)">"https://*.google.com/"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token string" style="color:hsl(95, 38%, 62%)">"http://*/"</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>建议直接直接暴力点写上</p>
<div class="language-json codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-json codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token property" style="color:hsl(355, 65%, 65%)">"permissions"</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">[</span><span class="token string" style="color:hsl(95, 38%, 62%)">"http://*/*"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"https://*/*"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>然后封装一下对应的 ajax 请求，因为在 content 内进行 ajax 请求，是会在控制台输出跨域请求拦截，或者是 HTTPS 访问 HTTP 不安全等问题，这时候就需要通过消息通信，将 content 要发送的请求发送给 bg，让 bg 请求，然后等 bg 请求完毕，再将数据返回到 content 即可。下面是我对应的封装代码</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// background.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">runtime</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">onMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">addListener</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">req</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> sender</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> sender</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token keyword control-flow" style="color:hsl(286, 60%, 67%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">cmd</span><span class="token plain"> </span><span class="token operator" style="color:hsl(207, 82%, 66%)">==</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'ajax'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    $</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">ajax</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">url</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">url</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">type</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> req</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">data</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">async</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token boolean" style="color:hsl(29, 54%, 61%)">false</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token function-variable function" style="color:hsl(207, 82%, 66%)">success</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">        </span><span class="token function" style="color:hsl(207, 82%, 66%)">sendResponse</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">res</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token comment" style="color:hsl(220, 10%, 40%)">// content.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(207, 82%, 66%)">sendAjaxToBg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">url</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> type</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> data</span><span class="token parameter punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token parameter"> callback</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  chrome</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token property-access">runtime</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">sendMessage</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">cmd</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">'ajax'</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">url</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> url</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">type</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> type</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:hsl(355, 65%, 65%)">data</span><span class="token operator" style="color:hsl(207, 82%, 66%)">:</span><span class="token plain"> data </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">      </span><span class="token function" style="color:hsl(207, 82%, 66%)">callback</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">    </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">  </span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>这里的话我通信发送的是 js 对象，其中 cmd 决定了我要的操作，后台通过判断 cmd 来执行对应的操作。比较不好理解的是回调函数，由于 JS 自身语言的因素与浏览器的问题，很多事件都是先挂着，后做完在回调，所以我这里就封装成这种形式，例如</p>
<div class="language-js codeBlockContainer_APcc theme-code-block" style="--prism-background-color:hsl(220, 13%, 18%);--prism-color:hsl(220, 14%, 71%)"><div class="codeBlockContent_m3Ux"><pre tabindex="0" class="prism-code language-js codeBlock_qGQc thin-scrollbar" style="background-color:hsl(220, 13%, 18%);color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><code class="codeBlockLines_p187"><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token function" style="color:hsl(207, 82%, 66%)">sendAjaxToBg</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token string" style="color:hsl(95, 38%, 62%)">"http://..."</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token string" style="color:hsl(95, 38%, 62%)">"GET"</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword null nil" style="color:hsl(286, 60%, 67%)">null</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">,</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(286, 60%, 67%)">function</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token parameter">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token console class-name" style="color:hsl(29, 54%, 61%)">console</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">.</span><span class="token method function property-access" style="color:hsl(207, 82%, 66%)">log</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">(</span><span class="token plain">response</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain">	</span><span class="token spread operator" style="color:hsl(207, 82%, 66%)">...</span><span class="token plain">code</span><br></span><span class="token-line" style="color:hsl(220, 14%, 71%);text-shadow:0 1px rgba(0, 0, 0, 0.3)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">}</span><span class="token punctuation" style="color:hsl(220, 14%, 71%)">)</span><br></span></code></pre><div class="buttonGroup_6DOT"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_FhaS" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_phi_"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_FfTR"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>
<p>这只是一个简单的 http 封装发送，如果要更复杂的话还可以添加协议头和 cookies，这里就不在补充了。</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="一些自写-chrome-插件">一些自写 Chrome 插件<a href="http://www.yanghao717.cn/en/blog/chrome-plugin-development#%E4%B8%80%E4%BA%9B%E8%87%AA%E5%86%99-chrome-%E6%8F%92%E4%BB%B6" class="hash-link" aria-label="Direct link to heading" title="Direct link to heading">​</a></h3>
<p>实际上已经写过一些 Chrome 插件了，奈何写的比较烂或没搞完，也就暂时先不发，有时间会再整理一下自己所写的。</p>
<p>一个验证码识别，有时候在登录的时候需要输入验证码是件非常痛苦的事情。于是乎我就通过调用打码 Api 接口写了个自动识别验证码并填写的。也提供了非常方便的右键识别验证码的功能。具体效果如图（实际上还是得第一次先确认要识别的图片框与输入框，下次加载的时候需要手动点击验证码才会自动生效，还是不够智能的，不过成就感十足）</p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/image-20210820001938051.png" alt="image-20210820001938051" class="img_ev3q"></p>
<p><img decoding="async" loading="lazy" src="https://img.night.cn/wydm.gif" alt="wydm" class="img_ev3q"></p>
<p>另一个是基于某布大佬的 WebHook 工具，所更改的，不过一直停滞着，有空将其完善一下。</p>]]></content:encoded>
            <category>chrome</category>
            <category>plugin</category>
            <category>develop</category>
        </item>
    </channel>
</rss>