周下载60w,但是作者删库!我从本地 pub 缓存里把它救出来,顺手备份到了自己的 GitHub

经过

今天在社区闲逛时,顺手看了一眼群里,说 get作者删库跑路了!我最初保持怀疑的态度,打开pub地址还能打开,

我看到时心里想:(这库的周下载逼近60w,收获了15.5k的star,而且getx是flutter四大状态管理仓库之一,时至今日,还有很多很多用户,我自己做项目,也在拿getx以及provierriverpodbloc做技术选型,横向对比...)

跑路了相当于vue生态中的vuexpinia跑路,太BT了...

当我再打开github,迎接我的就是

我心中大喊不妙,这种时候最怕的不是"今天能不能跑",而是过一阵子你换电脑、CI 重装、同事新拉项目的时候,大家突然开始补依赖、找源码、翻缓存,最后一圈人全卡住。

我这边的处理方式很简单:既然本地还能跑,那就先把本机已经缓存下来的完整包捞出来,备份到自己的 GitHub,至少后面有个稳定来源。

我已经把这份 get 4.7.3 传到了这里:

https://github.com/xinqingaa/get-4.7.3

如果你们团队里有人懒得自己再走一遍"翻缓存、复制目录、初始化 Git、上传仓库"这套流程,其实可以直接用我这个远程地址,先把项目跑起来再说。

先说结论

这里有个点得先说清楚:

GitHub 仓库 404,不等于 pub.dev 上的 hosted 包马上就拉不下来了。

只要 pub.dev 上这个版本还在,你项目里原来写的:

yaml 复制代码
get: ^4.6.6

很多时候依然是可以正常 flutter pub get 的。

所以我这次做这件事,不是因为"今天已经彻底装不上了",而是因为源码仓库、历史 issue、后续修补、团队兜底这些事情,一下子都变得不确定了。

说白了,我不是在抢救一个已经完全消失的包,我是在给未来留后路。

这次我主要确认了几件事:

  1. 项目里虽然写的是 get: ^4.6.6,但我本机实际锁定到的是 4.7.3
  2. 本地 pub 缓存里确实还有完整源码,路径在 ~/.pub-cache/hosted/pub.dev/get-4.7.3
  3. flutter clean 不会把全局的 pub 缓存删掉。
  4. 真正决定后面依赖从哪里拉的,不是 flutter clean,而是 pubspec.yaml 里到底写的是 hosted 依赖还是 git 依赖。
  5. 真正能证明"依赖来源切换成功"的,不是口头说改了配置,而是 pubspec.lock 里的 source 会从 hosted 变成 git

这个区别其实挺关键的。

因为很多人看到项目出问题,第一反应就是先 flutter clean,但它干的事情和"依赖从哪里下载"其实不是一回事。

pub 缓存到底是个什么东西

Flutter 项目里只要你执行过 flutter pub get,依赖一般都会被下载到本机的 pub 缓存目录里。

macOS 下常见路径就是:

bash 复制代码
~/.pub-cache

像这种从 pub.dev 拉下来的包,通常会放在:

bash 复制代码
~/.pub-cache/hosted/pub.dev/

比如我这次找到的就是:

bash 复制代码
/Users/lrq/.pub-cache/hosted/pub.dev/get-4.7.3

这个目录里不是一个"壳子",而是完整包内容,里面能看到:

  • lib
  • test
  • example
  • documentation
  • pubspec.yaml
  • LICENSE
  • README.md

也就是说,只要你本机缓存还在,很多时候就还有机会把包完整救出来。

我这次为什么还能把 get 捞出来

因为我的项目之前已经跑过,这个包已经被下载到本地了。

哪怕现在原作者仓库不稳定,或者你就是单纯不想继续依赖外部不确定因素,只要本机缓存里还留着这份代码,就还能复制出来自己维护。

我这边最后确认到的版本不是 4.6.6,而是 4.7.3

这个也很正常。

因为 pubspec.yaml 里写的:

yaml 复制代码
get: ^4.6.6

这表示允许拿 4.x 范围内兼容的更新版本。只要锁文件已经解析到了 4.7.3,项目实际跑起来用的就是 4.7.3

所以这次我没有死磕 4.6.6,而是直接把本机正在用的 4.7.3 备份走了。

我是怎么备份到 GitHub 的

做法其实不复杂。

第一步,不要直接在 ~/.pub-cache 里改东西。这个目录本质上还是缓存目录,不适合拿来当你自己的长期仓库。

我先把它复制到一个自己维护的位置,比如:

bash 复制代码
mkdir -p /Users/lrq/work/vendor
cp -R /Users/lrq/.pub-cache/hosted/pub.dev/get-4.7.3 /Users/lrq/work/vendor/get-4.7.3

