了解机器:JavaScript函数的开放标准

了解机器:JavaScript函数的开放标准

时间:2020-7-6 作者:gykj

作为开发人员,我们始终在寻求方法来更好地完成我们的工作,无论是遵循模式,使用编写良好的库和框​​架,还是您拥有什么。在本文中,我将与您分享一个易用功能的JavaScript规范。本文面向JavaScript开发人员,您将学习如何使用通用API编写JavaScript函数,该API使这些函数的使用变得容易。这对于创作npm软件包特别有用(我们将在本文结尾看到)。

本文没有特殊的先决条件。如果您可以编写JavaScript函数,则可以继续进行。话虽如此,让我们深入。

什么是机器?

机器是遵循Mike麦克尼尔(Mike McNeil)编写的机器规范的自我记录和可预测的JavaScript函数。机器的特征如下:

  • 它必须有一个明确的目的,即发送电子邮件,发出JSON Web令牌,发出获取请求等。
  • 它必须遵循规范,这使得通过npm安装可以预测机器的消耗。

作为示例,这是一组机器的集合,这些机器提供了与Cloudinary一起使用的简单且一致的API。该集合展示用于上传图像,删除图像等的功能(机器)。这就是所有机器的本质:它们只是公开了一个简单且一致的API,用于处理JavaScript和Node.js函数。

机器特点

  • 机器是自我记录的。这意味着您可以只看一台机器,就知道它在做什么以及它将运行什么(参数)。这个功能真的让我很卖。所有机器都是自记录文件,可预测。
  • 我们将看到,机器可以快速实施。使用用于命令行界面(CLI)的machinepack工具,我们可以快速搭建机器并将其发布到npm。
  • 机器易于调试。这也是因为每台机器都有一个标准化的API。我们可以轻松调试机器,因为它们是可预测的。

那里有机器吗?

您可能会想:“如果机器性能很好,那为什么直到现在我还没有听说过它们?” 实际上,它们已经被广泛使用。如果您使用过Node.js MVC框架Sails.js,那么您已经编写了机器或与夫妇建立了接口。Sails.js的作者还是机器规范的作者。

除了Sails.js框架之外,您还可以通过搜索machinepack来浏览npm上可用的计算机,或者转到http://node-machine.org/machinepacks,它是machinepack的注册表守护程序;它与npm同步并每10分钟更新一次。

机器是通用的。作为包装消费者,您会知道会发生什么。因此,无需再尝试猜测已安装的特定软件包的API。如果是机器,则可以期望它遵循相同的易于使用的界面。

现在我们已经了解了什么是机器,让我们通过分析示例机器来研究规格。

机器规格

    module.exports = {
  friendlyName: 'Do something',
  description: 'Do something with the provided inputs that results in one of the exit scenarios.',
  extendedDescription: 'This optional extended description can be used to communicate caveats, technical notes, or any other sort of additional information which might be helpful for users of this machine.',
  moreInfoUrl: 'https://stripe.com/docs/api#list_cards',
  sideEffects: 'cacheable',
  sync: true,

  inputs: {
    brand: {
      friendlyName: 'Some input',
      description: 'The brand of gummy worms.',
      extendedDescription: 'The provided value will be matched against all known gummy worm brands. The match is case-insensitive, and tolerant of typos within Levenstein edit distance <= 2 (if ambiguous, prefers whichever brand comes first alphabetically).',
      moreInfoUrl: 'http://gummy-worms.org/common-brands?countries=all',
      required: true,
      example: 'haribo',
      whereToGet: {
        url: 'http://gummy-worms.org/how-to-check-your-brand',
        description: 'Look at the giant branding on the front of the package. Copy and paste with your brain.',
        extendedDescription: 'If you don\'t have a package of gummy worms handy, this probably isn\'t the machine for you. Check out the `order()` machine in this pack.'
      }
    }
  },

  exits: {
    success: {
      outputFriendlyName: 'Protein (g)',
      outputDescription: 'The grams of gelatin-based protein in a 1kg serving.',
    },
    unrecognizedFlavors: {
      description: 'Could not recognize one or more of the provided `flavorStrings`.',
      extendedDescription: 'Some **markdown**.',
      moreInfoUrl: 'http://gummyworms.com/flavors',
    }
  },

  fn: function(inputs, exits) {
    // ...
    // your code here
    var result = 'foo';
    // ...
    // ...and when you're done:
    return exits.success(result);
  };
}

上面的摘录摘自官方网站上的交互式示例。让我们剖析这台机器。

