news 2026/9/17 13:30:40

TypeScript + Nx + semantic-release 工程化实践指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TypeScript + Nx + semantic-release 工程化实践指南

1. 项目概述:一个被严重低估的 TypeScript 工程化能力基座

“agent-skills”这个名称乍看像某个 AI 代理的技能插件包,但结合热搜词agent-skills、TypeScript、node、Nx、semantic-release,再叠加全网高频出现的typescript面试、nx二次开发、typescript + nestjs、nvm安装及全局配置node、linux离线安装node、npm : 无法加载文件 d:\node\npm.ps1等长尾搜索行为——真相立刻清晰:这不是一个面向终端用户的“AI技能库”,而是一个面向前端/全栈工程师的、可复用、可组合、可版本语义化发布的 TypeScript 技能模块集合工程模板。它本质是 Nx 工作区中一类特殊库(library)的标准化实践范式:把通用业务能力(如表单校验、权限路由跳转、文件分片上传、WebSocket 心跳保活、OpenAPI Schema 解析、Mock 数据生成器、错误码统一映射、国际化 key 提取工具)封装成独立、无副作用、类型完备、文档自动生成、测试覆盖率强制达标、发布策略自动化的“技能单元”。

我从 2019 年开始在大型企业级项目中落地 Nx,主导过 3 个超 50 人协作的 monorepo 项目。其中最常被问到的问题不是“怎么写组件”,而是“这个工具函数放哪?谁来维护?改了会不会影响其他团队?上线后怎么知道哪个版本引入了这个新校验规则?”——agent-skills 就是为解决这类“能力归属模糊、复用成本高、演进不可控”问题而生的工程契约。它不提供 UI,不绑定框架,不耦合状态管理,只做一件事:用 TypeScript 的类型系统 + Nx 的依赖图 + semantic-release 的语义化规则,把“一段稳定、可测、可追溯的逻辑”变成一个可被@org/agent-skills-form这样精确引用的 npm 包。

它适合三类人:一是正在搭建企业级前端基建的 Tech Lead,需要统一收口通用能力;二是准备 TypeScript 面试的中级开发者,这里藏着大量高频考点(泛型约束、条件类型、模块声明合并、d.ts 生成、Jest 模拟技巧);三是刚接触 Nx 的工程师,这是理解 workspace.json、project.json、nx.json 三者分工最直观的入口。你不需要懂 LLM 或 Agent 架构,但必须理解declare module 'fs'export * as utils from './utils'在类型层面的差异——因为 agent-skills 的核心价值,就藏在这类细节里。

2. 整体设计思路与架构选型逻辑

2.1 为什么是 Nx 而非 Turborepo 或 pnpm workspaces?

很多人看到 “monorepo” 第一反应是 pnpm workspaces,但 agent-skills 的设计目标决定了它必须选择 Nx。关键区别在于依赖拓扑感知能力。pnpm workspaces 只解决包链接(symlink),而 Nx 能静态分析出@org/agent-skills-auth库被@org/agent-skills-http@org/app-admin同时依赖,当修改 auth 的login()函数签名时,Nx 可以精准计算出哪些测试必须重跑、哪些应用需要重新构建、哪些 CI 任务可以跳过。这在 agent-skills 场景中至关重要——一个校验规则的变更,绝不该触发整个后台管理系统的全量构建。

我实测过:在 12 个 skills 库、8 个应用组成的 workspace 中,修改@org/agent-skills-validationisEmail()类型定义,pnpm workspaces 下需手动指定受影响范围,而 Nx 通过nx affected --target=test自动识别出 3 个库的测试需执行,耗时 42 秒;若用 pnpm 手动 run script,则平均耗时 217 秒且易漏测。更关键的是 Nx 的project.jsonimplicitDependencies字段,允许你声明“此库变更时,自动触发 docs 项目的构建”,这是 semantic-release 自动发版的前提——没有这个隐式依赖链,release 就成了盲人摸象。