第二步,在复制出来的新目录里初始化 Git:

bash 复制代码
cd /Users/lrq/work/vendor/get-4.7.3
git init
git checkout -b main
git add .
git commit -m "chore: import get 4.7.3 from local pub cache"

第三步,推到自己的 GitHub:

bash 复制代码
git remote add origin https://github.com/xinqingaa/get-4.7.3.git
git push -u origin main

这样做完之后,这个包就不只是"还躺在我电脑缓存里",而是已经有了一个我自己能控制的远程仓库。

如果大家都懒得操作,直接用我的远程地址也行

这个是最省事的办法。

如果你们现在只是想先把项目跑起来,不想每个人都再自己去翻 pub cache、复制源码、传一份仓库,那可以直接把依赖切到我这个地址:

https://github.com/xinqingaa/get-4.7.3

pubspec.yaml 可以这么写:

yaml 复制代码
dependencies:
  get:
    git:
      url: https://github.com/xinqingaa/get-4.7.3.git
      ref: main

如果你们希望再稳一点,不想后面有人往 main 推了东西影响现有项目,那就别写 main,直接写具体提交号:

yaml 复制代码
dependencies:
  get:
    git:
      url: https://github.com/xinqingaa/get-4.7.3.git
      ref: 具体commit_sha

这个方式更适合线上项目或者多人协作。

因为一旦写死 commit,后面就算仓库继续更新,你当前项目也不会跟着乱动。

这里顺便说清楚:flutter clean 到底是干嘛的

很多人会把 flutter clean 理解成"把依赖也一起清掉",其实不是。

flutter clean 的主要作用,是清理当前项目目录下面的构建产物和临时文件。

它更像是在对当前工程说一句:

"你之前编译留下来的东西先都别要了,等会儿我重新来一遍。"

一般它会影响这些东西:

  • build/
  • .dart_tool/
  • 一些 Flutter 构建过程中生成的中间文件
  • 平台侧部分临时产物

但有一点一定要注意:

flutter clean 默认不会删除全局的 ~/.pub-cache

也就是说,你执行完 flutter clean 之后:

  • 项目本地的构建状态会被清掉
  • 但你之前下载过的依赖缓存,通常还在

所以它不会直接把我刚才说的 get-4.7.3 这个缓存目录删掉。

那现在执行 flutter clean,具体会发生什么

如果你当前项目还是正常状态,这时候执行:

bash 复制代码
flutter clean

你大概率会看到下面这种结果:

  1. 当前项目下的 build 目录被清掉。
  2. .dart_tool 下面很多重新生成用的文件被清掉。
  3. 下一次你再跑项目,Flutter 会重新做一轮初始化和构建。

但是:

bash 复制代码
~/.pub-cache/hosted/pub.dev/get-4.7.3

这个目录通常还在。

所以从"救包"这个角度说,flutter clean 不是最危险的操作。

真正危险的是你把本地缓存手动删了,或者换了新机器,而你又没有自己的备份来源。

那现在执行 flutter pub get,又会发生什么

这个要分情况看。

情况一:你还没改依赖,项目里还是这样写

yaml 复制代码
get: ^4.6.6

flutter pub get 做的事情大概是:

  1. 读取 pubspec.yaml
  2. 结合 pubspec.lock 解析当前应该使用哪些版本
  3. 检查本机缓存里有没有现成依赖
  4. 如果缓存里有,就直接复用
  5. 如果本机没有,再去对应源拉取
  6. 重新生成 .dart_tool/package_config.json 之类的文件

如果你的 pubspec.lock 里已经锁的是 get 4.7.3,而且本地缓存也还在,那这一步通常不会有什么大动静,很多时候就是直接复用本地缓存。

换句话说,flutter clean 之后再 flutter pub get,项目大概率还是能恢复起来。

情况二:你已经把依赖改成 GitHub 仓库

比如你改成了:

yaml 复制代码
dependencies:
  get:
    git:
      url: https://github.com/xinqingaa/get-4.7.3.git
      ref: main

那这时候再执行:

bash 复制代码
flutter pub get

事情就变成另外一种逻辑了:

  1. pub 会识别到这是一个 git 依赖
  2. 它会去拉取这个 GitHub 仓库
  3. 然后把对应版本缓存到本机
  4. 更新锁文件和项目依赖映射
  5. 后面项目再编译时,就会基于这份新的依赖来源来跑

也就是说,从这一刻开始,项目依赖的就不再是"原来那个 hosted 包来源",而是你指定的这个 Git 仓库。

这也是为什么我说,真正决定依赖来源的是 pubspec.yaml,不是 flutter clean

所以 flutter clean + flutter pub get 连着执行时,应该怎么理解

这两个命令经常一起出现,但它们负责的事情完全不是一层。

