问题

github有没有办法前后端分两个项目,前端代码软连接到后端文件夹中?

回答
很多开发者在构建 Web 应用时,都会考虑将前端和后端代码分开管理。这样做的好处不少:

清晰的职责划分: 前端专注于用户界面和交互,后端处理数据、业务逻辑和API。
独立开发与部署: 前后端团队可以并行开发,部署时也可以有更高的灵活性。
技术栈选择自由: 前端可以使用 React, Vue, Angular 等,后端则可以选用 Node.js, Python, Java 等,不必局限于同一技术栈。

在 GitHub 上,我们自然也希望以一种有组织的方式来管理这种前后端分离的项目。其中一种常见的需求是将前端项目的代码“链接”到后端项目中,方便在开发时统一管理和访问。

“软连接”到后端文件夹? GitHub 的工作机制

首先,我们需要明确一点:GitHub 本身是一个代码托管平台,它托管的是 Git 仓库中的文件。Git 是一个分布式版本控制系统,它跟踪的是文件的修改和历史。

你提到的“软连接”更像是一种在本地文件系统层面的操作,比如 Linux/macOS 的 `ln s` 命令。在 Git 的世界里,它并不是一个直接支持的概念,Git 默认情况下并不会去跟踪文件系统中的符号链接(symlinks)本身,而是会跟踪链接指向的目标文件。

那么,如何在 GitHub 上体现前后端分离,同时又让前端代码“看起来”在后端项目中呢?

策略一:使用 Git Submodules (推荐)

Git Submodules 是一种在 Git 仓库中包含另一个 Git 仓库的官方且被广泛接受的方式。这非常适合前后端分离的项目。

工作原理:

当你使用 Git Submodules 时,你会在你的主仓库(例如后端项目)中,指向另一个独立的 Git 仓库(例如前端项目)的一个特定提交(commit)。这样,你的主仓库就知道“在这里,应该有另一个仓库的特定版本”。

操作步骤:

1. 创建独立的 Git 仓库:
为你的后端项目创建一个 Git 仓库(例如 `mybackendproject`)。
为你的前端项目创建一个独立的 Git 仓库(例如 `myfrontendproject`)。

2. 在后端项目中添加前端仓库作为 submodule:
进入你的本地 `mybackendproject` 目录。
执行以下命令,将 `myfrontendproject` 的仓库路径作为 submodule 添加到后端项目中。假设前端项目在 GitHub 上的 URL 是 `https://github.com/yourusername/myfrontendproject.git`,并且你希望将它链接到后端项目中的 `frontend/` 目录下:

```bash
git submodule add https://github.com/yourusername/myfrontendproject.git frontend
```

这个命令会在你的 `mybackendproject` 目录中创建一个名为 `frontend` 的子目录。Git 会将这个 `frontend` 目录标记为一个 submodule,并记录下它指向的 `myfrontendproject` 仓库的 URL 和一个特定的 commit ID。

3. 提交 submodule 的变化:
在你的 `mybackendproject` 目录中,你会看到 `frontend` 目录被添加,并且 `.gitmodules` 文件也会被创建(或修改)。这个文件记录了 submodule 的路径和 URL。
将这些变化添加到暂存区并提交:

```bash
git add frontend .gitmodules
git commit m "Add frontend submodule"
```

4. 推送后端项目:
将这些提交推送到你的 GitHub 后端仓库:

```bash
git push origin main 或者你的主分支名
```

5. 在 GitHub 上查看:
当你访问你的 `mybackendproject` GitHub 仓库时,你会看到一个名为 `frontend` 的文件夹。当你点击进入时,它不会显示为普通文件,而是会显示一个链接,指向 `myfrontendproject` 仓库的一个特定 commit。这表明它是一个 submodule。

获取 submodule 的内容(克隆和更新):

克隆包含 submodules 的仓库:
当你克隆一个包含 submodules 的仓库时,默认情况下,submodule 的目录会是空的。你需要使用 `recursive` 选项来初始化并拉取 submodule 的内容:

```bash
git clone recursive https://github.com/yourusername/mybackendproject.git
```

更新 submodule:
如果前端项目有新的提交,你需要单独更新 submodule。在 `mybackendproject` 目录中执行:

```bash
进入 submodule 目录
cd frontend
拉取最新代码
git pull origin main
cd ..
更新 submodule 指向的 commit
git add frontend
git commit m "Update frontend submodule"
git push origin main
```