Turborepo 虽然也支持缓存和任务调度,但它缺乏 Nx 的代码质量门禁(如nx enforce强制要求每个库必须有tsconfig.lib.json)、缺乏对 Angular/Vue/React 项目的原生适配(agent-skills 需兼容多框架消费)、缺乏nx graph可视化依赖图(排查循环依赖时救命)。我们曾用 Turborepo 替换 Nx 试运行两周,最终因无法在 CI 中稳定拦截export * from './internal'这类破坏封装的导出而回滚——Nx 的eslint-plugin-nx规则库直接内置了这条检查。

2.2 为什么用 semantic-release 而非 conventional-changelog 手动发版?

agent-skills 的每个库都遵循严格语义化版本:1.2.31是破坏性变更(如移除validatePhone()函数),2是新增功能(如增加validateIdCard()),3是修复(如修正正则表达式边界)。手动维护 CHANGELOG.md 几乎必然出错——去年某次发布,同事在 commit message 写了feat: add phone validator却忘了更新 package.json 的 version,导致下游项目npm install @org/agent-skills-validation@1.2.0实际拉到的是旧版代码,线上表单校验失效 3 小时。

semantic-release 的核心价值在于将版本号完全交给 Git 提交规范驱动。它监听main分支的 push 事件,扫描最近 commit,按feat:前缀自动升minorfix:patchBREAKING CHANGE:major,然后调用 npm publish。更重要的是它与 Nx 深度集成:nx release命令会先执行nx affected --target=build确保所有待发布库构建成功,再调用 semantic-release。我们还定制了@org/release-config包,覆盖默认配置——比如国内 npm registry 镜像地址、私有 registry 认证 token 注入方式、发布前自动运行nx test --coverage强制覆盖率 ≥85%。

提示:semantic-release 默认使用 GitHub Token,但企业内网 GitLab 需要@semantic-release/gitlab插件,并在.releaserc中配置gitlabUrl。我们踩过的坑是:GitLab 的 API 版本必须匹配插件要求,v15.0+ 的 GitLab 需用@semantic-release/gitlab@7.0.0+,否则会报401 Unauthorized

2.3 为什么 TypeScript 是唯一语言选项?

有人问:“JavaScript 不行吗?更轻量。”——不行。agent-skills 的存在意义就是消灭运行时类型错误。举个真实案例:@org/agent-skills-storage提供localStorage.setItem(key, value)的封装,JS 版本只能靠注释写// value must be string,而 TS 版本可写setItem<T extends string>(key: string, value: T): void,消费方传入number会立即报错。更关键的是d.ts文件生成:Nx 构建时自动产出index.d.ts,下游项目无需安装@types/xxx,IDE 直接显示参数提示。

我们曾对比过 JS + JSDoc 方案:在 VS Code 中,JSDoc 的@param {import('./types').User} user无法跨文件跳转,而 TS 的import { User } from './types'支持 Ctrl+Click。对于agent-skills这种被数十个项目引用的基座库,类型即文档,类型即契约。另外,TS 的--declarationMap选项生成.d.ts.map文件,让调试时能直接定位到源码而非编译后代码——这点在排查isDate()函数为何返回 false 时极其关键。

3. 核心细节解析与实操要点

3.1 Nx 工作区初始化:避开 3 个致命陷阱

创建 agent-skills 工作区不能简单npx create-nx-workspace@latest。必须按以下顺序操作,否则后续 80% 的问题都源于此:

  1. 先装 Node.js,再装 Nx CLI
    全网高频问题npm : 无法加载文件 d:\node\npm.ps1的根源是 Windows PowerShell 执行策略限制。正确解法不是关掉策略(安全风险),而是用npm install -g nx安装全局 CLI,然后用npx nx执行命令。这样避免了 PowerShell 对本地 npm.ps1 的调用。

  2. 初始化时禁用默认应用
    npx create-nx-workspace@latest my-workspace --preset=apps会生成 demo app,但 agent-skills 只需库。应使用--preset=empty,然后手动添加库:

    nx g @nrwl/node:library agent-skills-auth --directory=libs/agent-skills --publishable --importPath=@org/agent-skills-auth

    关键参数--publishable表示该库可被外部 npm install,--importPath指定包名,避免默认的@my-workspace/agent-skills-auth

  3. 立即配置 TypeScript 路径别名
    tsconfig.base.jsoncompilerOptions.paths中添加:

    "@org/agent-skills-*": ["libs/agent-skills/*/src/index.ts"]

    否则import { login } from '@org/agent-skills-auth'会报错。注意路径必须指向index.ts,而非index.js——TS 编译器只认源码路径。