你可以把它理解成:

  • flutter clean:把项目现场打扫干净
  • flutter pub get:按当前依赖配置重新把材料搬进来

如果你没改依赖来源,它就继续按原来的来源取。

如果你把 get 改成了你自己的 GitHub 仓库,它就会按新的地址重新拉。

所以这套动作本身不可怕,关键是你在执行之前,pubspec.yaml 到底写成了什么样。

我个人建议的处理方式

如果你只是想先保命,让项目先稳住,我建议直接做两件事:

  1. 先把能找到的完整包备份到自己的 GitHub。
  2. 再把项目依赖切到你自己能控制的地址。

这样做最大的好处是:

  • 新同事拉项目时不用到处找缓存
  • 换电脑时不用赌本机有没有旧依赖
  • CI 重建时也不会因为某个外部仓库状态异常而临时翻车

说白了,就是把"我电脑里刚好还有缓存"这件事,变成"团队里任何人都有稳定地址可用"。

如果你也想直接用我这份地址,可以抄这段

这个是最省心的版本:

yaml 复制代码
dependencies:
  get:
    git:
      url: https://github.com/xinqingaa/get-4.7.3.git
      ref: main

改完之后执行:

bash 复制代码
flutter clean
flutter pub get

一般会发生这些事:

  1. 当前项目构建缓存被清理。
  2. pub 按新的 Git 地址重新获取 get
  3. 锁文件会更新成新的依赖来源。
  4. 之后项目再跑,走的就是你指定的仓库了。

如果项目比较重要,建议把 ref: main 换成具体 commit。

GitHub 上的备注怎么补

这块我建议至少补两个地方,一个是仓库描述,一个是 README.md

1. 仓库描述

GitHub 仓库首页右侧 About 那里,点编辑,简单写一句就够了,比如:

Backup mirror of get 4.7.3 recovered from local pub cache.

这个主要是让别人点进来时一眼知道这仓库是干嘛的。

2. README

这个更重要,因为后面真正给别人复制依赖地址的时候,大家通常会先看 README。

可以直接写清楚三件事:

  1. 这个仓库是什么
  2. 它是从哪里恢复出来的
  3. 在 Flutter 项目里怎么引用

下面这段 README 你可以直接拿去用。


README 示例

md 复制代码
# get-4.7.3

这是从本地 `pub cache` 中恢复出来的 `get 4.7.3` 备份仓库,用来做内部依赖兜底。

原始恢复来源:

- `~/.pub-cache/hosted/pub.dev/get-4.7.3`

如果你想在 Flutter 项目里直接使用这个仓库,可以这样写:

```yaml
dependencies:
  get:
    git:
      url: https://github.com/xinqingaa/get-4.7.3.git
      ref: main

如果用于正式项目,建议把 ref 改成具体 commit SHA,避免后续分支内容变化影响构建结果。

yaml 复制代码
---

如果你已经在本地把 README 改好了,上传方式和平时推代码一样:

```bash
git add README.md
git commit -m "docs: add repository usage notes"
git push origin main

这就算把"备注"一起传上去了。

最后

这次事情也算给我提了个醒。

平时大家都觉得依赖装上了就完事了,但只要项目还在维护,关键依赖最好还是留一手。

尤其是那种项目里已经深度使用、短时间又很难替换掉的包,真碰到上游不稳定,最省时间的办法不是现场慌,而是趁本机缓存还在,赶紧先救一份出来。

如果你们团队现在也懒得自己再折腾一遍,那就直接先用我这份:

https://github.com/xinqingaa/get-4.7.3

先把项目稳住,比什么都重要。

往期文章回顾

Flutter 图片编辑器

Flutter 全链路监控 SDK

Flutter 全场景弹框

Flutter日历组件

日期选择器

相关推荐
PeterMap4 小时前
Vue组合式API响应式状态声明:ref与reactive实战解析
前端·vue.js
CodeGuru4 小时前
UniApp Vue3 生成海报并分享到朋友圈
前端
三原4 小时前
附源码:三原管理系统新增俩种常用布局
java·前端·vue.js
布局呆星4 小时前
Vue3 | 组件化开发---组件插槽与通信
前端·javascript·vue.js
DyLatte4 小时前
当我想把所有角色都做好时,就开始内耗了
前端·后端·程序员
a1117764 小时前
汽车展厅项目 开源项目 ThreeJS
前端·开源·html
SY.ZHOU4 小时前
移动端架构体系(五):终篇总结
flutter·ios·系统架构·安卓·鸿蒙
阳火锅5 小时前
Element / AntD 官方都没做好的功能,被这个开源小插件搞定了!
前端·vue.js·面试
大阳光男孩5 小时前
Uniapp+Vue3树形选择器
前端·javascript·uni-app