用 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:
以及以下开发依赖项:
- @types/node - Node.js 的类型定义
- nodemon——如果你不知道这是什么,现在就应该停止阅读本教程,去做点别的事情了。
- ts-node - 执行环境和 REPL(如果你需要搜索 REPL,说真的,请去做点别的事情吧)
- 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