通过查看上面的代码片段,我们可以看到机器是包含某些标准化属性和单个功能的导出对象。首先让我们看看这些属性是什么以及为什么这样。

  • friendlyName
    这是机器的显示名称,它遵循以下规则:

    • 是句子大小写(就像普通句子一样),
    • 不得标点符号结尾,
    • 不得超过50个字符。
  • description
    在机器操作的命令性情绪(即权威声音)中,这应该是一个清晰的单句描述。一个示例是“发出JSON Web令牌”,而不是“发出JSON Web令牌”。它唯一的约束是:

    • 它应该少于80个字符。
  • extendedDescription(可选)
    此属性提供可选的补充信息,扩展了description属性中已经说过的内容。在此字段中,您可以使用标点符号和完整的句子。

    • 它应该少于2000个字符。
  • moreInfoUrl(可选)
    此字段包含一个URL,可在其中找到有关机器内部工作或功能的其他信息。这对于与第三方API(例如GitHub和Auth0)进行通信的计算机特别有用。

    • 确保使用完全限定的URL,例如http://xyz.abc/qwerty
  • sideEffects(可选)
    这是一个可选字段,您可以省略或将其设置为cacheableidempotent。如果设置为cacheable,则.cache()可以在本机上使用。请注意,只有没有的机器才sideEffects应设置为cacheable
  • sync(可选)
    默认情况下,计算机是异步的。设置该sync选项以true关闭该机器的异步功能,然后可以将其用作常规功能(不带asyncawaitthen())。

输入

这是机器功能期望值的说明或声明。让我们看一下机器输入的不同字段。

  • brand
    使用上面的机器片段作为我们的指南,品牌字段称为输入键。它通常是驼峰式的,并且必须是一个以小写字母开头的字母数字字符串。

    • 输入键标识符或字段中不允许使用特殊字符。
  • friendlyName
    这是输入的人类可读显示名称。这应该:

    • 以句子为例,
    • 没有结尾标点符号
    • 少于50个字符。
  • description
    这是描述输入用途的简短描述。
  • extendedDescription
    就像extendedDescription机器本身上的字段一样,此字段提供有关此特定输入的补充信息。
  • moreInfoUrl
    这是一个可选URL,如果需要,它提供有关输入的更多信息。
  • required
    默认情况下,每个输入都是可选的。这意味着如果在运行时未为输入提供任何值,则将fn未定义。如果您的输入不是可选的,则最好将此字段设置为true,因为这会使机器抛出错误。
  • example
    该字段用于确定输入的预期数据类型。
  • whereToGet
    这是一个可选的文档对象,它提供有关如何找到此输入的适当值的附加信息。这对于诸如API密钥,令牌等之类的东西特别有用。
  • whereToGet.description
    这也是一个单句的清晰描述,也以命令式语气描述了如何为该输入找到正确的值。
  • extendedDescription
    这提供了有关在何处获得此机器的合适输入值的附加信息。

出口

这是该机器的fn实现可以触发的所有可能的退出回调的规范。这意味着每个出口代表机器执行的一个可能结果。

  • success
    这是机器规格中的标准化退出键,表示一切正常,机器正常运行,没有任何错误。让我们看一下它可能公开的属性:

    • outputFriendlyName
      这只是出口输出的显示名称。
    • outputDescription
      这个简短的名词短语描述了出口的输出。

其他出口表示出了点问题,并且机器遇到了错误。此类出口的命名约定应遵循输入键的命名约定。让我们看看这些出口下的字段:

  • description
    这是描述何时调用出口的简短描述。
  • extendedDescription
    这提供了有关何时将调用此出口的其他信息。它是可选的。您可以在此字段中使用完整的Markdown语法,并且通常应少于2000个字符。

你做到了!

要花很多钱。但是请放心:开始编写计算机时,这些约定会生效,尤其是在您的第一台计算机之后,我们很快就会一起编写这些约定。但首先…

机器包装

在编写机器时,您会在npm上发布机器包。它们只是一组相关的实用程序,用于使用Node.js执行常见的重复性开发任务。假设您有一个可以处理数组的机器包;这将是机器的捆绑阵列上,比如工作concat()map()等看到阵列machinepack在注册表中得到一个完整的视图。

机器包命名约定

所有机器包都必须遵循以“ machinepack-”作为前缀以及机器名的标准。例如,machinepack-array,machinepack-sessionauth。

我们的第一个机器包

为了更好地理解机器,我们将编写并发布一个机器包,该机器包是文件贡献者 npm包的包装器。

入门

我们需要以下条件来制作机器包:

  1. 您可以通过运行以下命令来获得Machinepack CLI工具
    npm install -g machinepack
    
  2. Yeoman脚手架工具
    可通过运行以下命令全局安装:

     npm install -g yo
    
  3. Machinepack Yeomen generator
    像这样安装:

    npm install -g generator-machinepack
    