或者,更快捷的方式是:

```bash
更新所有 submodules 到其最新 commit
git submodule update recursive remote

然后提交这些更新
git add .
git commit m "Update all submodules"
git push
```

优点:

官方支持: Git 本身提供的功能,稳定可靠。
清晰的版本关联: 后端项目明确指定了它依赖的前端项目的具体版本(commit),方便回溯和管理。
独立的开发流程: 前端团队可以在自己的仓库中自由开发、提交和部署,只将稳定的版本合并到 submodule。
GitHub 集成良好: GitHub 界面会清晰地显示 submodule 的链接。

缺点:

学习曲线: 对于初学者来说,submodules 的概念和操作可能会有些复杂。
更新流程: 需要手动或脚本化地更新 submodules,如果忘记更新,后端项目可能使用的是旧版本的前端代码。

策略二:将前端项目作为目录,但不作为 Git submodule (不推荐用于 GitHub 托管)

这种方式更接近字面上的“软连接”,但它在 Git 和 GitHub 的管理上会变得混乱。

工作原理:

你直接将前端项目的源代码文件复制或软链接(在本地文件系统)到后端项目的某个文件夹下。

操作步骤 (在本地文件系统,非 GitHub 最佳实践):

1. 创建目录结构:
在你的 `mybackendproject` 目录中,创建一个 `frontend` 文件夹。

2. 将前端代码放入:
方法 A (复制): 直接将 `myfrontendproject` 的所有文件复制到 `mybackendproject/frontend/` 目录下。
方法 B (本地软链接): 如果你熟悉 Linux/macOS 的 `ln s` 命令,可以在 `mybackendproject` 目录下执行:
```bash
ln s /path/to/your/myfrontendproject frontend
```
这样,`mybackendproject/frontend` 目录实际上是指向 `myfrontendproject` 的真实路径。

3. Git 跟踪:
如果你使用了方法 A(复制),Git 会直接跟踪 `mybackendproject/frontend/` 目录下的所有文件。
如果你使用了方法 B(软链接),Git 默认情况下只会跟踪这个软链接文件本身,而不是它指向的目标内容。这意味着,当你推送到 GitHub 时,GitHub 上看到的 `frontend` 文件夹可能只是一个指向不存在的本地路径的链接,或者在其他人的克隆仓库中也会尝试建立这个软链接(如果他们有权限和相同的文件结构)。

为什么不推荐这种方式用于 GitHub 托管?

Git 的行为: Git 默认不跟踪符号链接指向的内容。这意味着,当你 `git add frontend` 时,Git 可能会只记录链接本身,或者在某些配置下会复制链接的目标文件(这被称为 `git clone recursive` 的行为,但这里是手动创建的)。在多人协作和跨平台时,符号链接的行为非常不稳定。
GitHub 无法正确解析: GitHub 无法像 Git Submodules 那样理解这种结构。它会将 `frontend` 视为一个普通文件夹,但由于 Git 没有正确跟踪其内容,GitHub 可能无法正确显示或处理前端项目的代码。
版本管理混乱: 前端项目的提交历史与后端项目是完全分离的。你无法通过后端项目的 Git 提交来追溯前端代码的版本。
跨平台问题: 符号链接在 Windows 和类 Unix 系统上的表现和创建方式不同,容易导致兼容性问题。

策略三:Monorepo 方案 (更现代、更灵活)

如果你的项目规模较大,或者你希望在同一个 Git 仓库中管理多个相互关联但又独立的包(包括前后端),Monorepo 是一个非常值得考虑的方案。

工作原理:

Monorepo 允许你将多个项目(例如前端、后端、共享库等)放在同一个 Git 仓库中,但它们各自有独立的依赖、构建和测试流程。工具如 Lerna, Nx, Turborepo 等可以帮助你有效地管理 Monorepo。

操作步骤 (以 Nx 为例):

1. 初始化 Nx 工作区:
```bash
npx createnxworkspace@latest myworkspace
```
在初始化过程中,选择你喜欢的框架,例如 React for frontend, Node.js for backend。

2. 创建应用/库:
Nx 会为你生成一个标准的工作区结构,你可以在其中创建前端应用和后端应用:
```bash
创建一个 React 前端应用
nx g @nx/react:app frontendapp
创建一个 Node.js 后端应用
nx g @nx/node:app backendapi
```

