本文参加了由公众号@若川视野发起的每周源码共读活动,点击了解详情一起参与。
这是源码共读的第14期,链接:juejin.cn/post/708315…。
源码
import {promisify} from 'node:util';
import childProcess from 'node:child_process';
const execFile = promisify(childProcess.execFile);
export default async function remoteGitTags(repoUrl) {
const {stdout} = await execFile('git', ['ls-remote', '--tags', repoUrl]);
const tags = new Map();
for (const line of stdout.trim().split('\n')) {
const [hash, tagReference] = line.split('\t');
const tagName = tagReference.replace(/^refs\/tags\//, '').replace(/\^{}$/, '');
tags.set(tagName, hash);
}
return tags;
}
示例:
const tags = await remoteGitTags('https://github.com/facebook/react');
使用 execFile
方法执行 git ls-remote --tags repoUrl
获取所有 tags
和 tags
对应 hash
值存放在 Map
对象中。
归纳
node:child_process
child_process
用来创建子进程
-
异步方式:
spawn
exec
execFile
fork
-
同步方式:
spawnSync
execSync
execFileSync
spawn
spawn(command[, args][, options]): ChildProcess
command: 要执行的指令
args: 传递参数
options: 配置项
示例:
spawn('ls', ['-l'], {stdio: 'inherit'})
stdio
选项用于配置父进程和子进程之间建立的管道
inherit
方式使得子进程直接使用父进程的 stdio
,因此可以看到输出
exec
exec(command[, options][, callback]): ChildProcess
command: 要执行的指令
options: 配置项
callback:回调
示例:
exec('ls', (error, stdout, stderror) => {
console.log('stdout', stdout)
})
execFile
exec(command[, args][, callback]): ChildProcess
command: 要执行的指令
args: 传递参数
callback:回调
示例:
execFile('ls', ['-l'], (error, stdout, stderror) => {
console.log('stdout', stdout)
})
fork
fork(modulePath[, options]): ChildProcess
modulePath: 要执行模块路径
options: 配置项
示例:
a.js
function sayHello() {
console.log('hello')
}
sayHello()
const n = fork('./a.js')
n.on('message', m => {
console.log('m', m) // hello
})
spawnSync
spawnSync(command[, options]): SpawnSyncReturns
command: 要执行的指令
options: 配置项
示例:
const {stdout} = spawnSync('ls', {encoding: 'utf-8'})
console.log('stdout', stdout)
execSync
execSync(command[, options]): string
command: 要执行的指令
options: 配置项
示例:
const execResult = execSync('ls', {encoding: 'utf-8'})
console.log('execResult', execResult)
execFileSync
execFileSync(command[, args][, options]): string | Buffer
command: 要执行的指令
args: 传递参数
options: 配置项
示例:
const execFileResult = execFileSync('ls', ['-ls'], {encoding: 'utf-8'})
console.log('execFileResult', execFileResult)
spawn
/ exec
/ execFile
/ fork
比较
类型 | 回调/异常 | 执行类型 | 可设置参数 |
---|---|---|---|
spawn | 不支持 | 命令 | 不支持 |
exec | 支持 | 命令 | 支持 |
execFile | 支持 | 可执行文件 | 支持 |
fork | 不支持 | JavaScript 文件 | 不支持 |
promisify
promisify()
方法可以将基于回调的函数转换为基于 Promise
的函数。
示例:
- 基于回调的函数
import fs from 'node:fs'
fs.readFile('./package.json', function callback(err, buf) {
const obj = JSON.parse(buf.toString('utf8'))
console.log(obj.name)
})
- 基于
Promise
的函数
import {promisify} from 'node:util';
import fs from 'node:fs'
const readFile = util.promisify(fs.readFile)
const buf = await readFile('./package.json')
const obj = JSON.parse(buf.toString('utf8'))
console.log(obj.name)