发布于 2026-01-06 1 阅读
0

用 TypeScript 编写你自己的 Git 库 - 第一部分

用 TypeScript 编写你自己的 Git 库 - 第一部分

关于 Git 的这句引言给了我启发:

核心的简洁性和强大的应用能力相结合,常常使事物变得很难理解,因为需要从基本抽象概念(比如单子)的本质简洁性中推导出各种各样的应用,这需要思维上的飞跃。

它源自一篇关于用 Python 编写自己的 git 的教程,我决定将其移植到 TypeScript。

在本篇及后续文章中,我们将逐步完成本教程,共需 8 个步骤。代码已尽可能地实现了强类型,可在此处找到。本教程将最终应用程序升级为“功能齐全的 Git 库和 CLI ”的任务留给了读者,因此我们将尝试在此基础上更进一步,甚至完全实现。

我们跳舞吧?

0 - 目标受众

熟悉 NodeJS 且对文件系统有一定基础知识的中级 JS/TS 开发人员。对 TypeScript 感兴趣并正在学习这门语言的人士。

1 - 入门指南

我们的目标是用 TypeScript 创建一个 Node.js 应用,使其功能类似于 wyag。为此,我们需要一个 TypeScript 命令行界面。

我按照这篇教程用Node创建了一个CLI,下面总结一下整个过程:

初始化

在您的文件夹中执行操作npm init,然后将以下依赖项添加到您的文件中package.json

  1. 清除- 清除屏幕
  2. Figlet - Schwaaag 的 ASCII 艺术,
  3. 粉笔- 终端样式
  4. 指挥官- 用于参数
  5. 路径- 用于处理文件和目录路径

以及以下开发依赖项:

  1. @types/node - Node.js 的类型定义
  2. nodemon——如果你不知道这是什么,现在就应该停止阅读本教程,去做点别的事情了。
  3. ts-node - 执行环境和 REPL(如果你需要搜索 REPL,说真的,请去做点别的事情吧)
  4. TypeScript - ❤️

脚本

您的脚本部分package.json应该如下所示:

"scripts": {
  "start": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/index.ts",
  "create": "npm run build && npm run test",
  "build": "tsc -p .",
  "test": "sudo npm i -g && pizza",
  "refresh": "rm -rf ./node_modules ./package-lock.json && npm install"
},

TSconfig

您还需要tsconfig.json在与主文件相同的文件夹中创建一个文件,package.json内容如下:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "lib": ["es6", "es2015", "dom"],
    "declaration": true,
    "outDir": "lib",
    "rootDir": "src",
    "strict": true,
    "types": ["node"],
    "esModuleInterop": true,
    "resolveJsonModule": true
  }
}

创建 CLI

src在目录中创建一个文件夹,并index.ts在其中创建一个文件。然后开始编辑:

我们从一个普通的事件开始

#!/usr/bin/env node

清除屏幕:

clear()

导入依赖项:

const chalk = require('chalk');
const clear = require('clear');
const figlet = require('figlet');
const path = require('path');
const program = require('commander');

显示横幅:

console.log(
  chalk.green(
    figlet.textSync('sustain', { font: 'slant', horizontalLayout: 'full' })
  ));

将我们需要处理的命令/参数添加到 CLI 应用程序中:

program
  .version('0.0.1')
  .description('A distributed version control system')
  .option('-i, --init', 'Init a repo')
  .option('-a, --add', 'Add file')
  .option('-c, --cat', 'Cat file')
  .option('-t, --checkout', 'Checkout')
  .option('-m, -commit', 'Commit')
  .option('-h, -hash', 'Hash Object')
  .option('-l, -log', 'Log')
  .option('-t, -ls-tree', 'Hash Object')
  .option('-h, -hash', 'Hash Object')
  .option('-g, -merge', 'Merge')
  .option('-r, -rebase', 'Rebase')
  .option('-v, -rev', 'Rev parse')
  .option('-r, -rm', 'Remove')
  .option('-s, -show', 'Show ref')
  .option('-t, -tag', 'Tag')
  .parse(process.argv);

接下来,我们需要为用户发送的参数添加一些占位符操作,稍后我们会回到这里,为每个参数编写相应的函数:

if (program.init) console.log(' - Initialize a repo');
if (program.add) console.log('  - Add file');
if (program.cat) console.log('  - Cat file');
if (program.checkout) console.log('  - Checkout');
if (program.commit) console.log('  - Commit');
if (program.hash) console.log('  - Hash object');
if (program.log) console.log('  - Log');
if (program.lstree) console.log(' - Show dir tree');
if (program.merge) console.log('  - Merge');
if (program.rebase) console.log('  - Rebase');
if (program.rparse) console.log('  - Rev parse');
if (program.rm) console.log(' - Remove');
if (program.show) console.log('  - Show ref');
if (program.tag) console.log('  - Tag');

最后,添加以下内容以实现用户需要帮助时的必填参数-h--help

if (!process.argv.slice(2).length) {
  program.outputHelp();
}

现在运行npm run build并调用该程序,你应该会看到类似这样的输出:
第一屏幕

下一部分我们将向SusRepository程序中添加类,这是我们的基本构建模块。我们还将向代码中添加一些实用函数。然后我们将实现该init命令,并编写一个RepoFind函数,该函数将递归地查找 Git 目录以实现我们的init功能。

您可以点击此处阅读我博客上的原文

文章来源:https://dev.to/surajsharma/write-your-own-git-in-typescript-part-1-3g8m