{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-03-14-why-fe-learn-sls","result":{"data":{"currentBlog":{"id":"c18924ec-cade-5f2f-91ca-e1717924521b","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020115/1579078112543-1577769064015-joshua-aragon-FGXqbqbGt5o-unsplash.jpg","authors":["Aceyclee"],"categories":["engineering-culture","user-stories"],"date":"2020-03-14T00:00:00.000Z","title":"前端为什么要关注 Serverless?","description":"前端为什么要接 serverless? 交给后端不行吗?","authorslink":["https://www.zhihu.com/people/Aceyclee"],"translators":null,"translatorslink":null,"tags":["Serverless","全栈应用"],"keywords":"serverless发展,Serverless 基本概念,Serverless生产力","outdated":null},"wordCount":{"words":233,"sentences":51,"paragraphs":51},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-14-why-fe-learn-sls.md","fields":{"slug":"/blog/2020-03-14-why-fe-learn-sls/","keywords":["serverless","vue","vuejs","website","website 组件","serverless","Serverless","tencent","express","serverlesscloud","github"]},"html":"<p>Serverless 的概念或应用场景我们以前讲过很多，这里不再冗述。概括性地讲 —— <strong>Serverless 的内涵就是对全部底层资源和运维工作的封装，让开发者更专注于业务逻辑。</strong></p>\n<p>完备的基础性文章推荐阅读这两篇：</p>\n<ul>\n<li><a href=\"https://serverlesscloud.cn/blog/2019-08-01-serverless-basic-concept\">Serverless 基本概念入门</a></li>\n<li><a href=\"https://serverlesscloud.cn/blog/2019-08-21-serverless-operation-architecture\">Serverless 的运行原理与组件架构</a></li>\n</ul>\n<p>本文尝试从出圈的角度，以更接地气的方式聊聊 Serverless。</p>\n<p>先讲个故事，疫情期间在家办公，大家肯定没少做饭，自己做饭才体会到家务不易，你需要：买菜买锅、处理食材、煎炒蒸煮、最后洗碗。</p>\n<blockquote>\n<p>听起来是不是还挺像软件开发？你需要有云服务器、后台开发、前端开发、还有运维。</p>\n</blockquote>\n<p>你想着，要是我能只翻两下铲子，然后就能吃饭那该多好。</p>\n<p>巧了，有一些商家就提供了这种服务，帮你准备好了锅、洗干净的食材、专业的厨师指点，你只要进去翻两下铲子，就能煮一顿精美的饭食！而且不用洗碗。</p>\n<blockquote>\n<p>对应到软件开发，开发者只需要关注业务逻辑（炒菜），而底层资源和运维工作（锅碗瓢盆、食材处理）都不用再操心。</p>\n</blockquote>\n<p>终于到了正式复工的时间，你不用再自己做饭，新买的厨具就闲置了。你回想起昨天在商圈里的美好体验，家里的厨具要是也在能用的时候付费，不用不收费多好啊。</p>\n<blockquote>\n<p>嘿嘿，Serverless 亦如此，按水电般计费，当部署在其上的函数运行时才收费。</p>\n</blockquote>\n<p>所以回到题目中来，Serverless 本身是云计算相关技术，并非前端技术，为何前端要关注 Serverless 呢？</p>\n<p><strong>答案很简单 —— 解放生产力。</strong></p>\n<p>你的厨房里已经准备好了所有厨具和处理好的食材，你现在只需要关心火候认真炒菜，成为美食博主指日可待。也就是文首所说的 —— 开发者能更专注于业务逻辑，其他的底层资源和运维工作已经全部封装好了。</p>\n<hr>\n<h2 id=\"▎talk-is-cheap-show-you-the-code\"><a href=\"#%E2%96%8Etalk-is-cheap-show-you-the-code\" aria-label=\"▎talk is cheap show you the code 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>▎Talk is cheap, show you the code.</h2>\n<p>先给大家展示一个基于 Serverless 构建 docsify 文档的 <a href=\"https://serverlesscloud.cn/best-practice/2019-12-14-docsify-with-serverless\">demo</a></p>\n<p>这个三分钟的 demo，不仅完成了 docsify 发布代码的上传，还包括了腾讯云对象存储 COS 资源的申请和配置。而这仅仅是我第一次使用 Serverless 来构建应用，可见它上手性之高。</p>\n<video id=\"video\" controls=\"\" preload=\"none\" poster=\"https://img.serverlesscloud.cn/20191217/1576566243002-docsifyvideopic.png\">\n<source id=\"mp4\" src=\"https://img.serverlesscloud.cn/video/docsify%2B%E7%89%87%E5%B0%BE4.mp4\">\n</video>\n<blockquote>\n<p>原文链接：<a href=\"https://serverlesscloud.cn/best-practice/2019-12-14-docsify-with-serverless\">《三分钟入坑指北   Docsify + Serverless Framework 快速创建个人博客》</a></p>\n</blockquote>\n<p><strong>再进一步，我们演示个 Fullstack Application。</strong>该项目借助社区现有的 <a href=\"https://github.com/serverless-components/tencent-express\">@serverless/tencent-express</a> 和 <a href=\"https://github.com/serverless-components/tencent-website\">@serverless/tencent-website</a> 组件来完成。</p>\n<p>下面是一张简单的组件依赖图：</p>\n<p><img src=\"https://static.yugasun.com/serverless/component-framework.png\" alt=\"Component Dependency Structure\"></p>\n<blockquote>\n<p>在开始所有步骤前，需执行 <code class=\"language-text\">npm install -g serverless</code> 命令，全局安装 <code class=\"language-text\">serverless cli</code>。</p>\n</blockquote>\n<p><strong>1. 准备</strong></p>\n<p>新建项目目录 <code class=\"language-text\">fullstack-application-vue</code>，在该项目目录下新增 <code class=\"language-text\">api</code> 和 <code class=\"language-text\">dashboard</code> 目录。然后新增 <code class=\"language-text\">serverless.yml</code> 和 <code class=\"language-text\">.env</code> 配置文件，项目目录结构如下：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">├── README.md \t\t// 项目说明文档\n├── api\t\t\t\t\t  // Restful api 后端服务\n├── dashboard\t\t\t// 前端页面\n├── .env\t\t\t\t\t// 腾讯云相关鉴权参数：TENCENT_APP_ID，TENCENT_SECRET_ID，TENCENT_SECRET_KEY\n└── serverless.yml\t// serverless 文件</code></pre></div>\n<p><strong>2. 后端服务开发</strong></p>\n<p>进入目录 <code class=\"language-text\">api</code>，新增 <code class=\"language-text\">app.js</code> 文件，编写 <code class=\"language-text\">express</code> 服务代码，这里先新增一个路由 <code class=\"language-text\">/</code>，并返回当前服务器时间：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"33919492403480867000\"\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(`const express = require('express')\nconst cors = require('cors')\nconst app = express()\n\napp.use(cors())\napp.get('/', (req, res) => {\n  res.send(JSON.stringfy({ message: \\`Server time: \\${new Date().toString()}\\` }))\n})\nmodule.exports = app`, `33919492403480867000`)\"\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=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><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>\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>\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>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span><span class=\"token function\">cors</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\napp<span class=\"token punctuation\">.</span><span class=\"token function\">get</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 constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringfy</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> message<span class=\"token punctuation\">:</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Server time: </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">Date</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> app</code></pre></div>\n<p><strong>3. 前端页面开发</strong></p>\n<p>本案例使用的是 <code class=\"language-text\">Vue.js</code> + <code class=\"language-text\">Parcel</code> 的前端模板，当然你可以使用任何前端项目脚手架，比如 Vue.js 官方推荐的 <a href=\"https://github.com/vuejs/vue-cli\">Vue CLI</a> 生成的项目。进入 <code class=\"language-text\">dashboard</code> 目录，编写入口文件 <code class=\"language-text\">src/index.js</code>:</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"72181261863652210000\"\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(`// 这里初始是没有 env.js 模块的，第一次部署后会自动生成\nrequire('../env')\n\nconst Vue = require('vue')\n\nmodule.exports = new Vue({\n  el: '#root',\n  data: {\n    message: 'Click me!',\n    isVisible: true,\n  },\n  methods: {\n    async queryServer() {\n      const response = await fetch(window.env.apiUrl)\n      const result = await response.json()\n      this.message = result.message\n    },\n  },\n})`, `72181261863652210000`)\"\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=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token comment\">// 这里初始是没有 env.js 模块的，第一次部署后会自动生成</span>\n<span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'../env'</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">const</span> Vue <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'vue'</span><span class=\"token punctuation\">)</span>\n\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Vue</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  el<span class=\"token punctuation\">:</span> <span class=\"token string\">'#root'</span><span class=\"token punctuation\">,</span>\n  data<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span>\n    message<span class=\"token punctuation\">:</span> <span class=\"token string\">'Click me!'</span><span class=\"token punctuation\">,</span>\n    isVisible<span class=\"token punctuation\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  methods<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">async</span> <span class=\"token function\">queryServer</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">const</span> response <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <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>\n      <span class=\"token keyword\">const</span> result <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>message <span class=\"token operator\">=</span> result<span class=\"token punctuation\">.</span>message\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><strong>3. 配置</strong></p>\n<p>前后端代码都准备好了，再简单配置下 <code class=\"language-text\">serverless.yml</code> 文件了：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"92729077615712370000\"\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(`name: fullstack-application-vue\n\nfrontend:\n  component: '@serverless/tencent-website'\n  # inputs 为 @serverless/tencent-website 组件的输入\n  # 具体配置说明参考：https://github.com/serverless-components/tencent-website/blob/master/docs/configure.md\n  inputs:\n    code:\n      src: dist\n      root: frontend\n      hook: npm run build\n    env:\n      # 下面的 API服务部署后，获取对应的 api 请求路径\n      apiUrl: \\${api.url}\n\napi:\n  component: '@serverless/tencent-express'\n  # inputs 为 @serverless/tencent-express 组件的输入\n  # 具体配置说明参考：https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md\n  inputs:\n    code: ./api\n    functionName: fullstack-vue-api\n    apigatewayConf:\n      protocol: https`, `92729077615712370000`)\"\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=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> fullstack<span class=\"token punctuation\">-</span>application<span class=\"token punctuation\">-</span>vue\n\n<span class=\"token key atrule\">frontend</span><span class=\"token punctuation\">:</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\"># inputs 为 @serverless/tencent-website 组件的输入</span>\n  <span class=\"token comment\"># 具体配置说明参考：https://github.com/serverless-components/tencent-website/blob/master/docs/configure.md</span>\n  <span class=\"token key atrule\">inputs</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">code</span><span class=\"token punctuation\">:</span>\n      <span class=\"token key atrule\">src</span><span class=\"token punctuation\">:</span> dist\n      <span class=\"token key atrule\">root</span><span class=\"token punctuation\">:</span> frontend\n      <span class=\"token key atrule\">hook</span><span class=\"token punctuation\">:</span> npm run build\n    <span class=\"token key atrule\">env</span><span class=\"token punctuation\">:</span>\n      <span class=\"token comment\"># 下面的 API服务部署后，获取对应的 api 请求路径</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\n<span class=\"token key atrule\">api</span><span class=\"token punctuation\">:</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 comment\"># inputs 为 @serverless/tencent-express 组件的输入</span>\n  <span class=\"token comment\"># 具体配置说明参考：https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md</span>\n  <span class=\"token key atrule\">inputs</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">code</span><span class=\"token punctuation\">:</span> ./api\n    <span class=\"token key atrule\">functionName</span><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 key atrule\">protocol</span><span class=\"token punctuation\">:</span> https</code></pre></div>\n<p><strong>4. 部署</strong></p>\n<p>部署时，只需要运行 <code class=\"language-text\">serverless</code> 命令就行，当然如果你需要查看部署中的 <code class=\"language-text\">DEBUG</code> 信息，还需要加上 <code class=\"language-text\">--debug</code> 参数，如下：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ serverless\n# or\n$ serverless --debug</code></pre></div>\n<p>最后终端会 <code class=\"language-text\">balabalabala~</code>, 看到绿色的<code class=\"language-text\">done</code>就行了。</p>\n<blockquote>\n<p>体验：<a href=\"https://br1ovx-efmogqe-1251556596.cos-website.ap-guangzhou.myqcloud.com/\">在线 Demo</a></p>\n</blockquote>\n<p>既然是全栈，怎么少得了数据库的读写呢？</p>\n<p>读者可移步作者原文继续阅读：<a href=\"https://serverlesscloud.cn/best-practice/2019-12-5-Full-stack-solution-based-on-serverless-component\">《基于 Serverless Component 的全栈解决方案》</a></p>\n<p>从这两个小项目中已然得解 ——  Serverless 的内涵就是对全部底层资源和运维工作的封装，让开发者更专注于业务逻辑。</p>\n<h2 id=\"▎写在后面\"><a href=\"#%E2%96%8E%E5%86%99%E5%9C%A8%E5%90%8E%E9%9D%A2\" 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>题主在问题描述中的思考很有价值，其实 Serverless 的确不是一个前端的概念，甚至都不是为了解决前端的问题而出现的，<strong>它其实就是云计算发展的必经过程。</strong></p>\n<p>就好比，底层语言的发展趋势肯定是高级语言。而高级语言肯定也会封装起底层的硬件，让程序员无需关心硬件的状态，专注编码。</p>\n<p>十年前编程还是比较难的高级学科，如今小学已经开展编程课程。其实就是因为程序语言的发展，让编程变得更加友好。</p>\n<p>同样地，Serverless 的出现和完善，也是让软件开发变得更加友好。不仅前端需要关注 Serverless，它可能属于每一种类型的应用开发者。</p>\n<p>而这会淘汰后端吗？并不会！</p>\n<p>后端会更聚焦于业务逻辑、数据处理、算法策略等更专精的事情。</p>\n<p>汽车的出现让马车夫成为了司机，技术在变革，工程师也将成长。</p>\n<hr>\n<div id='scf-deploy-iframe-or-md'></div>\n<hr>\n<blockquote>\n<p><strong>传送门：</strong></p>\n<ul>\n<li>GitHub: <a href=\"https://github.com/serverless/serverless/blob/master/README_CN.md\">github.com/serverless</a></li>\n<li>官网：<a href=\"https://serverless.com/\">serverless.com</a></li>\n</ul>\n</blockquote>\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-03-14-why-fe-learn-sls/#%E2%96%8Etalk-is-cheap-show-you-the-code\">▎Talk is cheap, show you the code.</a></li>\n<li><a href=\"/blog/2020-03-14-why-fe-learn-sls/#%E2%96%8E%E5%86%99%E5%9C%A8%E5%90%8E%E9%9D%A2\">▎写在后面</a></li>\n</ul>"},"previousBlog":{"id":"59a44895-3215-5ad0-8f99-9da7ee04ecdd","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020326/1585234124615-0.jpg","authors":["serverless 社区"],"categories":["user-stories","engineering-culture"],"date":"2020-03-16T00:00:00.000Z","title":"Serverless Python 开发实战（附源码）","description":"本文将为大家详细讲解 Serverless 架构的处理规范与处理模型、典型的工作流程，以及 Serverless 工程化的难点与挑战，最后将结合 Python Flask + Serverless 的情人节表白页制作实例","authorslink":null,"translators":null,"translatorslink":null,"tags":["Serverless","Python"],"keywords":"serverless发展,Serverless 基本概念,Serverless生产力","outdated":true},"wordCount":{"words":590,"sentences":104,"paragraphs":104},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-16-serverlesspython.md","fields":{"slug":"/blog/2020-03-16-serverlesspython/","keywords":["serverless","无服务器","云函数","云原生","Serverless","事件","Python","函数"]}},"nextBlog":{"id":"55953085-8519-57ce-bf38-6f3a36d113c3","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020318/1584508229341-blogging.jpg","authors":["云洋"],"categories":["user-stories"],"date":"2020-03-12T00:00:00.000Z","title":"Serverless 动态博客开发趟「坑」记","description":"本文为 Serverless 社区成员撰稿。作者云洋，从事信息管理工作，多年电子政务信息系统建设管理经验，对 Serverless 技术和架构有浓厚兴趣。","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["Serverless","动态博客"],"keywords":"Serverless 动态博客开发,Serverless 动态博客,Serverless 开发","outdated":true},"wordCount":{"words":391,"sentences":74,"paragraphs":74},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-12-blog-issues.md","fields":{"slug":"/blog/2020-03-12-blog-issues/","keywords":["serverless","website","部署","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":"36ad18b2-1694-5b48-bb23-d6a5575343cd","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/4c101fcf0be63a70e0aa992da17dd955.png","authors":["BrianNeisler"],"categories":["engineering-culture"],"date":"2018-01-24T00:00:00.000Z","title":"如何将设计思维应用到精益初创公司的软件开发中","description":"关于将设计思维与敏捷开发相结合的尝试 —— 成功与失败剖析","authorslink":["https://serverless.com/author/brianneisler/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["敏捷开发","Serverless"],"keywords":"Serverless 设计思维,Serverless 敏捷开发","outdated":null},"wordCount":{"words":213,"sentences":41,"paragraphs":41},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-01-23-appy-design-thinking-lean-startup-software-development.md","fields":{"slug":"/blog/2018-01-23-appy-design-thinking-lean-startup-software-development/","keywords":["思维","设计","用户","团队","产品","想法","验证","优先级","敏捷","公司"]}}},{"node":{"id":"e7fe6284-d107-5e80-8e6e-cae075aff38c","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/67b0bff4886896e1ee5d4f5917cf6096.jpg","authors":["FelixDesroches"],"categories":["engineering-culture"],"date":"2018-02-09T00:00:00.000Z","title":"Serverless 公司的远程团队沟通策略","description":"Serverless 团队分散在全球各地，本文介绍我们如何管理沟通策略和远程协作。","authorslink":["https://serverless.com/author/felixdesroches/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["远程协同","Serverless"],"keywords":"Serverless 远程团队,Serverless 沟通策略,Serverless 远程协作","outdated":null},"wordCount":{"words":137,"sentences":22,"paragraphs":22},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-02-09-communication-strategies-remote-teams.md","fields":{"slug":"/blog/2018-02-09-communication-strategies-remote-teams/","keywords":["沟通","团队","工具","Radical","Candor","团建","Slack","方式"]}}},{"node":{"id":"548b1bba-ea90-5753-a0eb-040193083655","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/20191212/1576149285117-charmmie-square.jpg","authors":["CharmmieHendon"],"categories":["engineering-culture"],"date":"2018-02-01T00:00:00.000Z","title":"一名时尚艺术家转行到科技行业的历程","description":"Serverless 团队新成员 Charmmie 是从高级时装行业转行到技术领域的，本文是她的故事，太酷了。","authorslink":["https://serverless.com/author/charmmiehendon/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["Serverless"],"keywords":"Serverless 团队成员,Charmmie","outdated":null},"wordCount":{"words":242,"sentences":39,"paragraphs":37},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-01-30-serverless-style-from-fashion-to-tech.md","fields":{"slug":"/blog/2018-01-30-serverless-style-from-fashion-to-tech/","keywords":["go","serverless","Serverless","技术","科技","Sam","行业","时尚","工作","时装","旧金山","适合"]}}},{"node":{"id":"dc9c5f49-4ee1-56bb-b5ec-6780d9fd69e1","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/c2598ce0fad913a7d1fe2bfcdd3324e3.jpeg","authors":["NickGottlieb"],"categories":["engineering-culture"],"date":"2018-02-23T00:00:00.000Z","title":"通过 Serverless 架构构建更好的软件","description":"Nick Gottlieb 分享了他在 ServerlessConf Tokyo 上关于 Serverless、软件状态以及提高生产效率方法的演讲。","authorslink":["https://serverless.com/author/nickgottlieb/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["Serverless"],"keywords":"Serverless 架构构建,ServerlessConf Tokyo,Serverless 效率方法","outdated":null},"wordCount":{"words":200,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-02-23-serverless-path-building-better-software.md","fields":{"slug":"/blog/2018-02-23-serverless-path-building-better-software/","keywords":["无服务器","云函数","Serverless","服务","构建","工具","软件","开发人员","函数","架构"]}}},{"node":{"id":"73576d26-e0ce-5f26-9330-64b4f3889157","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/3cb7b20955d78ced738e0279bb3f6f41.jpg","authors":["AndreaPasswater"],"categories":["news","engineering-culture"],"date":"2018-03-09T00:00:00.000Z","title":"Serverless 数据解读：2018 报告","description":"Serverless Framework 使用统计数据：事件源、服务结构、运行时长等等。","authorslink":["https://serverless.com/author/andreapasswater/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["事件源","服务结构"],"keywords":"Serverless 统计数据,Serverless 事件源,Serverless 服务结构","outdated":null},"wordCount":{"words":212,"sentences":45,"paragraphs":45},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-03-09-serverless-by-the-numbers-2018-data-report.md","fields":{"slug":"/blog/2018-03-09-serverless-by-the-numbers-2018-data-report/","keywords":["go","serverless","无服务器","云函数","服务","使用率","Go","部署"]}}},{"node":{"id":"665f9ce2-4451-59fd-bf98-1861789d3b3b","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/Serverless_logo.png","authors":["AndreaPasswater"],"categories":["guides-and-tutorials","engineering-culture"],"date":"2018-03-19T00:00:00.000Z","title":"如何为无服务器开放源代码项目做贡献","description":"想要为无服务器开放源代码项目做贡献？您可以遵循下面的指南。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":96,"sentences":36,"paragraphs":36},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-03-19-how-contribute-to-serverless-open-source.md","fields":{"slug":"/blog/2018-03-19-how-contribute-to-serverless-open-source/","keywords":["serverless","无服务器","serverless","github","插件","服务器","贡献","示例","blog","contribute"]}}},{"node":{"id":"a3e92579-65c3-5159-937c-32d18c5df7d7","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/why-not/why-not-header.png","authors":["AndreaPasswater"],"categories":["guides-and-tutorials","operations-and-observability","engineering-culture"],"date":"2018-03-21T00:00:00.000Z","title":"不适合选择无服务器的情境及原因","description":"无服务器既有优点也有缺点。那么，哪些情境下不适合选择无服务器？原因又是什么呢？","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":163,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-03-21-when-why-not-use-serverless.md","fields":{"slug":"/blog/2018-03-21-when-why-not-use-serverless/","keywords":["faas","react","serverless","spa","无服务器","无服务器函数","无服务器架构","无服务器开发","服务器","twitter","serverless","blockquote","lang","script","en"]}}}],"totalCount":87}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"c18924ec-cade-5f2f-91ca-e1717924521b","previousBlogId":"59a44895-3215-5ad0-8f99-9da7ee04ecdd","nextBlogId":"55953085-8519-57ce-bf38-6f3a36d113c3","categories":["engineering-culture","user-stories"]}}}