一.简介

remote-git-tags主要是从git仓库中获取tags,根据readme文档,可以看到相应的用法

安装


  1. $ npm install remote-git-tags

使用


  1. import remoteGitTags from 'remote-git-tags';
  2. console.log(await remoteGitTags('https://github.com/sindresorhus/remote-git-tags'));
  3. //=> Map {'v1.0.0' => '69e308412e2a5cffa692951f0274091ef23e0e32', …}

相关的API,可以查看readme文档,仓库地址

二.源码部分

package.json

  1. {
  2. ...
  3. "type": "module",
  4. "exports": "./index.js",
  5. "engines": {
  6. "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
  7. },
  8. "scripts": {
  9. "test": "xo && ava"
  10. },
  11. ...
  12. "devDependencies": {
  13. "ava": "^3.15.0",
  14. "xo": "^0.44.0"
  15. }
  16. }

从package.json的文件中,我们可以看到有2个依赖:avaxoava和xo是用进行测试的。ava测试需要建立一个测试的文件,就是目录中的test.js
test.js

  1. import test from 'ava';
  2. import remoteGitTags from './index.js';
  3. test('main', async t => {
  4. const tags = await remoteGitTags('https://github.com/sindresorhus/got');
  5. t.is(tags.get('v6.0.0'), 'e5c2d9e93137263c68db985b3dc5b57865c67b82');
  6. t.is(tags.get('v5.0.0'), '0933d0bb13f704bc9aabcc1eec7a8e33dc8aba51');
  7. });

执行

  1. npm run test

得到的结果:
image.png
下面主要看下主文件
index.js

  1. import {promisify} from 'node:util';
  2. import childProcess from 'node:child_process';
  3. const execFile = promisify(childProcess.execFile);
  4. export default async function remoteGitTags(repoUrl) {
  5. const {stdout} = await execFile('git', ['ls-remote', '--tags', repoUrl]);
  6. const tags = new Map();
  7. for (const line of stdout.trim().split('\n')) {
  8. const [hash, tagReference] = line.split('\t');
  9. // Strip off the indicator of dereferenced tags so we can override the
  10. // previous entry which points at the tag hash and not the commit hash
  11. // `refs/tags/v9.6.0^{}` → `v9.6.0`
  12. const tagName = tagReference.replace(/^refs\/tags\//, '').replace(/\^{}$/, '');
  13. tags.set(tagName, hash);
  14. }
  15. return tags;
  16. }
  1. import {promisify} from 'node:util';
  2. import childProcess from 'node:child_process';

Node 13.2.0开始支持ES Modules的模式,在Node中使用ESM,需要
1)在 package.json 中,增加 “type”: “module” 配置;例如package.json中的type
2) 在 .mjs 文件可以直接使用 import 和 export

ps:根据 ESM 规范,使用 import 关键字并不会像 CommonJS 模块那样,在默认情况下以文件扩展名填充文件路径。因此,ES Modules 必须明确文件扩展名

可以参考阮一峰的文章:Nodejs如何处理ES6模块

promisify是将callback那种回调格式改成promise的形式,可以进行链式调用;childProcess是Node的子模块,里面的一些函数,例如:execFile可以执行外部应用,类似的还有exec,spawn

利用execFile执行

  1. git ls-remote --tags

结果:
image.png
for循环部分的代码,就是将上图的数据存储在Map中,tagName应用到了字符串的正则匹配

知识点总结:

1.解析赋值:const [hash, tagReference] = line.split(‘\t’);

2.node支持ESM

3.git获取tags的命令:git ls-remote —tag