注意我假设您的计算机上已经安装了Node.js和npm。

生成您的第一个机器包

使用上面安装的CLI工具,让我们使用machinepack生成器生成一个新的machinepack。为此,请首先进入要让生成器在其中生成文件的目录,然后运行以下命令:

yo machinepack

上面的命令将启动一个交互式过程,为您生成准系统机器包。它会问您几个问题。请确保对创建示例计算机的操作说是。

注意: 我注意到在使用Node.js 12或13时Yeoman生成器存在一些问题。因此,我建议使用nvm并安装Node.js 10.x,这是对我有用的环境。

如果一切按计划进行,那么我们将生成机器包的基础层。让我们来看看:

DELETE_THIS_FILE.md
machines/
package.json
package.lock.json
README.md
index.js
node_modules/

以上是为您生成的文件。让我们玩一下位于machines目录中的示例机器。因为我们安装了machinepack CLI工具,所以我们可以运行以下命令:

machinepack ls

这将在我们的machines目录中列出可用的计算机。目前,有一台“说你好”机器。让我们通过运行以下命令找出say-hello的作用:

machinepack exec say-hello

这将提示您输入一个名称,并将打印say-hello计算机的输出。

您会注意到,CLI工具正在利用机器的标准化来获取机器的描述和功能。漂亮整齐!

让我们做一台机器

让我们添加一台自己的机器,该机器将包裹文件提供者和node-fetch包(我们还需要使用npm安装它们)。因此,运行以下命令:

npm install file-contributors node-fetch --save

然后,通过运行添加新机器:

machinepack add

系统将提示您填写机器的友好名称,描述(可选)和扩展描述(也是可选)。之后,您将成功生成计算机。

现在,让我们充实这台机器的功能。打开您在编辑器中生成的新计算机。然后,需要file-contributors软件包,如下所示:

const fetch = require('node-fetch');
const getFileContributors = require('file-contributors').default;

global.fetch = fetch; // workaround since file-contributors uses windows.fetch() internally

注意: 我们正在使用node-fetch包和global.fetch = fetch解决方法,因为file-contributors包在windows.fetch()内部使用,而Node.js中不提供。

文件提供者getFileContributors需要使用三个参数才能工作:(owner存储库的所有者),repo(存储库)和path(文件的路径)。因此,如果您一直遵循,那么您会知道这些将成为我们的inputs关键。现在添加这些:

...
 inputs: {
    owner: {
      friendlyName: 'Owner',
      description: 'The owner of the repository',
      required: true,
      example: 'DominusKelvin'
    },
    repo: {
      friendlyName: 'Repository',
      description: 'The Github repository',
      required: true,
      example: 'machinepack-filecontributors'
    },
    path: {
      friendlyName: 'Path',
      description: 'The relative path to the file',
      required: true,
      example: 'README.md'
    }
  },
...

现在,让我们添加出口。最初,CLI success为我们添加了一个出口。我们将对此进行修改,然后添加另一个出口,以防事情未按计划进行。

exits: {

    success: {
      outputFriendlyName: 'File Contributors',
      outputDescription: 'An array of the contributors on a particular file',
      variableName: 'fileContributors',
      description: 'Done.',
    },

    error: {
      description: 'An error occurred trying to get file contributors'
    }

  },

最后,让我们制作机器的肉,它是fn

 fn: function(inputs, exits) {
    const contributors = getFileContributors(inputs.owner, inputs.repo, inputs.path)
    .then(contributors => {
      return exits.success(contributors)
    }).catch((error) => {
      return exits.error(error)
    })
  },

和瞧!我们制造了第一台机器。让我们通过运行以下命令使用CLI进行尝试:

machinepack exec get-file-contributors

一个提示符出现询问ownerrepopath,先后。如果一切都按计划进行,那么我们的机器将成功退出,并且我们将看到我们指定的存储库文件的贡献者数组。

代码中的用法

我知道我们不会使用CLI在我们的代码库中使用机器包。因此,以下是我们如何使用机器包中的机器的摘要:

    var FileContributors = require('machinepack-filecontributors');

// Fetch metadata about a repository on GitHub.
FileContributors.getFileContributors({
  owner: 'DominusKelvin',
  repo: 'vue-cli-plugin-chakra-ui',
   path: 'README.md' 
}).exec({
  // An unexpected error occurred.
  error: function (){
  },
  // OK.
  success: function (contributors){
    console.log('Got:\n', contributors);
  },
});

结论

恭喜你!您刚刚熟悉机器规格,创建了自己的机器,并了解了如何使用机器。我很高兴看到您创建的机器。

版权所有:https://www.eraycloud.com 转载请注明出处