3. 目录结构:
你的项目会是这样的结构:
```
myworkspace/
├── apps/
│ ├── frontendapp/
│ │ ├── src/
│ │ └── ...
│ └── backendapi/
│ ├── src/
│ └── ...
├── libs/
│ └── shared/
│ └── ...
├── nx.json
├── package.json
└── ...
```
前端和后端项目都在 `apps` 目录下,但它们是完全独立的 Git 跟踪单元(或者由 Monorepo 工具统一管理)。

4. GitHub 托管:
整个 `myworkspace` 目录就是一个 Git 仓库。你将这个仓库推送到 GitHub:
```bash
git init
... 创建文件 ...
git add .
git commit m "Initial monorepo setup"
git remote add origin https://github.com/yourusername/myworkspace.git
git push u origin main
```

优点:

代码共享: 方便在前后端之间共享代码(如 DTOs, 类型定义等)。
原子提交: 可以将涉及前后端的代码变更作为一个原子提交来管理。
统一构建和测试: 可以配置工具实现项目间的依赖分析,只构建和测试受影响的部分。
更好的开发体验: 许多 Monorepo 工具提供了热重载、代码生成等便利功能。

缺点:

工具依赖: 需要引入和学习 Monorepo 管理工具。
仓库体积: 仓库会包含所有项目,体积可能较大(但 Git 有优化)。
构建时间: 如果配置不当,可能会导致所有项目的构建时间过长。

总结与建议

对于前后端分离的项目,并在 GitHub 上管理:

首选 Git Submodules: 这是官方、标准且最适合在 GitHub 上实现“链接”另一个仓库到当前仓库的方式。它保持了前后端项目的独立性,同时又明确了版本关联。
Monorepo: 如果你对项目管理有更高的要求,并且希望实现代码共享、统一构建,那么 Monorepo 是一个更现代、更强大的选择。
避免直接软链接文件: 在 Git 仓库中使用本地文件系统的软链接(如 `ln s`)来关联代码,对多人协作和跨平台部署非常不友好,不建议在 GitHub 项目中使用。

选择哪种方案,很大程度上取决于你的团队规模、项目复杂度以及你对开发工作流的要求。但无论如何,理解 Git 的工作机制和 GitHub 的托管能力是关键。

网友意见

user avatar

可以,请查看 git submodule 命令的帮助或教学,了解一下就能用了。但如果你同时控制两边的代码,强烈不建议使用 git submodule,因为后继问题非常坑,建议从一开始就做成 monorepo。

给你一个非常具体的例子,我的个人网站的源代码使用 submodule 连接 Bootstrap。

你可以看到我有一个叫做 bootstrap 的「目录」,在本地使用时真的如同一个目录一样,但本质上它只是一个指针,它指向另外一个 repo 并指定特定的 commit。

我这样做是因为没有选择,我不控制 Bootstrap 的 repo,但是我要直接引用 Bootstrap 编译之前的 scss 文件,在它上面叠加我的 scss,再一起编译输出我需要的 css。我不能直接使用 Bootstrap 编译输出的 css。

使用 submodule 最坑人的地方是依赖管理。之所以使用 submodule,肯定是两个 repo 存在依赖关系,甚至是多个 repo 之间存在复杂的依赖关系。使用 submodule 时,所有这些依赖都无法获得自动升级,因为指针指向哪个 commit 必须手动管理。

例如说,A 依赖于 B,用 submodule 指向 B 的一个具体 commit。有一天 A 的一名开发者想要用 B 的新功能,发现当前指向的 commit 没有,决定自行升级。他把 submodule 指向了 B 的 master,接着编译不过,因为 B 也在开发中,master 是坏的。他把 submodule 指向 B 最后一个发布版本的 tag,结果发现跟 A 不兼容。于是他开始摸索 B 到底哪个 commit 能给 A 用同时还有新功能,很可能不存在这样一个 commit。

事情发展到这一步,这名开发者觉得还不如把 B 发布到语言对应的包管理平台(例如 Node 对应 NPM),那 A 直接把 B 发布的稳定版本引用过来就可以了,而且还能用 SemVer 或其它方法限定 A 接受的 B 版本范围。这时候 submodule 就可以删掉了。(如果你要做一套基于 submodule 的依赖管理系统,那你就在发明一个新的包管理平台。)