注意:Nx 18+ 默认启用projectReferences,这意味着每个库都有独立tsconfig.lib.json。务必检查libs/agent-skills-auth/tsconfig.lib.jsonextends是否指向../../tsconfig.base.json,否则路径别名失效。

3.2 agent-skills 库的标准结构:每个文件都有明确职责

一个合规的agent-skills-auth库目录结构如下(非自动生成,需人工校验):

libs/ agent-skills-auth/ src/ index.ts // 唯一公共入口,只 re-export,禁止逻辑 lib/ login.ts // 核心函数,含完整 JSDoc 和类型定义 logout.ts // 同上 utils/ token.ts // 工具函数,如 parseToken() types/ auth.model.ts // 所有类型定义,如 interface User {} jest.config.ts // 库专属 Jest 配置,覆盖 workspace 级 project.json // Nx 任务定义,含 build/test/lint README.md // 使用示例,含 import 和调用代码块

index.ts内容必须极简:

export * from './lib/login'; export * from './lib/logout'; export * from './utils/token'; export * from './types/auth.model';

禁止在此文件写任何逻辑或默认导出——这是为了确保import * as auth from '@org/agent-skills-auth'时,Tree-shaking 能正常工作。我们曾发现某库在index.ts中写了console.log('init'),导致所有消费方启动时都打印日志,排查耗时 2 天。

login.ts的 JSDoc 必须包含@param@returns@throws

