{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-11-17-stdsuperman","result":{"data":{"currentBlog":{"id":"f02f2d33-403a-5936-b733-bac2a216c76d","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020122/1606879260376-1585217744291-%E6%91%84%E5%9B%BE%E7%BD%91_400730082_wx.jpg","authors":["陌小路"],"categories":["user-stories"],"date":"2020-11-17T00:00:00.000Z","title":"Serverless 从懵逼到实战","description":"一篇非常完善的入门级的教程！","authorslink":["https://github.com/STDSuperman"],"translators":null,"translatorslink":null,"tags":["Serverless","云函数"],"keywords":null,"outdated":null},"wordCount":{"words":408,"sentences":94,"paragraphs":93},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-11-17-stdsuperman.md","fields":{"slug":"/blog/2020-11-17-stdsuperman/","keywords":["java","react","serverless","vue","website","云函数","函数","部署","serverless","目录","代码"]},"html":"<blockquote>\n<p>原文链接：<a href=\"https://juejin.cn/post/6895346770177687566\">https://juejin.cn/post/6895346770177687566</a></p>\n</blockquote>\n<h2 id=\"定义\"><a href=\"#%E5%AE%9A%E4%B9%89\" aria-label=\"定义 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>定义</h2>\n<p><code class=\"language-text\">Serverless</code> 是一种执行模型<code class=\"language-text\">（execution model）</code>。在这种模型中，云服务商负责通过动态地分配资源来执行一段代码。云服务商仅仅收取执行这段代码所需要资源的费用。代码通常会被运行在一个无状态的容器内，并且可被多种事件触发（<code class=\"language-text\">http 请求</code>、数据库事件、监控报警、文件上传、定时任务……）。代码常常会以函数<code class=\"language-text\">（function）</code>的形式被上传到云服务商以供执行，因此<code class=\"language-text\">Serverless</code>也会被称作<code class=\"language-text\">Functions as a Service</code> 或者 <code class=\"language-text\">FaaS</code>。</p>\n<ul>\n<li><code class=\"language-text\">BaaS</code>: <code class=\"language-text\">Backend as a Service</code>，这里的<code class=\"language-text\">Backend</code>可以指代任何第三方提供的应用和服务，比如提供云数据库服务的<code class=\"language-text\">Firebase</code>和<code class=\"language-text\">Parse</code>，提供统一用户身份验证服务的<code class=\"language-text\">Auth0</code>和<code class=\"language-text\">Amazon Cognito</code>等。</li>\n<li><code class=\"language-text\">FaaS</code>: <code class=\"language-text\">Functions as a Service</code>，应用以函数的形式存在，并由第三方云平台托管运行，比如腾讯云云函数 SCF、AWS Lambda 等。</li>\n</ul>\n<h2 id=\"背景\"><a href=\"#%E8%83%8C%E6%99%AF\" aria-label=\"背景 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>背景</h2>\n<p>那么我们为什么需要<code class=\"language-text\">Serverless</code>呢？对于这个问题来说，我们可以从我们日常个人的开发中找到原因。无论是个人博客，亦或者是小程序，还是个人网站，我们都要面临一个问题就是，怎么解决服务器部署相关的问题。</p>\n<p>对于常规的项目来说，一般的流程莫过于：购买服务器 => 域名备案（这一步可能可以不用，看个人需求） => 环境搭建 => 部署</p>\n<p>那么我们如果仅仅是想要开发一个几乎不太需要多强的后台支持时，却要去做这么多操作，这对于整个项目的开发来说是十分不友好的，很容易就会让人放弃上线的念头。</p>\n<p>那么<code class=\"language-text\">Serverless</code>就是用于解决这个问题的存在，他具备托管服务端各项功能的能力，让你无需进行上述繁琐的步骤就能轻松让你的网站或服务正常运行且可访问，同时能够极大降低个人的维护成本，这对于广大开发者而言无疑是十分实用的。</p>\n<h2 id=\"serverless特点\"><a href=\"#serverless%E7%89%B9%E7%82%B9\" aria-label=\"serverless特点 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Serverless特点</h2>\n<h3 id=\"1-低成本\"><a href=\"#1-%E4%BD%8E%E6%88%90%E6%9C%AC\" aria-label=\"1 低成本 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 低成本</h3>\n<p>众所周知，我们购买一个云服务器，抛去人力成本不计，单从收费方式上来分析，各厂商都是采用按月计费的方式来收取，也就是即使没有人访问你的网站或服务，每月需要支付的租金都是不变的。</p>\n<p>然后再来看<code class=\"language-text\">Serverless</code>应用，它是按你实际使用的资源量来进行计价的，可以理解为你用多少付多少，可以类比于我们手机流量的方式来收取。同时，根据福布斯2015年发布的一份研究报告，从全年来看，一个典型的数据中心里的服务器平均资源使用率只有可怜的 5%~15%，也就是说如果全部使用<code class=\"language-text\">Serverless</code>，理论上至少可以节省80%的运行成本。</p>\n<p>对比分析之后，<code class=\"language-text\">Serverless</code>在成本方面无疑是较低的。</p>\n<h3 id=\"2-自动扩缩容\"><a href=\"#2-%E8%87%AA%E5%8A%A8%E6%89%A9%E7%BC%A9%E5%AE%B9\" aria-label=\"2 自动扩缩容 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 自动扩缩容</h3>\n<p>正如上文所述，函数即应用，每一个函数只会服务于特定的功能，它可以随意的进行动态拓展或者收缩容量，同时不会影响到其他函数，并且粒度更小，速度更快。反观我们的单体应用和微服务来说，借助于各种容器编排技术，虽然也能实现自动扩缩容，但由于粒度关系，相比函数，始终会存在一定的资源浪费。</p>\n<h3 id=\"3-事件驱动\"><a href=\"#3-%E4%BA%8B%E4%BB%B6%E9%A9%B1%E5%8A%A8\" aria-label=\"3 事件驱动 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. 事件驱动</h3>\n<p>函数本质上实现的是一种IPO<code class=\"language-text\">（Input-Process-Output）</code>模型，它是短暂的，是即用即走的。这点是函数区别于单体应用和微服务的另一个特征。不管是单体应用，还是微服务，都是系统中的常驻进程，即便你不使用，它依旧会一直运行。而对于函数来说，没有请求就不需要消耗任何资源，只有在收到请求时才会调动资源进行响应，完成之后就会立刻释放资源，这在节省资源方面无疑是巨大的优点。</p>\n<h3 id=\"4-无状态\"><a href=\"#4-%E6%97%A0%E7%8A%B6%E6%80%81\" aria-label=\"4 无状态 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. 无状态</h3>\n<p>从事件驱动能力中我们提到了它只有在收到请求时才会工作起来，工作完成之后就立刻被释放，也就是各种运行时的内存缓存都是没有太大效益的，不仅如此，同一个请求方式，第二次访问服务时很有可能被调度到其他新的机器上，所以本地缓存方式依旧是失效的，函数只能使用外存（比如<code class=\"language-text\">Redis</code>，数据库）进行缓存，而操作外存都需要通过网络，性能跟内存、本地硬盘相比差了一到两个数量级。</p>\n<h2 id=\"第一个云函数\"><a href=\"#%E7%AC%AC%E4%B8%80%E4%B8%AA%E4%BA%91%E5%87%BD%E6%95%B0\" aria-label=\"第一个云函数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>第一个云函数</h2>\n<p>这里将利用腾讯云作为演示平台，首先你需要先登录到<a href=\"https://cloud.tencent.com/\">腾讯云</a>。</p>\n<p>接着打开<a href=\"https://console.cloud.tencent.com/scf/list\">云函数控制台</a>：</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/14/DP8GUP.png\" alt=\"腾讯云函数控制台\"></p>\n<p>我们选择新建一个云函数</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/14/DP8rEq.png\" alt=\"新建云函数\"></p>\n<p>在这里我们可以自由选择开发的语言以及是否需要模板，为了演示方便还是选择勾选模板，然后点击完成，就能进入我们正式的代码编写环节了。</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/14/DP8hr9.png\" alt=\"代码工作台\"></p>\n<p>这里我们可以随意的修改函数的返回值，接着就能对它进行测试啦。</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/14/DP8jrd.png\" alt=\"测试云函数\"></p>\n<p>当你看到运行后的返回结果和你编写的代码返回值一致时就说明你的云函数已经在工作中了。</p>\n<p>当然，仅仅只是这么测试一下自然很不过瘾，我还想能通过<code class=\"language-text\">http</code>请求的方式来访问这个云函数，又该怎么做呢？</p>\n<p>这个其实也很简单，我们选择左侧的触发管理，新建一个触发策略，并选择触发方式为<code class=\"language-text\">API网关</code>，然后直接点击提交。</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/14/DPGeZn.png\" alt=\"新建触发策略\"></p>\n<p><img src=\"https://s3.ax1x.com/2020/11/14/DPGtd1.png\" alt=\"具体操作步骤\"></p>\n<p>这个时候我们其实已经可以通过<code class=\"language-text\">url</code>进行访问了，我们复制访问路径，然后在浏览器访问，就能看到我们云函数给我们返回的内容了。</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/14/DPJCwR.png\" alt=\"复制链接\"></p>\n<p><img src=\"https://s3.ax1x.com/2020/11/14/DPGboq.png\" alt=\"访问步骤\"></p>\n<h2 id=\"本地开发\"><a href=\"#%E6%9C%AC%E5%9C%B0%E5%BC%80%E5%8F%91\" aria-label=\"本地开发 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>本地开发</h2>\n<p>介绍完在云平台上创建函数的方式，接下来就该介绍如何进行本地开发并部署的方式了：</p>\n<h3 id=\"1-安装\"><a href=\"#1-%E5%AE%89%E8%A3%85\" aria-label=\"1 安装 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 安装</h3>\n<p>这里将以<code class=\"language-text\">Node</code>作为开发语言进行演示，更多语言安装方式请参考<a href=\"https://cloud.tencent.com/document/product/583/44753\">官方文档</a>。</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"71122939949023440000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`npm i serverless -g`, `71122939949023440000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">npm</span> i serverless -g</code></pre></div>\n<p>先安装对应的包，这里可以安装到全局便于以后使用。</p>\n<p>接着使用相关命令生成<code class=\"language-text\">demo</code>模板项目：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"77810273525707500000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`serverless init sls-demo`, `77810273525707500000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">serverless init sls-demo</code></pre></div>\n<blockquote>\n<p>这里有个小插曲，笔者用官方给的简写<code class=\"language-text\">sls init sls-demo</code>的时候，发现跳出来一个奇怪的输入，笔者暂时就没去深究了，所以还是改用全写就行了。</p>\n</blockquote>\n<p>创建完成之后，我们进入生成目录，映入眼帘的就是一个<code class=\"language-text\">src</code>目录和一个<code class=\"language-text\">serverless.yml</code>配置文件。我们一般将源代码都放置在<code class=\"language-text\">src</code>目录下，当然，这个也看个人喜好，如果你不喜欢，可以选择放在任意文件夹下，不过就需要修改一下配置文件中的<code class=\"language-text\">src</code>字段对应的值了，它默认是指向了当前目录下的<code class=\"language-text\">src</code>目录。</p>\n<p>组件信息：</p>\n<table>\n<thead>\n<tr>\n<th align=\"center\">字段名</th>\n<th align=\"center\">是否必选</th>\n<th align=\"center\">说明</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"center\">component</td>\n<td align=\"center\">是</td>\n<td align=\"center\">component 的名称，可使用 sls registry 命令查询可引入的组件。</td>\n</tr>\n<tr>\n<td align=\"center\">name</td>\n<td align=\"center\">是</td>\n<td align=\"center\">创建的实例名称，每个组件在部署时将创建一个实例。</td>\n</tr>\n</tbody>\n</table>\n<p>参数信息（inputs下对应的字段）：\n| 字段名  | 说明 |\n| :----:| :----: |\n| name | 云函数名称，同时也作为资源 ID。|\n| src\t| 代码路径。|\n| handler |\t函数处理方法名称。|\n| runtime\t| 云函数运行环境，目前支持： Python2.7、Python3.6、Nodejs6.10、Nodejs8.9、Nodejs10.15、Nodejs12.16、PHP5、PHP7、Go1、Java8 和 CustomRuntime。|\n| region |\t云函数所在的区域。|\n| events |\t触发器。支持的触发器为：timer、apigw、cos、cmq、ckafka 。|</p>\n<p>想查询更多详细信息可以参考<a href=\"https://cloud.tencent.com/document/product/583/45352\">官方文档</a>。</p>\n<h3 id=\"2-开发\"><a href=\"#2-%E5%BC%80%E5%8F%91\" aria-label=\"2 开发 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 开发</h3>\n<p>我们可以将业务的各项代码都放置在<code class=\"language-text\">src</code>目录下，这里以当前<code class=\"language-text\">demo</code>项目举例。</p>\n<p>我们打开<code class=\"language-text\">src/index.js</code>，在暴露的这个函数中我们可以尽情的做一些骚操作，然后返回一个结果，并进行测试。你可以连接数据库操作，或者是发起请求等，根据你自己选取的语言来进行代码编写，笔者这里是选择的<code class=\"language-text\">Nodejs</code>环境进行调试。</p>\n<p>不仅如此，我们可以配合其他<code class=\"language-text\">Node</code>框架</p>\n<h3 id=\"3-部署\"><a href=\"#3-%E9%83%A8%E7%BD%B2\" aria-label=\"3 部署 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. 部署</h3>\n<p>部署就比较简单了，只要一句小小的命令即可轻松部署到云端：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"48574249855236194000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`serverless deploy`, `48574249855236194000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">serverless deploy</code></pre></div>\n<p>如果你属于第一次部署的话，将会发现在控制台打印出了一个二维码，你需要做的就是用微信进行扫码授权，然后就静待部署完成即可。</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/15/DFnOzj.png\" alt=\"部署效果预览\"></p>\n<blockquote>\n<p>这里你部署完成之后会发现你的目录下生成了一个<code class=\"language-text\">.env</code>文件，里面保存了你部署需要用到的私密数据，然后第二次部署时就可以不用扫码就能成功部署了（这个授权信息是有时效的，如果失效则需要重新授权）。</p>\n</blockquote>\n<h3 id=\"4-调试\"><a href=\"#4-%E8%B0%83%E8%AF%95\" aria-label=\"4 调试 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. 调试</h3>\n<p>执行触发函数命令，<code class=\"language-text\">function=</code>后面跟着的是你的云函数名称，这样就能判断是否部署成功了。</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"92579826134269790000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`serverless invoke  --inputs function=scfdemo-dev-scf-demo`, `92579826134269790000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">serverless invoke  --inputs <span class=\"token assign-left variable\">function</span><span class=\"token operator\">=</span>scfdemo-dev-scf-demo</code></pre></div>\n<p>效果预览：</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/15/DFYHRP.png\" alt=\"效果预览\"></p>\n<h2 id=\"全栈项目实战\"><a href=\"#%E5%85%A8%E6%A0%88%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98\" aria-label=\"全栈项目实战 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>全栈项目实战</h2>\n<p>如果仅仅只学会了云函数的玩法会不会就有点显示不出<code class=\"language-text\">serverless</code>的方便性了，这里将用<code class=\"language-text\">express</code> + <code class=\"language-text\">Vue3</code>带来一个实战项目部署的过程。</p>\n<h3 id=\"结构搭建\"><a href=\"#%E7%BB%93%E6%9E%84%E6%90%AD%E5%BB%BA\" aria-label=\"结构搭建 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>结构搭建</h3>\n<p>首先创建一个目录来放置我们的前后端项目，然后进入目录，新建一个<code class=\"language-text\">api</code>目录用于放置我们服务端项目代码，接着在<code class=\"language-text\">api</code>同级目录下创建一个<code class=\"language-text\">vue</code>项目（这里是没有限制的，你可以选择<code class=\"language-text\">react</code>或<code class=\"language-text\">vue</code>），笔者为了方便，就采用<code class=\"language-text\">vite</code>创建了一个<code class=\"language-text\">vue3</code>项目。</p>\n<p>同时在该目录下创建一个<code class=\"language-text\">serverless.yml</code>作为整体项目的配置文件。</p>\n<p>目录结构图如下所示，<code class=\"language-text\">.serverless</code> 这个目录不用管，后面部署的时候自动生成的。</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/15/DFyKM9.png\" alt=\"目录结构预览\"></p>\n<p>这样我们基本的目录结构就搭好了，下面开始配置一下吧：</p>\n<h4 id=\"a-服务端代码编写\"><a href=\"#a-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%BB%A3%E7%A0%81%E7%BC%96%E5%86%99\" aria-label=\"a 服务端代码编写 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>a. 服务端代码编写</h4>\n<p>首先我们打开<code class=\"language-text\">api</code>目录，创建一个<code class=\"language-text\">app.js</code>作为入口文件,并采用<code class=\"language-text\">npm init</code>初始化一下项目，并安装<code class=\"language-text\">express</code>和<code class=\"language-text\">cors</code>，该演示项目只用这两个包：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"71251341717477600000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`npm init\n\nnpm i express cors -S`, `71251341717477600000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">npm</span> init\n\n<span class=\"token function\">npm</span> i express cors -S</code></pre></div>\n<p>然后在<code class=\"language-text\">app.js</code>中编写如下代码，并将<code class=\"language-text\">express</code>实例进行导出。</p>\n<blockquote>\n<p>记住这里不要写<code class=\"language-text\">app.listen(...)</code>，只要默认导出就行了</p>\n</blockquote>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"29579621493673810000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`// app.js文件中代码\n\nconst express = require('express');\nconst cors = require('cors');\n\nconst app = express();\n\napp.use(cors);\n\napp.use('/*', (req, res) => {\n    res.send({\n        msg: 'hello world'\n    })\n})\n\nmodule.exports = app;`, `29579621493673810000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">// app.js文件中代码</span>\n\n<span class=\"token keyword\">const</span> express <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'express'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> cors <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'cors'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> app <span class=\"token operator\">=</span> <span class=\"token function\">express</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span>cors<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/*'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    res<span class=\"token punctuation\">.</span><span class=\"token function\">send</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        msg<span class=\"token punctuation\">:</span> <span class=\"token string\">'hello world'</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> app<span class=\"token punctuation\">;</span></code></pre></div>\n<h4 id=\"b-前端代码编写\"><a href=\"#b-%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E7%BC%96%E5%86%99\" aria-label=\"b 前端代码编写 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>b. 前端代码编写</h4>\n<p>这里为了演示方便就写了一个简单的例子，看个人爱好来编写自己喜欢的项目。</p>\n<p>首先打开<code class=\"language-text\">front</code>目录下的<code class=\"language-text\">App.vue</code>，并改写代码：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"54711426056354865000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`<template>\n<div>{{message}}</div>\n</template>\n\n<script>\nimport '../env'; // 部署的时候自动生成\nimport {\n    ref\n} from 'vue'\n\nexport default {\n    name: 'App',\n    setup(props) {\n        const message = ref();\n        fetch(window.env.apiUrl).then(res => res.json()).then(({\n            msg\n        }) => {\n            message.value = msg;\n        });\n\n        return {\n            message\n        }\n    }\n}\n</script>`, `54711426056354865000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>template</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span>{{message}}<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>template</span><span class=\"token punctuation\">></span></span>\n\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span><span class=\"token punctuation\">></span></span><span class=\"token script\"><span class=\"token language-javascript\">\n<span class=\"token keyword\">import</span> <span class=\"token string\">'../env'</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// 部署的时候自动生成</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span>\n    ref\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'vue'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span>\n    name<span class=\"token punctuation\">:</span> <span class=\"token string\">'App'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function\">setup</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">const</span> message <span class=\"token operator\">=</span> <span class=\"token function\">ref</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span>window<span class=\"token punctuation\">.</span>env<span class=\"token punctuation\">.</span>apiUrl<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">res</span> <span class=\"token operator\">=></span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span>\n            msg\n        <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n            message<span class=\"token punctuation\">.</span>value <span class=\"token operator\">=</span> msg<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n            message\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n</span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>这里笔者是采用<code class=\"language-text\">vue3</code>编写的，读者自己看个人喜欢选择框架吧，这里主要是想演示一下发起请求然后渲染页面的这个过程，这个<code class=\"language-text\">import &#39;../env&#39;</code>是必要的，我们不必在意它在不在我们项目的目录下，待会我们部署代码的时候会自动生成的，也就是我们这里直接导入就行了，它主要的做的事情就是将我们配置好的环境变量挂在到<code class=\"language-text\">window</code>上。</p>\n<blockquote>\n<p>笔者这里在<code class=\"language-text\">serverless.yml</code>文件中配置了项目部署之后的服务端<code class=\"language-text\">url</code>的环境变量（<code class=\"language-text\">window.env.apiUrl</code>），具体配置方式后面会提到，这里先用就行了</p>\n</blockquote>\n<p>我们看到<code class=\"language-text\">script</code>中的代码，这里其实笔者只做了一件事，请求我们服务器<code class=\"language-text\">api</code>，然后获取返回值将他渲染到页面上，功能比较简单这里就不进行详细解释了。</p>\n<h4 id=\"c-serverless-配置文件\"><a href=\"#c-serverless-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6\" aria-label=\"c serverless 配置文件 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>c. serverless 配置文件</h4>\n<p>最后一步，我们配置一下项目的部署配置，参数的用途看代码的注释即可，比较简单。</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"74628026422328840000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`# 项目名字\nname: tencent-fullstack-vue-app\n\n# 前端相关配置\ndashboard:\n  # 采用的serverless组件\n  component: '@serverless/tencent-website'\n  # 设置输入参数\n  inputs:\n    # 我们项目源代码配置\n    code:\n      # 部署的文件目录\n      src: dist\n      # 项目的根目录\n      root: front\n      # 部署之前执行的命令，这里用来先打包出dist目录，然后再将dist目录部署上去，也就是上面配置的src对应的目录\n      hook: npm run build\n    # 环境变量\n    env:\n      # 部署的路径\n      apiUrl: \\${api.url}\n# 服务端相关配置\napi:\n  # 采用的serverless组件\n  component: '@serverless/tencent-express'\n  inputs:\n    # 部署上去的服务端目录\n    code: './api'\n    # 云函数名字\n    functionName: tencent-fullstack-vue-api\n    apigatewayConf:\n      # 协议\n      protocols:\n       - https`, `74628026422328840000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"yml\"><pre class=\"language-yml\"><code class=\"language-yml\"><span class=\"token comment\"># 项目名字</span>\n<span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> tencent<span class=\"token punctuation\">-</span>fullstack<span class=\"token punctuation\">-</span>vue<span class=\"token punctuation\">-</span>app\n\n<span class=\"token comment\"># 前端相关配置</span>\n<span class=\"token key atrule\">dashboard</span><span class=\"token punctuation\">:</span>\n  <span class=\"token comment\"># 采用的serverless组件</span>\n  <span class=\"token key atrule\">component</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'@serverless/tencent-website'</span>\n  <span class=\"token comment\"># 设置输入参数</span>\n  <span class=\"token key atrule\">inputs</span><span class=\"token punctuation\">:</span>\n    <span class=\"token comment\"># 我们项目源代码配置</span>\n    <span class=\"token key atrule\">code</span><span class=\"token punctuation\">:</span>\n      <span class=\"token comment\"># 部署的文件目录</span>\n      <span class=\"token key atrule\">src</span><span class=\"token punctuation\">:</span> dist\n      <span class=\"token comment\"># 项目的根目录</span>\n      <span class=\"token key atrule\">root</span><span class=\"token punctuation\">:</span> front\n      <span class=\"token comment\"># 部署之前执行的命令，这里用来先打包出dist目录，然后再将dist目录部署上去，也就是上面配置的src对应的目录</span>\n      <span class=\"token key atrule\">hook</span><span class=\"token punctuation\">:</span> npm run build\n    <span class=\"token comment\"># 环境变量</span>\n    <span class=\"token key atrule\">env</span><span class=\"token punctuation\">:</span>\n      <span class=\"token comment\"># 部署的路径</span>\n      <span class=\"token key atrule\">apiUrl</span><span class=\"token punctuation\">:</span> $<span class=\"token punctuation\">{</span>api.url<span class=\"token punctuation\">}</span>\n<span class=\"token comment\"># 服务端相关配置</span>\n<span class=\"token key atrule\">api</span><span class=\"token punctuation\">:</span>\n  <span class=\"token comment\"># 采用的serverless组件</span>\n  <span class=\"token key atrule\">component</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'@serverless/tencent-express'</span>\n  <span class=\"token key atrule\">inputs</span><span class=\"token punctuation\">:</span>\n    <span class=\"token comment\"># 部署上去的服务端目录</span>\n    <span class=\"token key atrule\">code</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'./api'</span>\n    <span class=\"token comment\"># 云函数名字</span>\n    <span class=\"token key atrule\">functionName</span><span class=\"token punctuation\">:</span> tencent<span class=\"token punctuation\">-</span>fullstack<span class=\"token punctuation\">-</span>vue<span class=\"token punctuation\">-</span>api\n    <span class=\"token key atrule\">apigatewayConf</span><span class=\"token punctuation\">:</span>\n      <span class=\"token comment\"># 协议</span>\n      <span class=\"token key atrule\">protocols</span><span class=\"token punctuation\">:</span>\n       <span class=\"token punctuation\">-</span> https</code></pre></div>\n<p>从这里我们可以看到我们配置的环境变量<code class=\"language-text\">apiUrl</code>，这也就是我们上文中在前端项目中用到的属性，它会在项目部署的时候自动帮我们挂载到<code class=\"language-text\">window</code>上，我们直接用<code class=\"language-text\">window.env.apiUrl</code>访问就行了（前提你需要导入前端项目中根目录的<code class=\"language-text\">env</code>文件，这个是自动生成的，上文也有提到）</p>\n<h3 id=\"调试\"><a href=\"#%E8%B0%83%E8%AF%95\" aria-label=\"调试 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>调试</h3>\n<p>上面的工作完成之后就可以开始部署了：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"28033305181902012000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`serverless --debug`, `28033305181902012000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">serverless --debug</code></pre></div>\n<p>执行上述命令，它会首先自动部署项目到云端，然后将项目的地址打印在控制台上，我们复制地址直接访问就能看到我们部署好的项目了，这里应该也会要求你进行登录授权，控制台会打印出二维码，微信扫码登录一下就好了。</p>\n<p><img src=\"https://s3.ax1x.com/2020/11/15/DF2pF0.png\" alt=\"部署完成\"></p>\n<p>部署成功后我们控制台就能看到以上画面，我们复制<code class=\"language-text\">url</code>到浏览器打开，我们熟悉的<code class=\"language-text\">hello world</code>就已经完美的展现在页面上了。</p>\n<blockquote>\n<p>如果说你的页面并没有正常显示，那么就需要检查一下自己有没有地方代码编写错误，或者是语法问题以及配置不准确之类的了。</p>\n</blockquote>\n<h2 id=\"总结\"><a href=\"#%E6%80%BB%E7%BB%93\" aria-label=\"总结 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>总结</h2>\n<p>当然这只是一个入门级的教程，这里仅仅只是介绍了<code class=\"language-text\">Serverless</code>的一小部分功能，而<code class=\"language-text\">Serverless</code>的强大远非如此，这就需要广大开发者逐步的开启这个新世界的大门了。</p>\n<hr>\n<p>欢迎访问：<a href=\"https://serverlesscloud.cn/\">Serverless 中文网</a>，您可以在 <a href=\"https://serverlesscloud.cn/best-practice\">最佳实践</a> 里体验更多关于 Serverless 应用的开发！</p>","tableOfContents":"<ul>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#%E5%AE%9A%E4%B9%89\">定义</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#%E8%83%8C%E6%99%AF\">背景</a></li>\n<li>\n<p><a href=\"/blog/2020-11-17-stdsuperman/#serverless%E7%89%B9%E7%82%B9\">Serverless特点</a></p>\n<ul>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#1-%E4%BD%8E%E6%88%90%E6%9C%AC\">1. 低成本</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#2-%E8%87%AA%E5%8A%A8%E6%89%A9%E7%BC%A9%E5%AE%B9\">2. 自动扩缩容</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#3-%E4%BA%8B%E4%BB%B6%E9%A9%B1%E5%8A%A8\">3. 事件驱动</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#4-%E6%97%A0%E7%8A%B6%E6%80%81\">4. 无状态</a></li>\n</ul>\n</li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#%E7%AC%AC%E4%B8%80%E4%B8%AA%E4%BA%91%E5%87%BD%E6%95%B0\">第一个云函数</a></li>\n<li>\n<p><a href=\"/blog/2020-11-17-stdsuperman/#%E6%9C%AC%E5%9C%B0%E5%BC%80%E5%8F%91\">本地开发</a></p>\n<ul>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#1-%E5%AE%89%E8%A3%85\">1. 安装</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#2-%E5%BC%80%E5%8F%91\">2. 开发</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#3-%E9%83%A8%E7%BD%B2\">3. 部署</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#4-%E8%B0%83%E8%AF%95\">4. 调试</a></li>\n</ul>\n</li>\n<li>\n<p><a href=\"/blog/2020-11-17-stdsuperman/#%E5%85%A8%E6%A0%88%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98\">全栈项目实战</a></p>\n<ul>\n<li>\n<p><a href=\"/blog/2020-11-17-stdsuperman/#%E7%BB%93%E6%9E%84%E6%90%AD%E5%BB%BA\">结构搭建</a></p>\n<ul>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#a-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%BB%A3%E7%A0%81%E7%BC%96%E5%86%99\">a. 服务端代码编写</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#b-%E5%89%8D%E7%AB%AF%E4%BB%A3%E7%A0%81%E7%BC%96%E5%86%99\">b. 前端代码编写</a></li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#c-serverless-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6\">c. serverless 配置文件</a></li>\n</ul>\n</li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#%E8%B0%83%E8%AF%95\">调试</a></li>\n</ul>\n</li>\n<li><a href=\"/blog/2020-11-17-stdsuperman/#%E6%80%BB%E7%BB%93\">总结</a></li>\n</ul>"},"previousBlog":{"id":"e8af3d86-acc7-516b-a380-c03fbdcd525d","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/20201119/1605769526032-april.jpg","authors":["Serverless 社区"],"categories":["meetup"],"date":"2020-11-19T00:00:00.000Z","title":"Serverless 走进高校，技术普及从娃娃抓起（直播返场）","description":"11 月 19 日晚 7:00，线上直播","authorslink":null,"translators":null,"translatorslink":null,"tags":["Serverless","Meetup"],"keywords":null,"outdated":null},"wordCount":{"words":34,"sentences":7,"paragraphs":7},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-11-19-serverless-students.md","fields":{"slug":"/blog/2020-11-19-serverless-students/","keywords":["serverless","Serverless","serverlesscloud","学姐","直播"]}},"nextBlog":{"id":"162ef1e0-1ae9-54a2-b02e-8ccedefc0f0a","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/20201118/1605688310413-a439663e77e045899725dc094b393d6e_tplv-k3u1fbpfcp-watermark.jpg","authors":["Serverless 社区"],"categories":["meetup"],"date":"2020-11-16T00:00:00.000Z","title":"掘金 x 腾讯云联合征文 | 万物皆可 Serverless","description":"奖品大升级！！！🏆 征文继续 ing","authorslink":null,"translators":null,"translatorslink":null,"tags":["Serverless","Meetup"],"keywords":null,"outdated":null},"wordCount":{"words":188,"sentences":44,"paragraphs":44},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-11-16-juejin.md","fields":{"slug":"/blog/2020-11-16-juejin/","keywords":["serverless","函数计算","无服务器","无服务器架构","Serverless","文章","腾讯","serverlesscloud","掘金","参与","服务器","贴纸"]}},"recommendBlogs":{"edges":[{"node":{"id":"4300b21c-7209-5256-86ff-0d38e3daec9b","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/14f1c8eed372e76c1b139703b2f6d0fa.jpg","authors":["KieranMcCarthy"],"categories":["user-stories","engineering-culture"],"date":"2018-01-09T00:00:00.000Z","title":"我是如何在四年时间里，从厨师转行为 Serverless 应用开发者","description":"我是厨师出身，现在成为了一名 Serverless 应用开发者。","authorslink":["https://serverless.com/author/kieranmccarthy/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["应用开发","Serverless"],"keywords":"Serverless 应用开发,Serverless 管理,厨师转行为 Serverless 应用开发者","outdated":null},"wordCount":{"words":285,"sentences":38,"paragraphs":36},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years.md","fields":{"slug":"/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years/","keywords":["无服务器","无服务器开发","云函数","学习","Serverless","构建","Framework","开发者","服务器","应用","学位","简历"]}}},{"node":{"id":"713a0563-4bf9-5721-bacb-3b4ef609fe4a","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/camp-fire/camp-fire-housing-thumb.jpg","authors":["EricWyne"],"categories":["guides-and-tutorials","user-stories"],"date":"2018-12-05T00:00:00.000Z","title":"Serverless Twitter 机器人帮助为坎普山火受灾者安置住房","description":"加利福尼亚州的坎普山火致使数千人流离失所，为此，我构建了一个简单的 Serverless Twitter 机器人来帮助将受灾者安置在临时住房！","authorslink":["https://serverless.com/author/ericwyne/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":157,"sentences":26,"paragraphs":26},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-05-serverless-twitter-camp-fire.md","fields":{"slug":"/blog/2018-12-05-serverless-twitter-camp-fire/","keywords":["serverless","无服务器","云函数","Serverless","org","住房","Twitter","函数","受灾","机器人","山火"]}}},{"node":{"id":"98602143-b837-5f50-a24f-3b1ec76044d7","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/sqquid/sqquid-serverless-thumb.jpg","authors":["RonPeled"],"categories":["user-stories"],"date":"2018-12-17T00:00:00.000Z","title":"SQQUID：100% 无服务器初创公司","description":"SQQUID 将 AWS Lambda 和无服务器框架用于其核心产品和营销网站。我们来看看一个完全无服务器的初创公司是怎样的。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":266,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-17-sqquid-one-hundred-percent-serverless.md","fields":{"slug":"/blog/2018-12-17-sqquid-one-hundred-percent-serverless/","keywords":["go","serverless","无服务器","无服务器架构","服务器","架构","Lambda","集成","FaaS","串行","系统"]}}},{"node":{"id":"29dc2e58-d2ba-56f9-aee1-d21b0bc62e0e","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/ao-com-story/ao-serverless-thumbnail.png","authors":["NickGottlieb"],"categories":["user-stories"],"date":"2019-04-24T00:00:00.000Z","title":"AO.com：逐渐转向无服务器优先","description":"AO.com 的 SCV 团队率先尝试无服务器服务。折服于无服务器框架的快速周转时间和低维护成本，整个团队逐渐转向无服务器优先。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":236,"sentences":42,"paragraphs":35},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-04-24-ao-serverless-first.md","fields":{"slug":"/blog/2019-04-24-ao-serverless-first/","keywords":["serverless","无服务器","服务器","团队","Lambda","功能","构建"]}}},{"node":{"id":"752d08d1-387a-5bde-acf3-98141baab294","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020414/1586871710979-%E5%85%AC%E5%85%B1%E7%94%A8.png","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-06-20T00:00:00.000Z","title":"如何用 Serverless 为 Python 云函数打包依赖","description":"在使用无服务器云函数SCF时通常会遇到导入第三方库的问题，很多小伙伴比较头疼是：应该如何打包进去？这里，推荐几个不错的方法。","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["云函数","Serverless"],"keywords":"Serverless,Serverless应用,无服务器云函数","outdated":null},"wordCount":{"words":81,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-06-20-for-python-cloud-functions.md","fields":{"slug":"/blog/2019-06-20-for-python-cloud-functions/","keywords":["java","serverless","无服务器","无服务器云函数","云函数","serverlesscloud","安装","serverless","pillowtest"]}}},{"node":{"id":"2dc78814-9d77-555b-a1bb-ad202c8ec2d1","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/cloudforecast/thumbnail.png","authors":["FrancoisLagier"],"categories":["user-stories"],"date":"2019-08-07T00:00:00.000Z","title":"Serverless：初创企业的理想选择？（CloudForecast 案例分析）","description":"CloudForecast 是 2018 年成立的一家独立初创企业，本文将介绍他们决定选择 Serverless 的原因。","authorslink":["https://serverless.com/author/francoislagier/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":211,"sentences":29,"paragraphs":29},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-08-07-serverless-for-startups.md","fields":{"slug":"/blog/2019-08-07-serverless-for-startups/","keywords":["serverless","云函数","serverless","函数","Serverless","utm","Framework","blog","CloudForecast","cloudforecast"]}}},{"node":{"id":"97450b07-658b-5207-8216-1c7b9b51b115","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578988490344-v2-8b2cd2c5275aa2c5a3c5083a148a7a9f_1200x500.jpg","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-09-01T00:00:00.000Z","title":"如何通过 Serverless 与自然语言处理，让搜索引擎「看」到你的博客","description":"Serverless 与自然语言处理结合的一个小应用","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["个人博客","serverless"],"keywords":"Serverless 自然语言处理","outdated":null},"wordCount":{"words":106,"sentences":34,"paragraphs":34},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-01-search-engine-blog.md","fields":{"slug":"/blog/2019-09-01-search-engine-blog/","keywords":["serverless","云函数","keywords","serverlesscloud","summary"]}}},{"node":{"id":"ae4fd2f8-515c-5aec-b584-38427ef33f7e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578989800047-part-00492-780.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials","user-stories"],"date":"2019-09-16T00:00:00.000Z","title":"突破传统 OJ 瓶颈，「判题姬」接入云函数","description":"通过 Serverless 实现在线编程","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["在线编程","云函数"],"keywords":"Serverless 在线编程,Serverless OJ","outdated":null},"wordCount":{"words":169,"sentences":30,"paragraphs":30},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-16-online-Judge.md","fields":{"slug":"/blog/2019-09-16-online-Judge/","keywords":["python","serverless","云函数","代码","函数","serverless"]}}}],"totalCount":64}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"f02f2d33-403a-5936-b733-bac2a216c76d","previousBlogId":"e8af3d86-acc7-516b-a380-c03fbdcd525d","nextBlogId":"162ef1e0-1ae9-54a2-b02e-8ccedefc0f0a","categories":["user-stories"]}}}