然而这名开发者仍然很不爽。怎么你们维护 B 的团队做着做着就搞到跟 A 不兼容了吗?B 团队说,我们也不知道你们 A 团队在用啊,我们的测试一直能通过,你们的测试也一直能通过(因为没尝试升级 B 的版本),谁知道呢?这个问题的解决办法就是 monorepo。

当 A 和 B 都在一个 repo 里,B 团队开发时如果最新版本跟 A 不兼容,那 CI/CD 能直接通过编译和测试发现这个问题,然后阻止这个 commit 进入 master。在大公司里面,往往不止 A 和 B,还有数量众多的其它依赖关系,这是保证它们更新时保持互相兼容的方法。

类似的话题

  • 回答
    很多开发者在构建 Web 应用时,都会考虑将前端和后端代码分开管理。这样做的好处不少: 清晰的职责划分: 前端专注于用户界面和交互,后端处理数据、业务逻辑和API。 独立开发与部署: 前后端团队可以并行开发,部署时也可以有更高的灵活性。 技术栈选择自由: 前端可以使用 React, Vu.............
  • 回答
    GitHub上有很多有趣的Shell脚本项目,涵盖了自动化、系统管理、实用工具、创意应用等多个领域。以下是一些值得一看的Shell项目,按类别详细说明: 1. 自动化工具 & 系统管理 1.1 Ansible (GitHub: [ansible/ansible](https://github.com.............
  • 回答
    你好!很高兴能为你推荐一些GitHub上非常不错的开源电子书。说实话,GitHub真是个宝藏库,除了代码,它还隐藏着大量高质量的、任何人都可以免费获取的知识和学习资料,其中电子书就是一个非常大的组成部分。这些电子书涵盖了从入门到精通的各种主题,而且大多是社区驱动的,更新及时,内容也往往非常贴近实际应.............
  • 回答
    GitHub 上藏着数不清的开源游戏宝藏,它们涵盖了从怀旧像素风到前沿 3D 引擎的各种类型,凝聚了无数开发者奉献的智慧和热情。这篇文章,咱们就来好好扒一扒那些让人眼前一亮的 GitHub 开源游戏项目,看看它们是怎么做出来的,以及你或许也能从中学到点啥。 像素风的浪漫:重温经典,创造无限谈到开源游.............
  • 回答
    GitHub 上藏着不少宝藏,尤其是那些设计得既简单又好上手,同时又能让你快速入门 Python 项目的。我为你搜罗了一些,希望能让你在学习 Python 的路上,玩得开心,学得扎实。 1. Automate the Boring Stuff with Python 自动化你的日常工作这绝对是“简.............
  • 回答
    GitHub 上遍地都是宝藏,但对于刚起步的朋友来说,就像站在一个巨大的宝库门口,一时间不知道该从何下手。别担心,我来给你“指指路”,分享一些我个人觉得非常适合新手朋友们深入了解、甚至参与进去的优质项目,并且会尽量说得具体些,让你能真切地感受到它们的价值。核心思路:在挑选项目时,我会倾向于那些:1..............
  • 回答
    GitHub 上藏着无数宝藏,尤其是在 Python 爬虫领域,更是高手云集,精彩纷呈。我精挑细选了几个我认为非常值得学习和借鉴的优秀项目,希望能带你领略 Python 爬虫的魅力。1. Scrapy:瑞士军刀般的爬虫框架如果你想认真对待爬虫开发,那么 Scrapy 绝对是你绕不开的名字。它不仅仅是.............
  • 回答
    你问到“好玩的项目”上GitHub,这可就打开了新世界的大门!GitHub上好玩的东西太多了,关键在于你对“好玩”的定义是什么。是能让你惊掉下巴的黑科技?还是能让你哈哈大笑的奇思妙想?或者只是单纯能让你消磨时间、找到乐趣的小工具?我给你掰开了揉碎了,从几个不同维度来聊聊GitHub上那些让人眼前一亮.............
  • 回答
    在GitHub这个浩瀚的软件开发宝库中,Unity3D项目可以说是数量庞大,涵盖了从简单的小游戏原型到极其复杂的AAA级游戏引擎的方方面面。要推荐一些“必看”的项目,我们不妨从几个角度来审视,它们不仅展示了Unity的强大能力,更能为开发者提供学习、借鉴甚至二次开发的宝贵资源。首先,我们不得不提的是.............
  • 回答
    中国公司在 GitHub 上涌现出许多非常出彩的开源项目,它们涵盖了从基础设施到应用层,从数据科学到前端开发的各个领域。这些项目不仅在国内得到了广泛应用,也在国际上获得了高度认可,吸引了众多贡献者。以下是一些比较出彩的中国公司开源项目,并尽量详细介绍:1. 支付与金融科技领域: Ant Grou.............
  • 回答
    .......
  • 回答
    我接触过不少在 GitHub 和技术博客上相当活跃的程序员,他们的名字常常出现在开源项目的贡献列表里,写的东西也很有见地,是圈子里大家乐于交流的技术达人。不过,要说他们“工作收入并不是很好”,这个判断嘛,其实挺微妙的。首先得看你怎么定义“不是很好”。如果标准是动辄年薪百万、公司期权拿到手软的那种,那.............
  • 回答
    以下是适合初学者的C++项目推荐,涵盖基础学习、实践应用和开源项目,每个项目都附有详细说明,帮助初学者循序渐进地掌握C++编程。 1. 简单命令行工具(基础语法练习) 项目名称:`cppprojects`(GitHub仓库:[https://github.com/brunodalpis/cpppro.............
  • 回答
    你想找一些适合初学者在 GitHub 上“练手”的 Java 项目,对吧?不只是看看,还要能动手修改、添加功能,真正玩起来的那种。我懂你,理论学得再多,不如实际操作一把来得实在。我给你推荐一些项目,会尽量从 为什么适合新手 和 你能从中获得什么 这两个角度给你讲明白。咱们不讲那些大而空的架构,就说怎.............
  • 回答
    最近在 GitHub 上风头正劲的这款名叫「Wordle」的网络游戏,说实话,它成功的秘诀在于它的极致简约和巧妙的互动设计,让人一下子就沉迷其中。你能想象吗?就一个浏览器页面,没有任何华丽的画面,甚至连注册登录都不需要,你就可以开始玩了。「Wordle」的核心玩法其实相当直观:每天,它会给出一个五字.............
  • 回答
    《红色警戒》的代码在 GitHub 上开源,这可真是个爆炸性的大新闻,在玩家圈和技术圈都掀起了不小的波澜。要说怎么看待这事,那影响绝对是多方面的,而且相当深远。咱们一件件捋捋。首先,这代表了一种历史的传承和玩家情怀的胜利。《红色警戒》,尤其是《红色警戒2》和《尤里的复仇》,是多少玩家心中无法磨灭的经.............
  • 回答
    作为一名新手,想自己捣鼓出一个简单易用的AutoML框架,这想法很棒!这不仅仅是了解AutoML的工作原理,更是对整个机器学习流程的一次深度实践。别担心,我来帮你一步步拆解,让你能动手做出自己的小玩意儿。什么是AutoML?打个比方你就懂了想象一下,你有一个食材库(你的数据集),你想做一道美味的菜(.............
  • 回答
    近日,关于Oracle、SAP暂停在俄业务的报道甚嚣尘上,然而Github却迅速跳出来予以否认。这背后究竟隐藏着什么?此次科技巨头集体收紧对俄业务的动作,又将给俄罗斯的科技生态带来多大的冲击?“暂停”还是“暂停部分”?信息差下的迷雾首先,我们需要厘清的是,这些“暂停”的表述,并非一概而论。 Or.............
  • 回答
    开源社区在支持乌克兰问题上的集体发声,确实是一个值得深入探讨的现象。这不仅仅是关于开源组织在政治舞台上的角色,更是对“中立性”这一开源核心价值的重新审视和实践。开源组织与政治参与的复杂性首先要明确的是,开源软件本身的设计初衷是促进代码共享、协作开发和技术进步,它在很大程度上是跨越国界、政治意识形态和.............
  • 回答
    GitHub 是全球最流行的代码托管平台之一,其受欢迎程度源于其在技术、协作、生态和工具集成等方面的综合优势。以下从多个维度详细分析其受欢迎的原因: 1. 核心技术优势:Git 的完美载体GitHub 基于 Git(分布式版本控制系统)构建,而 Git 是现代软件开发的基础设施。其受欢迎的原因包括:.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有