{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-03-25-developer-tools","result":{"data":{"currentBlog":{"id":"dc6a99cf-6d6a-523d-945b-ad2c8aac8c75","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020331/1585640629003-office.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials"],"date":"2020-03-25T00:00:00.000Z","title":"入门 Serverless：Serverless Framework 开发者工具","description":"Serverless 架构是云发展的产物。然而，细心的朋友可能会发现，有一个开发者工具也叫 Serverless，那么这个开发者工具和 Serverless 架构又有什么关系呢？","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["Serverless","Component"],"keywords":"Serverless 全局变量组件,Serverless 单独部署组件,Serverless Component","outdated":null},"wordCount":{"words":648,"sentences":91,"paragraphs":90},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-25-developer-tools.md","fields":{"slug":"/blog/2020-03-25-developer-tools/","keywords":["go","koa","nodejs","php","python","serverless","website","函数计算","云函数","Serverless","函数","serverless","开发者","Plugin","Framework","部署","工具","tencnet"]},"html":"<blockquote>\n<p>Serverless 架构是云发展的产物，是一种去服务器化更加明显的架构。然而，细心的朋友可能会发现，有一个开发者工具也叫 Serverless，那么 Serverless 到底是一个架构，还是一个开发者工具呢？这个开发者工具和 Serverless 架构又有什么关系呢？</p>\n</blockquote>\n<h2 id=\"初探-serverless-开发者工具\"><a href=\"#%E5%88%9D%E6%8E%A2-serverless-%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7\" 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<p>Serverless 架构开始发展没多久，就有一群人注册了 serverless.com 的域名，成立了一家叫 Serverless 的公司，同时还开发了一款同名工具。</p>\n<p>Serverless 架构和 Serverless 开发者工具是两个不同的东西，如果类比一下的话，就相当于中国电信，一方面指的是中国电信行业，另一方面也指的是中国电信运营商。</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071949.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>从 Serverless 的公司名称，我们也可以推断出其推出的产品与 Serverless 架构紧密相关。在各个云厂商都有自己函数计算业务的时候，Serverless 团队做了一个类似多云管理平台的工具，可以认为是多 Serverless 管理的工具。利用这个工具，可以快速直接使用 AWS 的 Lambda、Azure 的 Funtions 以及腾讯云 SCF 等众多云厂商的函数计算相关服务，大体支持的功能如下：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071956.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>通过这个上表，大家也可以感觉到这其实是个开发者工具，帮助用户快速使用多个云厂商的函数服务，打包、部署、回滚…当然，各个厂商也都推出类似的工具，例如 AWS 的 SAM、腾讯云的 SCFCLI 等。</p>\n<p>除了一个以函数计算为核心的多云开发者工具之外，Serverless 公司还推出了组件化工具：Components。换句话说，Serverless 开发者工具不仅仅关注 Serverless 中的 FaaS，也要关注 BaaS，将 API 网关、对象存储、CDN、数据库等众多的后端服务和函数计算有机集合，让用户可以一站式开发，一站式部署，一站式更新，一站式维。</p>\n<p>Serverless Framework 开发者工具可以被一分为二：Plugin 和 Components。</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071955.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>如果说最初的 Serverless Cli 更多是一种以插件（Plugin）形式提供各个云厂商的函数计算功能，那么这个叫 Components 的功能更多就是以各个云厂商整体服务为基础，来帮助用户快速将项目部署到 Serverless 架构上。</p>\n<p>所谓的 Components 可以认为是很多 Component 的组合，例如如果部署一个网站，可能会需要有以下部分：静态资源部分、函数计算部分、API 网关部分、CDN 部分、域名解析部分等，而 Components 就可以帮我们一站式部署这些资源，将静态资源部署到对象存储中，将函数计算部分部署到函数中，将 API 网关、CDN 等业务部署到对应的产品或者服务中，如果有域名解析需求，会自动解析域名，同时将整个项目的所有资源进行关联。</p>\n<p>除了一键部署、自动关联之外，Components 还提供了若干的传统 Web 框架部署到 Serverless 架构的解决方案，用户可将自己已有的或者使用这些框架新开发的项目，直接一键部署到云端，对开发者来说这是一个巨大的便利。</p>\n<p>用户如何使用 Plugin 和 Components 呢？其实这两个功能都是 Serverless Cli 作为承载，也就是说，只要我们安装了 Serverless Framework 这个开发者工具，就可以同时使用这两个功能。</p>\n<p>安装 Serverless Framework 开发者工具的过程也很简单：</p>\n<ul>\n<li>安装 Nodejs，官方说的 nodejs 只需要 6 以上就好，但是在实际使用过程中，发现 6 不行，至少 8 以上才可以。</li>\n<li>安装 Serverless 开发者工具：<code class=\"language-text\">npm install -g serverless</code>，安装完成之后可以通过<code class=\"language-text\">serverless -v</code>查看版本号，来确定是否成功的安装该工具。</li>\n</ul>\n<p>至于如何使用 Serverless Framework 开发者工具，可以参考接下来的 Plugin 和 Components 部分。</p>\n<h2 id=\"什么是-serverless-plugin\"><a href=\"#%E4%BB%80%E4%B9%88%E6%98%AF-serverless-plugin\" aria-label=\"什么是 serverless plugin 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 Plugin</h2>\n<p>首先，什么是 Plugin，Serverless Framework Plugin 实际上是一个函数的管理工具，使用这个工具，可以很轻松的部署函数、删除函数、触发函数、查看函数信息、查看函数日志、回滚函数、查看函数数据等。</p>\n<p>Plugin 的使用比较简单，可以直接使用 Serverlss Framework 进行创建，例如：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">    serverless create -t tencent-python -p mytest</code></pre></div>\n<p>然后就会生成下图：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-072000.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>这其中，-t 指的是模板，-p 指的是路径，在 Serverless Plugin 操作下，可以在任何指令中使用 -h 查看帮助信息，例如查看 Serverless Plugin 的全部指令，可以直接：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071950.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>如果想查看 Create 的帮助：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071957.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>创建完 Serverless Plugin 的项目之后，我们可以看一下它的 Yaml 长什么样子：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-71953.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>通过 Yaml，我们可以看到其从上到下包括了几个主要的 Key：Service、Provider、Plugins 以及 Functions。</p>\n<p>Service 可以认为是一个服务或分组，即在一个 Service 下面的函数是可以被统一管理的，例如部署、删除、查看统计信息等。</p>\n<p>Provider 可以认为是供应商以及全局变量的定义场景，这里使用的是腾讯云的云函数，供应商是腾讯云，所以就要写 tencent，同时在这里还可以定义全局变量，这样在部署的时候，会将这些全局变量分别配置到不同的函数中。</p>\n<p>Plugin 就是插件，Serverless 团队提供了超级多的 Plugin，例如上文提到的 serverless-tencent-scf。</p>\n<p>最后就是 Functions，是定义函数的地方。</p>\n<p>创建项目，完成代码编写和 Yaml 的配置之后，接下来就是安装 Plugin：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">\tnpm install</code></pre></div>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071954.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>使用相关功能，例如部署服务：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">\tserverless deploy</code></pre></div>\n<p>在使用这个工具部署的时候，我们并没事先指定账号信息，所以它会自动唤起扫码登录，登陆之后会继续进行操作：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071951.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>操作完成会看到 Service 信息，这里要注意，如果是使用 CICD，就没办法扫码了，必须手动配置账户信息，格式是：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">    [default]\n    tencent_appid = appid\n    tencent_secret_id = secretid\n    tencent_secret_key = secretkey</code></pre></div>\n<p>配置完成之后，在 Yaml 中指定这个文件路径：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071959.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>完成部署之后，触发函数：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071952.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>服务信息：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-71956.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>除此之外，还有很多其它操作，大家有兴趣可以都试一下：</p>\n<ul>\n<li>创建服务</li>\n<li>打包服务</li>\n<li>部署服务</li>\n<li>部署函数</li>\n<li>云端调用</li>\n<li>查看日志</li>\n<li>回滚服务</li>\n<li>删除服务</li>\n<li>获取部署列表</li>\n<li>获取服务详情</li>\n<li>获取统计数据</li>\n</ul>\n<p>…</p>\n<p>需要注意的是，Plugin 是函数开发者工具，只针对对函数资源的管理（触发器除外），不包括 API 网关、COS、数据库、CDN 等。另外，在腾讯云函数中只有命名空间和函数的概念，但是在 Serverless Framework Plugin 中却有 Service、Stage 以及函数的三层概念，同时云函数在 Plugin 不支持命名空间，所以我们可以理解为，云函数只有函数的概念，而工具却有服务、阶段和函数的三层概念，这就会产生问题：Service 和 Stage 是什么？在函数中怎么体现？</p>\n<p>以我们刚才部署的 hello_world 为例：</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071953.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>从上图可以看到，Service 和 Stage 体现在函数名和标签两个地方。函数名在简单使用时可能没有影响，但如果涉及到函数间调用或者是云 API 使用函数时，就要注意，这里的函数名并不是在 Yaml 中的函数名！</p>\n<p>当然，这里也会出现另一个问题，即如果用户已经有一个函数，且这个函数不是按照三段式命名的，那么可能没有办法使用 Plugin 进行部署，除非把函数进行迁移，将原函数删掉，使用 Serverless 重新进行部署。</p>\n<h2 id=\"什么是-serverless-component\"><a href=\"#%E4%BB%80%E4%B9%88%E6%98%AF-serverless-component\" aria-label=\"什么是 serverless component 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 Component</h2>\n<p>Plugin 主要是对函数的管理，那么 Component 呢？Component 可以认为是云产品的工具，因为通过 Componnt 可以对所有的组件进行组合使用，甚至还可以很简单开发出自己的 Component 来满足需求。</p>\n<p>Component 的 Yaml 是一段一段的，而 Plugin 的 Yaml 是一个整体，Component 中前后两个组件可能是完全没有任何关系的，例如：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"45689013211846170000\"\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(`test1:\n  component: &quot;@gosls/tencent-website&quot;\n  inputs:\n    code:\n      src: ./public\n      index: index.html\n      error: index.html\n    region: ap-shanghai\n    bucketName: test1\n\n\ntest2:\n  component: &quot;@gosls/tencent-website&quot;\n  inputs:\n    code:\n      src: ./public\n      index: index.html\n      error: index.html\n    region: ap-shanghai\n    bucketName: test2`, `45689013211846170000`)\"\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\">test1</span><span class=\"token punctuation\">:</span>\n  <span class=\"token key atrule\">component</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"@gosls/tencent-website\"</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> ./public\n      <span class=\"token key atrule\">index</span><span class=\"token punctuation\">:</span> index.html\n      <span class=\"token key atrule\">error</span><span class=\"token punctuation\">:</span> index.html\n    <span class=\"token key atrule\">region</span><span class=\"token punctuation\">:</span> ap<span class=\"token punctuation\">-</span>shanghai\n    <span class=\"token key atrule\">bucketName</span><span class=\"token punctuation\">:</span> test1\n\n\n<span class=\"token key atrule\">test2</span><span class=\"token punctuation\">:</span>\n  <span class=\"token key atrule\">component</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"@gosls/tencent-website\"</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> ./public\n      <span class=\"token key atrule\">index</span><span class=\"token punctuation\">:</span> index.html\n      <span class=\"token key atrule\">error</span><span class=\"token punctuation\">:</span> index.html\n    <span class=\"token key atrule\">region</span><span class=\"token punctuation\">:</span> ap<span class=\"token punctuation\">-</span>shanghai\n    <span class=\"token key atrule\">bucketName</span><span class=\"token punctuation\">:</span> test2</code></pre></div>\n<p>通过 Yaml 我们可以看到整个的代码可以分为两部分，是把一个网站的代码放到了不同的 Bucket。</p>\n<p>目前腾讯云的 Component 的基础组件包括：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"32291391642722435000\"\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/tencnet-scf\n@serverless/tencnet-cos\n@serverless/tencnet-cdn\n@serverless/tencnet-apigateway\n@serverless/tencnet-cam-role\n@serverless/tencnet-cam-policy`, `32291391642722435000`)\"\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\">@serverless/tencnet<span class=\"token punctuation\">-</span>scf\n@serverless/tencnet<span class=\"token punctuation\">-</span>cos\n@serverless/tencnet<span class=\"token punctuation\">-</span>cdn\n@serverless/tencnet<span class=\"token punctuation\">-</span>apigateway\n@serverless/tencnet<span class=\"token punctuation\">-</span>cam<span class=\"token punctuation\">-</span>role\n@serverless/tencnet<span class=\"token punctuation\">-</span>cam<span class=\"token punctuation\">-</span>policy</code></pre></div>\n<p>封装的上层 Component 包括：</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"9020897538471040000\"\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/tencnet-express\n@serverless/tencnet-bottle\n@serverless/tencnet-django\n@serverless/tencnet-egg\n@serverless/tencnet-fastify\n@serverless/tencnet-flask\n@serverless/tencnet-koa\n@serverless/tencnet-laravel\n@serverless/tencnet-php-slim\n@serverless/tencnet-pyramid\n@serverless/tencnet-tornado\n@serverless/tencnet-website`, `9020897538471040000`)\"\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\">@serverless/tencnet<span class=\"token punctuation\">-</span>express\n@serverless/tencnet<span class=\"token punctuation\">-</span>bottle\n@serverless/tencnet<span class=\"token punctuation\">-</span>django\n@serverless/tencnet<span class=\"token punctuation\">-</span>egg\n@serverless/tencnet<span class=\"token punctuation\">-</span>fastify\n@serverless/tencnet<span class=\"token punctuation\">-</span>flask\n@serverless/tencnet<span class=\"token punctuation\">-</span>koa\n@serverless/tencnet<span class=\"token punctuation\">-</span>laravel\n@serverless/tencnet<span class=\"token punctuation\">-</span>php<span class=\"token punctuation\">-</span>slim\n@serverless/tencnet<span class=\"token punctuation\">-</span>pyramid\n@serverless/tencnet<span class=\"token punctuation\">-</span>tornado\n@serverless/tencnet<span class=\"token punctuation\">-</span>website</code></pre></div>\n<p>基础 Component 指的是可通过相关的 Component 部署相关的资源，例如 tencent-scf 就可以部署云函数，tencent-cos 就可以部署一个存储桶；上层的 Component 实际上就是对底层 Component 的组合，同时增加一些额外的逻辑，实现一些高阶功能，例如 tencent-django 就可以通过对请求的 WSGI 转换，将 Django 框架部署到云函数上，其底层依赖了 tencent-scf/tencent-apigateway 等组件。</p>\n<p>相对于 Plugin 而言，Component 并没有那么多的操作，只有两个：部署和移除。</p>\n<p>例如部署操作：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">serverless --debug</code></pre></div>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-71959.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>移除操作：</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">serverless remove --debug</code></pre></div>\n<p><img src=\"https://img.serverlesscloud.cn/2020-03-31-071958.png\" alt=\"入门 Serverless ：Serverless Framework开发者工具\"></p>\n<p>相对于 Plugin 而言，Component 的产品纬度是增加了，但是实际功能数量是缩减了。不过，这也不是大的问题，毕竟 Plugin 可以和 Component 混用，真正需要解决的问题是，这两者的 Yaml 不一样，如何混用？</p>\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<ul>\n<li>Plugin 部署到线上的函数，会自动变更名字，例如函数是 myFunction，服务和阶段是 myService-Dev，那么函数部署到线上就是 myService-Dev-myFunction，这样的函数名，很可能会让函数间调用产生很多不可控因素：如果环境是 Dev，函数间调用就要写函数名是 myService-Dev-myFunction，如果环境是 Test，此时就要写 myService-Test-myFunction。在我看来，环境更改只需要更改配置，无需更改更深入的代码逻辑，因此这一点会让我觉得不友好；</li>\n<li>Plugin 也是有优势的，例如如果有 Invoke、Remove 以及部署单个函数的功能，同时 Plugin 也有全局变量，它像是一个开发者工具，可以进行开发、部署、调用、查看信息、指标以及删除回滚等操作；</li>\n<li>Components 可以看作是一个组件集，这里面包括了很多的 Components，有基础的 Components，例如 cos、scf、apigateway 等，也有一些拓展的 Components，例如在 cos 上拓展出来的 website，可以直接部署静态网站等，还有一些框架级的，例如 Koa，Express；</li>\n<li>Components 除了支持的产品多，可以部署框架之外，对我来说，最大吸引力在于其部署到线上的函数名字就是指定的名字，不会出现额外的东西；</li>\n<li>Components 相对 Plugin 在功能上略显单薄，除了部署和删除，再没有其他功能。当你需要部署多个东西，并写在了某个 Components 的 yaml 上，那么即使你只修改了一个函数，它都需要全部重新部署一遍；</li>\n<li>Components 更多的定义是组件，所以在 Components 中是没有全局变量的。</li>\n</ul>\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-25-developer-tools/#%E5%88%9D%E6%8E%A2-serverless-%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7\">初探 Serverless 开发者工具</a></li>\n<li><a href=\"/blog/2020-03-25-developer-tools/#%E4%BB%80%E4%B9%88%E6%98%AF-serverless-plugin\">什么是 Serverless Plugin</a></li>\n<li><a href=\"/blog/2020-03-25-developer-tools/#%E4%BB%80%E4%B9%88%E6%98%AF-serverless-component\">什么是 Serverless Component</a></li>\n<li><a href=\"/blog/2020-03-25-developer-tools/#%E6%80%BB%E7%BB%93\">总结</a></li>\n</ul>"},"previousBlog":{"id":"a6531d60-e5c7-5da3-9e26-26978f8c068f","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020327/1585307844594-1212.jpg","authors":["serverless 社区"],"categories":["meetup"],"date":"2020-03-29T00:00:00.000Z","title":"基于 Vuejs + Express 快速构建 Serverless 应用 - 在线 Workshop","description":"Authing 的全栈工程师高鹏洋将实操教学如何基于 Vuejs+Express 快速构建 Serverless 应用","authorslink":["https://serverlesscloud.cn"],"translators":null,"translatorslink":null,"tags":["Serverless","Meetup"],"keywords":"Serverless 全局变量组件,Serverless 单独部署组件,Serverless Component","outdated":null},"wordCount":{"words":139,"sentences":35,"paragraphs":35},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-29-vuejs-express-meetup.md","fields":{"slug":"/blog/2020-03-29-vuejs-express-meetup/","keywords":["serverless","云函数","Serverless","serverless","serverlesscloud","Zoom","应用","分享","腾讯"]}},"nextBlog":{"id":"7815ab56-0a6c-5217-9f4c-5c5759f734dd","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020327/1585281283389-1.jpeg","authors":["Anycodes"],"categories":["guides-and-tutorials"],"date":"2020-03-23T00:00:00.000Z","title":"入门 Serverless：如何实现 Hello World？","description":"在云计算领域，有这样一个技术被众多云厂商认为是「风口项目」，甚至可以颠覆现有云计算中的某些格局，它就是 Serverless 技术。","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["Serverless","Component"],"keywords":"Serverless 全局变量组件,Serverless 单独部署组件,Serverless Component","outdated":null},"wordCount":{"words":959,"sentences":106,"paragraphs":97},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-03-23-helloworld.md","fields":{"slug":"/blog/2020-03-23-helloworld/","keywords":["go","python","serverless","函数计算","云函数","Serverless","函数","Hello","serverlesscloud"]}},"recommendBlogs":{"edges":[{"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"]}}},{"node":{"id":"6a16520b-7886-582e-9182-64e50712d486","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/vendor+choice/serverless-data-portability.jpg","authors":["NickGottlieb"],"categories":["engineering-culture","guides-and-tutorials"],"date":"2018-06-20T00:00:00.000Z","title":"浅谈无服务器、数据锁定和供应商选择","description":"供应商选择是如今 IT 领导者需要考虑的最重要事项，而这一点可利用数据可移植性来实现。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":205,"sentences":33,"paragraphs":33},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-06-20-data-lockin-vendor-choice-portability.md","fields":{"slug":"/blog/2018-06-20-data-lockin-vendor-choice-portability/","keywords":["go","serverless","无服务器","无服务器架构","供应商","serverless","开发人员","数据","锁定","选择","服务"]}}},{"node":{"id":"94741abb-10ba-5db1-9756-cd1d573473fa","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/webstorm-ide/streamline-webstorm-serverless2.jpg","authors":["EslamHefnawy"],"categories":["guides-and-tutorials","engineering-culture"],"date":"2018-08-15T00:00:00.000Z","title":"如何使用 WebStorm 简化无服务器工作流程","description":"在本文中，我将和您分享如何使用 WebStorm 进行无服务器特定的 IDE 设置以及如何利用它来极大地加快无服务器工作流程。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":234,"sentences":54,"paragraphs":54},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-08-15-streamline-serverless-workflow-webstorm.md","fields":{"slug":"/blog/2018-08-15-streamline-serverless-workflow-webstorm/","keywords":["nodejs","serverless","无服务器","无服务器开发","serverless","WebStorm","webstorm","服务器","blog","assets"]}}},{"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":"17c972d9-0583-51f6-9d5d-c2ba5f21b6a3","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/20191227/1577409288454-v2-577c2b21d600e3ea07f156f3e9d2d6b8_1200x500.jpg","authors":["Alfred Huang"],"categories":["guides-and-tutorials"],"date":"2019-08-21T00:00:00.000Z","title":"Serverless 的运行原理与组件架构","description":"本文重点探讨下开发者使用 Serverless 时经常遇到的一些问题，以及如何解决","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["运行原理","serverless"],"keywords":"Serverless 运行原理,Serverless 组件架构","outdated":null},"wordCount":{"words":236,"sentences":33,"paragraphs":33},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-08-21-serverless-operation-architecture.md","fields":{"slug":"/blog/2019-08-21-serverless-operation-architecture/","keywords":["koa","serverless","云函数","Serverless","用户","函数","请求","实例","形态","业务","serverlesscloud"]}}},{"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"]}}},{"node":{"id":"545ab3d2-e14e-5cc2-8548-0e863eac942b","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/2019-10-deployment-best-practices/safeguard-header.png","authors":["FernandoMedinaCorey"],"categories":["guides-and-tutorials"],"date":"2019-10-14T00:00:00.000Z","title":"无服务器部署最佳实践","description":"了解部署无服务器应用时的一些最佳实践。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":221,"sentences":46,"paragraphs":46},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-10-14-serverless-deployment-best-practices.md","fields":{"slug":"/blog/2019-10-14-serverless-deployment-best-practices/","keywords":["serverless","无服务器","serverless","部署","服务器","开发人员","应用","安全措施","使用","函数"]}}}],"totalCount":31}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"dc6a99cf-6d6a-523d-945b-ad2c8aac8c75","previousBlogId":"a6531d60-e5c7-5da3-9e26-26978f8c068f","nextBlogId":"7815ab56-0a6c-5217-9f4c-5c5759f734dd","categories":["guides-and-tutorials"]}}}