ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

软件说“no longer”怎么办?弃用警告的背后与应对

软件说“no longer”怎么办?弃用警告的背后与应对 谁还没在更新依赖后被一行 “no longer” 开头的警告砸过脸。我最近就接连撞上了好几回先是pnpm dev的时候蹦出来一条the pnpm field in package.json is no longer read by pnpm后面又看到同事群里有人贴 PHP 报错directive track_errors is no longer available还有人吐槽 Windows 上某个 TP-Link 管理工具提示路径不允许超过 260 个字符。这些报错表面上是八竿子打不着的几个软件但骨子里都在说同一件事技术世界里的“LONGER”是最贵的四个字母。它不一定是“更长久”更多时候是“不再继续支持你熟悉的那个老用法”。这篇东西我想好好聊一聊“no longer”现象为什么软件总爱说“不再支持”、这些消息背后到底意味着什么以及作为一个普通开发者/运维/轻度用户遇到这类提示时该怎么稳住心态、找出路、把损失控制在最小。内容会结合前阵子热传的几个真实报错场景来拆适合正在经历版本升级阵痛、好奇“官方为什么要这么干”的各位。别急这些坑我都替你踩过一遍了。1. “No Longer”不是bug是软件活着的证据先说个可能有点反直觉的结论一个项目如果长期不产生任何“no longer”反而才让人担心。因为这意味着它可能已经停止演化或者团队连清理遗产代码的勇气都没有了。1.1 软件生命周期的自然规律任何软件项目从诞生那天起就进入了一个持续变化的过程。早期它可能很简陋功能少、坑多、接口设计得随意。后来用户多了、场景杂了作者就会慢慢调整设计把不合理的部分推翻、把繁复的部分简化。这时候就会出现一种尴尬的局面老用户习惯的用法跟新设计产生了冲突。为了不让老用户瞬间崩盘通常的做法是“先标记弃用再彻底移除”——而在这个过程里最容易看到的关键词就是deprecated、removed、no longer supported。我们平时看到的no longer read、no longer available、is no longer supported其实就是在说“这块逻辑已经进入死缓阶段现在正式执行了。”它写得很直白甚至有点冷酷但背后是一个软件想活下去的必然选择。打个比方这就像一座城市发展起来之后老城区那些单向两车道的路就得改造成双向四车道。原来靠着路边摆摊的老商户肯定不爽但如果不改整个城市的交通就瘫痪了。软件里的“弃用”就是这种市政工程短痛换来的是后续十年、二十年的扩展空间。1.2 从热搜词看技术弃用的几种典型形态我梳理了一下最近大家高频碰到的“no longer”相关提示大致能分成三类配置格式迁移型。比如pnpm那条警告本质上是 pnpm 团队把某些配置项从package.json里面的pnpm字段挪到了独立的配置文件里。你的项目里还留着老写法工具已经不再读取它于是给个警告算是提醒搬家。运行环境不支持型。比如 PHP 的track_errors指令在新版本里被移除属于语言本身演进导致旧配置失效。这类问题在升级 PHP 小版本时特别常见经常一个php.ini的老配置没删干净整个服务起不来或者日志里刷一大堆fatal error。服务端策略更新型。比如 Gemini 客户端提示this client is no longer supported核心通常是服务端更新了 API 协议或鉴权策略老客户端的握手方式已经不被承认。用户感觉是“突然不能用了”实际上服务方早就公告过端口的关闭时间。平台限制遗留型。比如 Windows 经典的 260 字符路径上限。虽然系统层面早就提供了长路径支持开关但很多工具软件自己没适配或者默认配置没打开导致碰到长路径就报“无法配置超过 260 字符的路径”。这种“no longer”不是官方说取消而是老平台限制跟现代文件结构产生了摩擦。把这几种类型放在一起看你会发现一个共同点每一次“no longer”背后都有一处“需要跟着变”的地方。可以是配置文件、可以是代码写法、可以是系统设置反正总有一个位置在提醒你“时代变了”。2. 逐个拆解最近刷屏的几条“LONGER”报错理论说多了容易飘还是直接看实际案例吧。我挑了四个典型场景逐个分析问题成因、解决路径和背后的设计逻辑这些都是我和身边同事实打实碰到过的。2.1 pnpm 不再读取 package.json 里的 pnpm 字段这个警告的原文是pnpm dev [warn] the pnpm field in package.json is no longer read by pnpm. the following keys were ignored: pnpm.overrides. see https://pnpm.io/settings for the new home of each setting.出现这个警告的典型场景是你在package.json里写了类似这样的一段配置{ name: my-app, pnpm: { overrides: { lodash: 4.17.21 } } }然后在旧版本的 pnpm 下一切正常。升级 pnpm 之后一跑pnpm dev控制台就开始念叨上面的警告。到底为什么因为 pnpm 团队从一开始就觉得package.json是属于 Node.js 生态的公共文件不应该承载太多 pnpm 私有配置。早期他们临时把配置塞在pnpm字段里属于“先跑起来再说”的过渡方案。后来 pnpm 逐渐壮大需要管理的配置项越来越多再看这个字段就觉得不对劲一是语义不够清晰二是跟其他工具解析package.json时容易产生歧义。于是他们在新版本里把配置迁移到了pnpm-workspace.yaml现代版本或.npmrc部分旧配置里pnpm字段成了历史遗留。如果没迁移pnpm 出于兼容性会给你警告但不会真的帮你读。怎么解决第一步打开package.json把pnpm字段里的内容挨个记下来。第二步看官方文档确认每个子配置项的新位置。以overrides为例在较新版本里它是放在pnpm-workspace.yaml中的packages: - apps/* - packages/* overrides: lodash: 4.17.21如果项目还没用工作空间可以建一个pnpm-workspace.yaml里面只写overrides相关的内容也是可以的。第三步删掉package.json里面的pnpm字段重新跑pnpm install再跑pnpm dev警告就会消失。这里有个小经验不要在警告出现之后只是“看着烦”而不处理。overrides是限制依赖版本的关键手段如果 pnpm 不再读取它意味着你可能在不知情的情况下安装了带漏洞的传递依赖版本。安全审计工具一旦扫出来那就是生产事故级别的问题。2.2 PHP 的 track_errors 指令被彻底移除再来看这条 PHP 相关的报错fatal error: directive track_errors is no longer available in php in Unknown on line 0看到fatal error别慌这个错误最常出现在 PHP 8.4 之后的环境里。官方在 PHP 8.0 的时候把track_errors标记为废弃到了 8.4 就直接把它从引擎里摘掉了。如果你的php.ini里还写着track_errors On或者直接在代码里用ini_set(track_errors, 1)那 PHP 会在启动阶段报 fatal error进程直接退出页面全白。为什么要移除track_errors简单说这个指令控制的是$php_errormsg变量是否可用。在老 PHP 时代这是一个捕获错误信息的便捷通道比如这样$result some_function(); if (!$result) { echo $php_errormsg; }但这种方式有很明显的问题$php_errormsg是全局性的多个函数在同一个请求里调用时变量会被不断覆盖根本分不清当前错误到底来自哪一行。而且现代 PHP 有了完善的Error和Exception体系配合try/catch能拿到堆栈、错误码、文件路径等完整信息再依赖track_errors这种全局变量模式就是自找麻烦。怎么解决如果你是在启动脚本里看到了这个 fatal error先检查php.ini里有没有track_errors相关配置有就删掉。如果代码里用了ini_set(track_errors, 1)或者$php_errormsg你需要把错误处理逻辑改掉。常见的改写思路是try { $result some_function(); } catch (Throwable $e) { error_log($e-getMessage()); // 在这里做你自己的错误处理 }如果依赖的是老代码里那种“函数返回 false 但不抛异常”的模式建议排查一下第三方库版本换用支持新 PHP 版本的实现。还有一个容易忽略的点track_errors被移除后错误抑制符的行为在新版本里也会有些微妙变化。老代码如果大面积依赖加$php_errormsg的组合升级后要格外留意。社区里对的争论一直很大我个人建议新项目里彻底别用老项目也慢慢清理掉别把错误处理寄托在这种“眼不见为净”的写法上。2.3 Gemini 客户端提示不再被服务端支持这个场景对应的是failed to sign in. message: this client is no longer supported for gemini co...碰到这种提示的用户通常是在某个基于 Gemini 能力的客户端工具里直接登录结果某天突然发现登录失败提示“这个客户端不再被支持”。这事的本质是服务端策略更新。Gemini 服务在快速迭代过程中会持续调整协议版本、鉴权方式、API 端点。官方自己出的客户端或者经过审核的第三方客户端会跟着更新但如果你用的是某个很久没维护的封装库、老版本的桌面工具、或者网上某个“半成品”客户端它的认证握手方式和最新服务端已经不兼容了。站在服务商角度他们不可能无限期兼容所有历史版本客户端。每多支持一个旧协议就意味着多一份安全维护成本而且在 OAuth 这类鉴权体系升级时老客户端往往存在令牌存储不合规之类的隐患继续放行反而是风险。怎么解决首先是确认自己用的是哪个客户端去它的项目主页看看最近有没有更新。如果项目已经停更果断换官方工具或者维护活跃的社区替代品。其次是检查 API Key 或 OAuth 配置。有些所谓“客户端不支持”其实是服务商更新了密钥格式或鉴权端点你需要重新生成 Key或者修改环境变量、配置文件里的 API 地址。再一个思路是在代码里升级 SDK 版本别通过反向代理之类的间接方式访问服务这样更容易遇到协议不匹配的问题。保持 SDK 为最新版本是避免“客户端不再支持”的最稳手段。这里插一句题外话很多开发者在遇到服务端不再支持老客户端时第一反应是找人要旧版本 APK、旧版插件、或“破解版”。我特别不建议这么干因为旧客户端一旦被服务端放弃往往意味着安全漏洞不再修补数据风险反而更大。遇到“no longer supported”优先“向上看”而不是“往回退”。2.4 Windows 260 字符路径限制老平台限制与现代工程结构的冲突最后一个场景是 Windows 上的路径长度限制热搜里那条消息大概是window and is not configured tplink allow paths longer than 260 character这里面的tplink是指 TP-Link 的管理工具或驱动它弹出来的大意为当前 Windows 系统尚未配置成允许超过 260 字符的路径。在一些现代化工程里前端项目的node_modules深度动辄几百个字符Wi-Fi 网卡驱动的安装目录如果再深一点分分钟触发这个老古董限制。事情的源头是 Windows 的文件系统 API 长期以来有个路径上限MAX_PATH 260字符。这个限制从 DOS 时代就存在算下来已经是奶奶辈的遗产。Windows 10 1607 版本之后微软提供了注册表开关来放开限制但默认是关闭的原因是要确保老软件兼容性。怎么解决最常用的方案是在“注册表编辑器”里打开长路径支持计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem找到LongPathsEnabled把值从0改成1重启电脑后生效。也可以在“本地组策略编辑器”里改计算机配置 - 管理模板 - 系统 - 文件系统 - 启用 Win32 长路径选择“已启用”。不过要注意光系统支持还不够实际使用还得看软件自身是否用长路径 API 编译。有些老工具即使系统开了支持内部还是用旧的路径 API照样撞 260 字符的墙。遇到这种就只能从路径长度上想办法比如把项目放到靠近盘符根目录的位置C:\proj\my-app而不是C:\Users\你的用户名\Documents\Projects\web\frontend\my-app另外pnpm这类包管理器因为用了符号链接和内容寻址存储通常能绕开 node_modules 路径过深的问题这也是为什么很多前端在 Windows 上转用 pnpm 之后路径报错瞬间少了很多。3. 面对“不再支持”普通开发者的正确姿势前面拆了不少具体场景现在拉高一点视角聊聊我们遇到任何“no longer”类问题时的通用思路。毕竟工具千千万但应对框架是相通的。3.1 第一步分清“警告”“错误”“告知”三种级别看到no longer先别急着改代码看它是什么级别。警告型warn工具还能用但行为可能已经跟预期不一样了。比如 pnpm 那条配置不再被读取但项目还能dev只是某些覆盖规则失效。这种要尽快处理但不用火烧眉毛。错误型error / fatal error程序直接跑不起来。比如 PHP 的track_errors是 fatal error进程直接挂掉属于升级后必炸的雷必须处理完才能继续。告知型info / notice通常出现在日志里告诉你某个功能即将弃用、某个字段以后会变。很多项目为了照顾用户会提前两三个大版本发这种 notice给足缓冲期。应对的优先级自然是先处理错误型再造警告型最后是告知型。但千万别觉得告知型可以无限期拖等它变成错误型的时候周围的代码可能已经绕了十万八千里迁移成本会成倍增加。3.2 第二步确认版本锁定变更时间线任何一条“no longer”消息都应该先搞清楚一个问题从哪个版本开始不再支持的方法很简单拿到报错原文里的关键词去搜官方 changelog 或迁移指南。比如 pnpm 的报错里直接给了https://pnpm.io/settingsPHP 的报错可以去 php.net 查变更日志Gemini 客户端报错可以去官方公告页面看版本归档。锁定版本号之后你才能判断自己是“轻度滞后”还是“重度欠债”。轻度滞后通常只需要改个配置项重度欠债可能涉及依赖链的整体升级比如项目还在用 PHP 7.4想直接跳到 8.4那track_errors只是冰山一角后面还有一堆废弃函数等着你。这种时候不建议一步到位猛跨版本最好逐步升级7.4 - 8.0 - 8.1 - 8.2 - 8.3 - 8.4。每一个中间版本先处理弃用警告再继续往上走到达终点时会平滑很多。3.3 第三步做一次配置与依赖的全量盘点处理完眼前这条报错后强烈建议顺手做一次全量盘点看看还有没有其它“潜伏期”的弃用项。对于 Node.js 项目可以定期执行npm outdated或者用 pnpm 的话pnpm outdated对于 PHP 项目可以跑一下代码扫描工具看有没有用到废弃函数。网上有非常多成熟的静态分析工具挑一个顺手的挂到 CI 里每次提交自动扫一遍比人工检查靠谱得多。对于老旧的 Windows 配置可以检查一下系统里有没有其它低于现代标准的环境变量或注册表项。很多历史的坑都是同一个根源旧配置被遗忘在角落里直到某个新软件要求新行为时才爆出来。4. 实操心得我惯用的迁移套路与避坑清单唠了这么多最后分享一些我自己的操作习惯。这些经验都是从各种“no longer”的实战里攒出来的也不是什么机密但确实能让你少走不少弯路。4.1 升级前先备份备份完先看 diff不管遇到的是什么项目升级前第一件事永远是备份配置和锁文件。package-lock.json、yarn.lock、pnpm-lock.yaml、composer.lock、php.ini、.npmrc、pnpm-workspace.yaml这些全要纳入版本管理并且在升级前单独打一个 Tag。升级完如果出现no longer警告先去看官方迁移文档然后直接对比新旧配置文件的差异。很多时候报错信息里根本没有具体到配置项的对照反而是文档里的迁移表一清二楚照着改就完了。4.2 一条一条处理警告不要一次性全改如果有几十上百条deprecated警告千万别想着一次性全删干净。最理性的做法是先处理会影响安全性和依赖解析的比如overrides失效、锁文件里的漏洞版本再处理纯格式类的比如配置字段改名、路径格式变化最后处理代码风格类的比如$php_errormsg这种老写法的替换。每改完一类提交一次并跑一遍完整的测试。这样万一哪步改出了问题回滚起来非常容易定位不会像一锅乱炖那样排查到天亮。4.3 利用 CI 尽早发现“no longer”这条特别关键。本地环境往往带有历史的“温情脉脉”很多弃用警告根本不会在你机器上触发因为你的包版本、系统配置、运行时都跟生产环境不一样。但 CI 环境通常更干净能更好地暴露兼容性问题。建议在 CI 脚本里把这些步骤加进去使用最新稳定版的 Node / PHP / Python 运行测试开启依赖审计pnpm audit/npm audit/composer audit在 CI 日志里把所有deprecated、no longer、removed关键字提取出来单独成块展示方便一眼扫到问题。这样就算当下没时间处理至少能在代码评审时让当事人看到“你这 PR 引入了一个即将被移除的 API 调用。”4.4 真遇到不想升又必须用的情况怎么办偶尔也会遇到确实没法升级的尴尬局面老项目要维护但某个基础依赖已经no longer supported。这时候能做的事情大概有这几件锁定版本用 lock 文件锁死当前还能跑的版本别让包管理器悄悄升级到不兼容的版本隔离运行时比如老 PHP 项目用 Docker 单独跑一个老版本 PHP 镜像新代码继续用新版本跑两个服务之间通过 API 通信给迁移留出时间定期复查锁定版本不等于装死每隔几个月去翻一下上游有没有安全公告如果有高危漏洞且没有修复版那就要认真考虑重构了。我见过不少团队靠这套“隔离锁定”的状态撑了一两年最终平滑迁移到新架构。也有团队一直拖到服务被攻击才被迫重构那就相当被动了。总之可以躲一时但别想着躲一世。5. 几个真实的现场故事希望你不用再经历一遍讲完方法论来几个真实的“事故”现场都是我或者离我很近的人亲身碰到的篇幅不长但每个都值得记一笔。5.1 被忽略的 pnpm overrides 差点引入漏洞依赖有个同事某天跑pnpm dev看到上文的 warning觉得“反正能跑就不管了”。两周后安全扫描发现项目里某个传递依赖存在已知漏洞而他们明明在overrides里写了强制版本。查了半天才发现pnpm 升级后根本没读overrides所以强制版本一直没生效。漏洞就这么静悄悄地待了两周。好在那只是内部系统没有造成实际损失但这事儿给团队的教训是warning 不是给你看的装饰品不处理迟早变成事故。5.2 PHP 升级直接白屏半天排查后发现是 ini 缓存另一个故事来自一个老 Laravel 项目。运维升级了 PHP 8.4所有页面白屏php-fpm日志里只有一行track_errors ... no longer available。大家一开始到处找代码里的$php_errormsg翻遍了项目也没找到最后才想起来是php.ini里还留着一行远古配置。删掉后重启服务立刻恢复。这个小事故说明两件事一是老配置的遗迹可能藏在非常深的地方二是升级前真的要认真阅读官方废弃清单一条一条对照php.ini。5.3 Windows 路径超长装不上驱动也跑不了构建还有一个前端同事项目路径是C:\Users\Lenovo\Desktop\公司项目\官网重构\frontend\src\components\Marketing\Promotion\...光前半段就已经快 100 个字符再叠加上node_modules里的嵌套依赖路径直接在 Windows 上爆了 260 字符上限。pnpm install各种报错后来改了LongPathsEnabled、把项目挪到C:\work\web才算消停。这类事儿在 Windows 上做前端开发特别常见建议把长路径支持和“浅目录放代码”练成肌肉记忆能省下不少麻烦。6. 我的最后几点“反焦虑”心得技术世界里的“no longer”消息永远删不完。这不是谁的错也不是某个工具故意整你而是整个行业持续往前走的必然结果。我一直觉得判断一个开发者是否成熟的标志之一就是能不能心态平和地处理这类消息不无视、不恐慌、有条理地评估影响面。写代码这些年我自己也经历了好几次大型框架和语言的版本跨越。刚开始碰到deprecated会烦躁后来慢慢养成习惯每次看到这类提示先当它是“补课”的机会翻翻官方文档搞懂它为什么不再是旧样子反而收获很大。如果你刚碰到一条no longer之类的提示又恰好有点焦虑我的建议很简单复制报错里的关键句子搜索官方文档找到版本变更说明照着迁移指南一步步来。大部分“不再支持”的背后都有一篇写得很清楚的“现在应该这么用”等着你。最后再分享一个实用小工具习惯我会在项目根目录建一个UPGRADE.md每次升级完依赖就把踩过的坑、改过的配置、搜过的文档链接全部丢进去。等下次大版本升级的时候翻一翻这个文件很多问题根本不用重新踩一遍。这个方法听起来笨但长期坚持下来你会发现它是性价比最高的“知识管理”。就这样吧希望这篇关于“LONGER”的碎碎念能帮你在下一次接到no longer炸弹时多一点从容。说到底软件世界的“不再支持”并不是终点它只是提醒我们该往前走了。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进