/** * 用户登录函数 * @param credentials 登录凭证,含 username 和 password * @returns Promise<User> 登录成功的用户信息 * @throws {AuthError} 当用户名或密码错误时抛出 */ export async function login(credentials: { username: string; password: string }): Promise<User> { // 实现... }

这样下游项目 hover 时能看到完整文档,VS Code 自动生成调用代码。

3.3 semantic-release 配置:让发版成为无人值守流水线

.releaserc配置是 agent-skills 可靠性的基石。标准配置如下(适配国内环境):

{ "branches": ["main"], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", [ "@semantic-release/npm", { "npmPublish": true, "pkgRoot": "dist/libs/agent-skills-auth" } ], [ "@semantic-release/github", { "assets": ["dist/libs/agent-skills-auth/**/*"] } ] ], "publishConfig": { "registry": "https://registry.npmmirror.com" } }

关键点解析:

  • pkgRoot必须指向 Nx 构建后的dist目录,而非源码src。Nx 默认构建到dist/libs/xxx,semantic-release 会从这里读取package.jsonindex.js
  • registry设为npmmirror.com(淘宝镜像),避免海外 registry 超时。注意:npm set registry https://registry.npmmirror.com只影响本地,CI 中必须在.releaserc显式配置。
  • assets字段让 GitHub Release 附带构建产物(如index.d.ts),方便调试。

CI 脚本(GitHub Actions)示例:

name: Release on: push: branches: [main] jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm ci - run: npx nx build agent-skills-auth - name: Semantic Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npx semantic-release

fetch-depth: 0是必须的——semantic-release 需要完整 Git 历史计算版本号。

4. 实操过程与核心环节实现

4.1 从零搭建 agent-skills-auth 库:手把手步骤

假设你已按 3.1 节完成工作区初始化,现在创建第一个技能库:

Step 1:生成库骨架

nx g @nrwl/node:library agent-skills-auth \ --directory=libs/agent-skills \ --publishable \ --importPath=@org/agent-skills-auth \ --unitTestRunner=jest \ --linter=eslint

参数说明:

  • --directory指定父目录,避免libs/agent-skills-auth这种扁平结构,便于未来扩展agent-skills-http等同级库。
  • --publishable启用构建为 npm 包的能力。
  • --unitTestRunner=jest因为 Nx 对 Jest 的集成最成熟,Vitest 在 Nx 18 中仍需额外配置。

Step 2:编写核心逻辑(login.ts)

// libs/agent-skills-auth/src/lib/login.ts import { User } from '../types/auth.model'; /** * 模拟登录请求(实际项目中替换为 axios/fetch) * @param credentials 登录凭证 * @returns 用户信息 */ export async function login(credentials: { username: string; password: string }): Promise<User> { // 添加基础校验 if (!credentials.username || !credentials.password) { throw new Error('Username and password are required'); } // 模拟 API 调用 return new Promise((resolve) => { setTimeout(() => { resolve({ id: '1', username: credentials.username, email: `${credentials.username}@example.com`, role: 'admin', }); }, 300); }); }

Step 3:编写类型定义(auth.model.ts)

// libs/agent-skills-auth/src/types/auth.model.ts export interface User { id: string; username: string; email: string; role: 'admin' | 'user' | 'guest'; } export type AuthError = Error & { code: string };

Step 4:配置构建输出编辑libs/agent-skills-auth/project.json,确保build目标包含必要配置:

"build": { "executor": "@nrwl/node:webpack", "outputs": ["{workspaceRoot}/dist/libs/agent-skills-auth"], "options": { "outputPath": "dist/libs/agent-skills-auth", "main": "libs/agent-skills-auth/src/index.ts", "tsConfig": "libs/agent-skills-auth/tsconfig.lib.json", "assets": ["libs/agent-skills-auth/*.md"] } }

关键点:main必须指向index.ts(入口),tsConfig指向库专属配置,assets确保 README.md 被复制到 dist。

Step 5:编写测试(login.spec.ts)

// libs/agent-skills-auth/src/lib/login.spec.ts import { login } from './login'; describe('login', () => { it('should resolve with user object when credentials are valid', async () => { const result = await login({ username: 'test', password: '123' }); expect(result).toEqual({ id: '1', username: 'test', email: 'test@example.com', role: 'admin', }); }); it('should throw error when username is empty', async () => { await expect(login({ username: '', password: '123' })).rejects.toThrow( 'Username and password are required' ); }); });

运行nx test agent-skills-auth验证通过。

4.2 构建与发布全流程:一次命令完成

执行以下命令完成从代码到 npm 包的全过程:

# 1. 构建库(生成 dist) nx build agent-skills-auth # 2. 运行测试(确保质量) nx test agent-skills-auth # 3. 生成类型声明(d.ts) # Nx 18+ 自动在 build 中生成,无需额外命令 # 4. 手动发布(仅用于验证) cd dist/libs/agent-skills-auth npm publish --registry=https://registry.npmmirror.com # 5. 自动发布(CI 中执行) npx semantic-release

nx build的输出目录dist/libs/agent-skills-auth结构必须包含:

dist/ libs/ agent-skills-auth/ index.js // 编译后代码 index.d.ts // 类型声明 package.json // 由 Nx 自动生成,含 main/types/exports 字段 README.md // 从源码复制

其中package.json的关键字段:

{ "name": "@org/agent-skills-auth", "version": "0.0.1", // 此值会被 semantic-release 覆盖 "main": "./index.js", "types": "./index.d.ts", "exports": { ".": { "import": "./index.js", "require": "./index.js" } } }

exports字段确保 ESM 和 CommonJS 消费方都能正确导入。

4.3 消费方集成:3 种场景的正确姿势

场景 1:同一 workspace 内部引用
直接 import,Nx 自动处理路径:

// apps/my-app/src/app/app.component.ts import { login } from '@org/agent-skills-auth'; export class AppComponent { async onLogin() { const user = await login({ username: 'admin', password: '123' }); } }

场景 2:外部项目 npm install
安装后 import 方式相同:

npm install @org/agent-skills-auth
import { login } from '@org/agent-skills-auth';

TypeScript 自动读取index.d.ts,无需额外配置。

场景 3:CDN 直接引入(如 Vue SFC)
需构建 UMD 版本。修改project.jsonbuild配置:

"options": { "outputPath": "dist/libs/agent-skills-auth", "main": "libs/agent-skills-auth/src/index.ts", "tsConfig": "libs/agent-skills-auth/tsconfig.lib.json", "format": ["cjs", "esm", "umd"], // 新增 umd "assets": ["libs/agent-skills-auth/*.md"] }

构建后dist/libs/agent-skills-auth/index.umd.js可通过<script src="...">引入,全局变量为agentSkillsAuth

实操心得:我们曾因忘记在project.json中添加format: ["umd"],导致 CDN 用户报错Uncaught ReferenceError: agentSkillsAuth is not defined。解决方案是:在libs/agent-skills-auth/project.jsonbuild.options下添加"format": ["cjs", "esm", "umd"],并确保package.jsonunpkg字段指向index.umd.js

5. 常见问题与排查技巧实录

5.1 TypeScript 类型错误:90% 的问题源于路径别名失效

现象Cannot find module '@org/agent-skills-auth' or its corresponding type declarations.

排查流程

  1. 检查tsconfig.base.jsonpaths是否配置正确,且baseUrl.
  2. 运行tsc --traceResolution查看 TS 解析路径过程,确认是否尝试了node_modules/@org/agent-skills-auth
  3. 检查libs/agent-skills-auth/tsconfig.lib.json是否extends../../tsconfig.base.json
  4. 删除node_modules/.cachedist目录,重新nx build

根本原因:Nx 的tsconfig.base.json是根配置,子库的tsconfig.lib.json必须继承它才能识别路径别名。常见错误是手动创建tsconfig.lib.json时遗漏extends

5.2 Nx 构建失败:Cannot find module 'fs'类型缺失

现象nx build报错Cannot find name 'require'. Do you need to install type definitions for node?Cannot find module 'fs'

解决方案

  1. libs/agent-skills-auth/tsconfig.lib.jsoncompilerOptions.types中添加"node"
    "compilerOptions": { "types": ["node"] }
  2. 确保package.json中有@types/node作为 devDependency:
    npm install --save-dev @types/node

原理fspath等 Node.js 内置模块的类型定义由@types/node提供,TS 默认不加载,需显式声明。

5.3 semantic-release 发布失败:No commits foundInvalid version

现象 1semantic-release报错No commits found since last release

原因:Git 提交未推送到远程main分支,或本地分支名不是main

解决

  • 确保git push origin main已执行。
  • 检查.releasercbranches是否为["main"],若用master需同步修改。

现象 2semantic-release报错The new version (1.0.0) is invalid

原因package.jsonversion字段不是0.0.00.0.1

解决:Nx 生成的库默认version0.0.1,semantic-release 要求初始版本 ≤0.0.1。手动改为0.0.0即可。

5.4 Jest 测试失败:ReferenceError: require is not defined

现象:浏览器环境测试报错require is not defined

原因@nrwl/node:library生成的 Jest 配置默认针对 Node.js 环境,而浏览器环境需不同配置。

解决:为浏览器消费的库单独配置 Jest。在libs/agent-skills-auth/jest.config.ts中:

import { getJestProjects } from '@nrwl/jest'; import { pathsToModuleNameMapper } from 'ts-jest'; const { compilerOptions } = require('./tsconfig.lib.json'); export default { ...getJestProjects()[0], testEnvironment: 'jsdom', // 关键:改为 jsdom moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '<rootDir>/', }), };

5.5 agent-skills 库无法 Tree-shaking:打包体积过大

现象:Webpack 打包后,@org/agent-skills-auth的全部函数都被引入,即使只用了login()

原因index.ts中使用了export * from './lib/login',但login.ts内部又import * as utils from './utils',形成副作用。

解决方案

  • login.ts改为命名导出:export function login(...) {...}
  • index.ts改为显式导出:export { login } from './lib/login';
  • 禁止在login.tsimport * as xxx,改用import { func } from './xxx'

这样 Webpack 才能识别login是独立函数,支持按需加载。

6. 进阶能力:让 agent-skills 成为企业级基建核心

6.1 自动化文档生成:用 Typedoc 替代手写 README

手动维护README.md效率低下。我们接入 Typedoc:

npm install --save-dev typedoc

libs/agent-skills-auth/project.json中添加doc目标:

"doc": { "executor": "nx:run-commands", "options": { "commands": [ "typedoc --out docs --readme none --name 'Agent Skills Auth' --plugin typedoc-plugin-markdown --theme markdown libs/agent-skills-auth/src/index.ts" ] } }

运行nx doc agent-skills-auth自动生成 Markdown 文档,包含函数签名、JSDoc、参数说明。CI 中可自动提交到 GitHub Pages。

6.2 跨框架兼容:为 React/Vue/Angular 提供适配层

agent-skills 本身不依赖框架,但消费方常需 Hook/Composable/Service。我们在libs/agent-skills-auth下新增frameworks/目录:

libs/ agent-skills-auth/ frameworks/ react/ useLogin.ts // React Hook 封装 vue/ useLogin.ts // Vue Composable 封装 angular/ auth.service.ts // Angular Service 封装

这些适配层不包含业务逻辑,只做框架语法糖转换,同样受 semantic-release 管理,版本号与主库一致。

6.3 性能监控:为每个技能函数注入埋点

libs/agent-skills-auth/src/lib/login.ts中:

import { performance } from 'perf_hooks'; export async function login(credentials: { username: string; password: string }): Promise<User> { const start = performance.now(); try { const result = await doLogin(credentials); const duration = performance.now() - start; console.log(`[agent-skills-auth] login took ${duration.toFixed(2)}ms`); return result; } catch (e) { const duration = performance.now() - start; console.error(`[agent-skills-auth] login failed after ${duration.toFixed(2)}ms`, e); throw e; } }

生产环境可替换为window.performance或上报到监控平台。

我在实际项目中发现,这种细粒度埋点让性能问题定位时间从小时级降到分钟级。例如某次validateForm()函数耗时突增 200ms,通过日志快速定位到是正则表达式回溯导致,优化后恢复。

最后分享一个小技巧:在libs/agent-skills-auth/project.jsonbuild.options中添加"generatePackageJson": true,Nx 会自动生成package.json,省去手动维护。但要注意:publishConfig.registry字段需在.releaserc中配置,而非package.json,否则私有 registry 会失效。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 13:30:37

IEC104规约报文解析:APCI/ASDU结构、Wireshark抓包与故障排查

简介&#xff1a;在电力远动通信系统中&#xff0c;规约报文是设备间数据传输的载体&#xff0c;工程师常需通过抓包定位异常。IEC104规约作为运行于TCP之上的应用层协议&#xff0c;其报文由APCI和ASDU构成&#xff1a;APCI负责会话控制与序号管理&#xff0c;ASDU承载遥测、遥…

作者头像 李华
网站建设 2026/9/17 13:28:12

Excel表格秒变LaTeX代码:excel2latex插件安装配置与使用全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 13:27:50

告别PPT导出模糊,高清无损图片导出方法全解析

说实话&#xff0c;用 PPT 画图这事儿&#xff0c;入坑之后是真的香——论文配图、教程截图、公众号头图、甚至临时拼个海报&#xff0c;我都拿它搞定。但几乎每个人第一次把 PPT 里的内容导出成图片时&#xff0c;都会被默认那张“糊图”气到&#xff1a;屏幕上明明挺锐利&…

作者头像 李华
网站建设 2026/9/17 13:27:20

图书管理系统课程设计全解析:软工流程与SQL实现

简介&#xff1a;《图书管理系统&#xff08;软件工程课程设计报告&#xff09;》是一份面向软件工程专业学生与课程设计团队的完整项目文档&#xff0c;以XX学院09信计开发小组的图书管理系统项目为实例&#xff0c;系统说明了可行性研究、项目开发计划、需求分析、总体设计等…

作者头像 李华
网站建设 2026/9/17 13:26:00

GitHub入门实战:从本地项目上传到日常同步的完整指南

1. 先弄明白GitHub和Git&#xff0c;再开始动手1.1 一句话讲清Git和GitHub的关系很多新手会把Git和GitHub当成一回事&#xff0c;其实它们是两样完全不同的东西。Git是一个在你电脑本地运行的版本管理工具&#xff0c;负责记录代码每一次的改动&#xff0c;相当于一个细到文件行…

作者头像 李华