Plugin 的生命周期有五步:装、启用、升级、禁用、卸载。最容易出问题的不是装,是升级和卸载。 实测升级那条链:状态没变,变的只是版本——所以它最容易被当成没事发生,而它动的是全部文件。
上一节看静态结构,这一节看它被装进来之后会发生什么。 这一节的重点不是「怎么装」,是「装之前该问什么」——因为卸载不可逆。
一、五步各留下什么
安装:文件落到插件目录,记下版本。 启用:组件被加载,命令和技能开始出现在清单里。 升级:文件被替换,配置保留,状态不变——只变版本。
禁用:组件不加载,但文件还在。 卸载:文件被删除,数据未必。 五步里只有卸载不可逆,所以装之前的那个问题最要紧:它会把东西放哪儿?
二、升级那一步最容易出事
文件被替换、配置保留,这是正常情况。但有两个变数。 第一,新版本删掉了一个组件,你还在用它——表现为「命令突然不存在了」。 第二,新版本改了组件的行为,参数含义变了——表现是「还能跑,但结果不对」。
两种都不报错。所以升级要能回滚,回滚的前提是有版本号。 这就是 9.2 节那个 version 字段的真正用处:不是给发布流程看的,是给「出事那天」看的。
三、卸载那一步最容易后悔
文件被删除,但数据未必。有的实现连数据一起删,有的留下。 所以「我的配置放在包目录里」是危险的:卸载就没了。 正确做法是把配置放在包外面(比如项目里的配置文件),包只放代码和声明。
这一条和 6.4 节那个「带密钥的放项目本地」是同一个思路:状态和代码分开。
四、真跑:升级出问题怎么退回去
演示里四行:升到新版本、发现少了一个命令、回滚到旧版本、没有版本号的那种包。 前三行能走通,全靠「知道之前是哪个版本」。 最后一行是重点:没有版本号的包,出问题只能整个删掉重装,而重装回来还是那一版。
所以版本号不是形式主义,它是「退路」这件事的具体实现。
五、三个来源该怎么选
官方市场:装起来最省事,但不一定有你团队要的。 私有市场:内部审核过,代价是要有人维护(9.6 节)。 本地目录:开发时改一行就看得到效果,但不适合分发给别人。
顺序通常是:本地目录试、稳定后进私有市场、别人装走用官方源。 开发阶段用本地目录这一点很实用——它省掉了「打包、安装、再看」这一整圈。
六、动手 Demo:安装、升级、禁用、卸载,每一步留下什么
Plugin 的生命周期有五步。最容易出问题的不是安装,是升级和卸载。 这里把五步的状态变化摆出来,再看升级出问题怎么退回去。
STEPS = [(u"安装", u"未安装", u"已安装", u"文件落到插件目录,版本 0.3.1"),
(u"升级", u"启用中", u"启用中", u"文件被替换成 0.4.0,配置保留"),
(u"卸载", u"已禁用", u"未安装", u"文件被删除,数据未必")]
实跑输出:
--------------------------------------------------------------------
安装、升级、禁用、卸载,每一步留下什么
--------------------------------------------------------------------
Plugin 的生命周期有五步。最容易出问题的不是安装,是升级和卸载——它们会动到已有状态。
所以装之前先问一句:它会把东西放哪儿?卸载的时候会不会删掉我的配置?
① 五步各留下什么
--------------------------------------------------------------------
| 这一步 | 之前 | 之后 | 留下什么 |
|---|---|---|---|
| 安装 | 未安装 | 已安装 | 文件落到插件目录,版本 0.3.1 |
| 启用 | 已安装 | 启用中 | 组件被加载 |
| 升级 | 启用中 | 启用中 | 文件被替换成 0.4.0,配置保留 |
| 禁用 | 启用中 | 已禁用 | 组件不加载,文件还在 |
| 卸载 | 已禁用 | 未安装 | 文件被删除,数据未必 |
② 升级那一步最容易出事
--------------------------------------------------------------------
文件被替换,配置保留——这是正常情况。但有两个变数:
第一,新版本删掉了一个组件,你还在用它。表现为「命令突然不存在了」。
第二,新版本改了组件的行为,参数含义变了。表现是「还能跑,但结果不对」。
两种都不报错。所以升级要能回滚,回滚的前提是有版本号——这就是 9.2 节那个字段的用处。
③ 卸载那一步最容易后悔
--------------------------------------------------------------------
文件被删除,但数据未必。有的实现连数据一起删,有的留下。
所以「我的配置放在包目录里」是危险的:卸载就没了。
正确做法是把配置放在包外面(比如项目里的配置文件),包只放代码和声明。
这一条和 6.4 节那个「带密钥的放项目本地」是同一个思路:状态和代码分开。
④ 真跑:升级出问题,怎么退回去
--------------------------------------------------------------------
| 这一步 | 版本 | 配置 | 状态 |
|---|---|---|---|
| 升到 0.4.0 | 0.4.0 | 在 | 正常 |
| 发现少了一个命令 | 0.4.0 | 在 | 不可用 |
| 回滚到 0.3.1 | 0.3.1 | 在 | 恢复 |
| 没有版本号的包 | 说不清 | 在 | 没法回滚 |
前三行能走通,全靠「知道之前是哪个版本」。
最后一行是重点:没有版本号的包,出问题只能整个删掉重装,而重装回来还是那一版。
所以 9.2 节那个 version 字段,不是给发布流程看的,是给「出事那天」看的。
五个动作构成一条链:装、用、升、停、卸。每一步都能往回走,除了卸载。
「除了卸载」这一条,就是为什么装之前的那个问题最要紧。
⑤ 三个来源该怎么选
--------------------------------------------------------------------
| 来源 | 好处 | 代价 |
|---|---|---|
| 官方市场 | 装起来最省事 | 不一定有你团队要的 |
| 私有市场 | 内部审核过 | 要有人维护 |
| 本地目录 | 开发时改一行就看得到 | 不适合分发给别人 |
开发阶段用本地目录,稳定之后进私有市场——这个顺序和 9.6 节是一致的。
! 五步的命名各版本可能略有差异,这里讲的是「每一步会动到什么东西」。
①五步:装、启用、升级、禁用、卸载。 「升级」那一行状态没变,只变版本,所以它最容易被当成没事发生——而它动的是全部文件。 ②升级出事的两种方式:新版本删了一个组件(命令突然不存在)、改了组件行为(还能跑但结果不对)。 两种都不报错。 ③回滚全靠版本号。没有版本号的包,出问题只能整个删掉重装,而重装回来还是那一版。 ④卸载不可逆:文件被删,数据未必。 所以配置别放在包目录里——状态和代码要分开,这和「带密钥的放项目本地」是同一个思路。
30 秒实验
- 给「升级」加一种情况:新版本删了一个你正在用的组件,重跑一遍。这条链还能走通吗? 需要做什么才能走通?
- 把配置从包目录挪到项目目录,重跑一遍。卸载那一步的结果变了吗?
- 三个来源各用一个场景套一下:本地试、团队共用、给别人装。顺序能反过来吗?
常见误区
- 升级不写版本号。出问题没法回滚,只能删了重装。
- 把配置放在包目录里。卸载时可能被一起删掉。
- 以为升级只是换文件。它还可能删组件、改行为,两种都不报错。
- 开发阶段就打包安装。改一行要重走一遍装,效率极低。
- 不看来源就装。第三方的包没人审过,权限却是你替它要的。
自测三问(点开对答案)
1. 生命周期的五步是什么? —— 装、启用、升级、禁用、卸载。只有卸载不可逆。 2. 为什么说升级最容易出事? —— 因为它状态不变、只变版本,容易被当成没事发生;而它可能删组件、改行为,且不报错。 3. 配置为什么不该放在包目录里? —— 因为卸载会删文件。配置放包外面,状态和代码分开才安全。装进来之后有个新问题:两个包都有同名的东西,叫它的时候叫到谁。
- ☐ (本篇完,下一篇 9.4 命名空间:多 Plugin 共存)
相关笔记
- Plugin 的物理结构:清单里那个 version 字段
- 命名空间:同名时谁赢
- Claude Code 橙皮书 · 索引
- 🐎 Claude Code 实战 · 索引