Bilibili-Evolved v1 设置迁移功能详解:从旧版设置导出到 v2 自动安装的完整流程与源码原理
2026/9/19 12:47:52 网站建设 项目流程

Bilibili-Evolved v1 设置迁移功能详解:从旧版设置导出到 v2 自动安装的完整流程与源码原理

【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved

Bilibili-Evolved v2 重构了组件库与设置体系,为了让老用户平滑过渡,官方在 v2 组件库中提供了「v1 设置迁移」功能:读取 v1(旧版脚本)导出的settings.json,根据其中开启的选项自动下载并安装 v2 中对应的功能组件。本文以 v1 设置迁移组件文档 为骨架,结合其 组件入口、核心迁移逻辑 与 官方迁移教程,讲解迁移机制的整体设计、功能/选项两级映射原理,以及从导出设置到完成迁移的完整实操步骤。

迁移功能定位与触发方式

「v1 设置迁移」是一个注册在组件库 utils 分类下的组件,组件名v1Migrate,显示名「v1 设置迁移」。从 组件入口 可以看到,它并不像普通功能那样直接注入页面,而是通过数据注册机制在设置面板的「关于」页注入一个动作按钮:

export const component = defineComponentMetadata({ name: 'v1Migrate', displayName: 'v1 设置迁移', tags: [componentsTags.utils], entry: () => { addData('settingsPanel.about.actions', (actions: AboutPageAction[]) => { actions.push({ icon: 'mdi-inbox-arrow-down-outline', name: 'importV1Settings', displayName: '导入 v1 设置', run: async () => { /* ... */ }, }) }) }, })

这里的关键机制是addData('settingsPanel.about.actions', ...):关于面板的动作列表本身由 src/components/settings-panel/sub-pages/about-page.ts 维护,内置了「导出设置」「导入设置」两个动作,任何组件/插件都可以通过数据钩子追加自己的动作。该文件中定义了动作的数据结构:

export interface AboutPageAction { icon: string iconSize?: number disabled?: boolean name: string displayName: string actionName?: string run: (event?: MouseEvent) => void | Promise<void> }

因此安装该组件并刷新页面后,设置面板左下角「关于」页就会多出「导入 v1 设置」按钮,点击后:

  1. 调用 file-picker 的pickFile({ accept: '*.json' })打开文件选择框,只接受 JSON 文件;
  2. 读取选中文件内容并JSON.parse解析为 v1 设置对象;
  3. 将解析结果交给runMigrate(settings)执行迁移;
  4. 解析或迁移过程中抛出的异常统一由logError记录。

核心迁移流程:runMigrate 的四个阶段

整个迁移逻辑集中在 migrate.ts 的 runMigrate 中,大致分为四个阶段:

阶段一:从 CDN 拉取在线功能索引

迁移开始时会显示Toast.info('下载功能列表中', '导入 v1 设置'),然后根据当前设置的 CDN 源与编译分支构造功能索引地址并下载:

const featuresDataUrl = `${cdnRootsgetGeneralSettings().cdnRoot}doc/features/features.json` const featuresDataText = await monkey({ url: featuresDataUrl }) const features: DocSourceItem[] = JSON.parse(featuresDataText)
  • cdnRoots定义在 src/core/cdn-types.ts,支持jsDelivr(已废弃)、AltCdnGitHub三种更新源;
  • features.json是仓库在线文档生成的组件/插件索引,其条目类型DocSourceItem定义在 registry/lib/docs/index.ts,包含typecomponentplugin)、namefullAbsolutePathowner等字段,用于后续定位功能的下载地址。

阶段二:构造迁移动作清单

migrate.ts的核心是一个包含约 200 多条动作的migrateActions: Executable[]数组,每条动作都基于下面几类工厂函数生成:

featureMap:功能级迁移(安装/跳过)

const featureMap = (oldKey: string, newKey: string, type: 'component' | 'plugin') => async () => { const oldValue = v1Settings[oldKey] if (!oldValue) { console.log(`跳过了未开启的选项 ${oldKey}`) return } if (!(newKey in map[type])) { // 从 features.json 找到新功能地址, 从 CDN 下载代码并安装 const code = await monkey({ url }) const { before, after } = getHook(`user${lodash.startCase(type)}s.add`, code, url) await before() const { metadata, message } = await installerMaptype await after(metadata) } else { console.log(`${newKey} 已经存在, 跳过安装`) } }

其行为是:只有当 v1 设置中oldKey为真值(该功能在 v1 中开启)时才处理;若 v2 中对应功能尚未安装,则从 CDN 下载代码,通过installComponent/installPlugin安装,并用 src/plugins/hook.ts 提供的getHook在执行安装前后触发userComponents.add/userPlugins.add钩子;若已安装则跳过。注释中magic: guiSettings is always enabled揭示了getPlugin的巧妙用法——利用 v1 的guiSettings选项恒为开启的特性,把「某个插件是否安装」绑定到该选项上。

optionMap:选项级迁移(写入 v2 配置)

const optionMap = (oldKey: string, newKey: string, mapFunction?: (value: any) => any) => () => { const oldValue = v1Settings[oldKey] const newValue = mapFunction?.(oldValue) ?? oldValue if (newValue !== undefined) { const [componentName, ...optionPath] = newKey.split('.') const { options } = getComponentSettings(componentName) lodash.set(options, optionPath, newValue) } }

它通过getComponentSettings(定义在 src/core/settings/helpers.ts)拿到目标组件当前的options,再用lodash.set按点分路径写入 v1 的旧值。newKey中的第一个点分段是组件名,其余是选项路径,例如'expandDanmakuList.ignoreMediaList'表示写入expandDanmakuList组件的ignoreMediaList选项。

stylesMap:自定义样式迁移

const stylesMap = () => () => { const { customStyles } = v1Settings customStyles .filter((style: any) => style.enabled) .forEach((style: any) => { settings.userStyles[style.name] = lodash.omit(style, 'enabled') as Required<UserStyle> }) }

只迁移 v1 中处于启用状态的用户自定义样式,写入 v2 的settings.userStyles,并剔除enabled字段。此外i18nMap目前被注释为none,说明 v1 的多语言/翻译相关设置(i18ni18nLanguage)暂未纳入迁移范围(对应的语言映射逻辑以注释形式保留在源码中)。

navbarItemMappings:导航栏项重命名映射

v1 与 v2 的导航栏项命名不同,迁移时通过一张映射表完成新旧命名转换:

const navbarItemMappings = { category: 'home', activities: 'feeds', bangumi: 'subscriptions', watchlaterList: 'watchlater', favoritesList: 'favorites', historyList: 'history', rankingLink: 'ranking', drawingLink: 'drawing', bangumiLink: 'bangumi', musicLink: 'music', matchLink: 'match', shopLink: 'shop', }

它被用于customNavbar.order(导航栏排序)与customNavbar.hidden(隐藏项)的迁移:旧键先映射为新键再删除旧键,同时显式删除mangaLink(v2 中已不存在的项)。

阶段三:顺序执行全部迁移动作

let completed = 0 toast.message = `导入中... (${completed}/${migrateActions.length})` for (const action of migrateActions) { try { await action() success++ } catch (error) { console.log(error) fail++ } finally { completed++ toast.message = `导入中... (${completed}/${migrateActions.length})` } }

每条动作被独立包裹在 try/catch 中,单条失败不会中断整体迁移,进度通过 Toast 实时刷新,最终汇总为导入完成. 成功 X 个, 失败 Y 个, 可在控制台查看详细日志.

阶段四:结果反馈

外层 catch 捕获整体性错误(如features.json下载失败),关闭 Toast 并用logError记录;各条动作的详细执行日志(跳过的选项、下载的功能、迁移的选项等)通过console.log输出,方便用户在控制台核对。

典型迁移映射一览

migrateActions中的映射涵盖了 v2 组件库的大部分分类,以下是几组有代表性的映射(完整清单见 migrate.ts):

v1 设置键(oldKey)v2 目标(newKey)类型说明
useDarkStyledarkMode组件深色模式开关
darkColorSchemedarkModeFollowSystem组件跟随系统深色模式
darkSchedule/darkScheduleStart/darkScheduleEnddarkModeSchedule/.range.start/.range.end组件 + 选项深色模式定时
hideBannerhideBanner组件隐藏横幅
expandDanmakuList/expandDanmakuListIgnoreMediaListexpandDanmakuList/.ignoreMediaList组件 + 选项展开弹幕列表
expandDescriptionfullVideoDescription组件展开视频简介
removeAds/showBlockedAdsTip/preserveEventBannerremovePromotions/.showPlaceholder/.preserveEventBanner组件 + 选项移除广告
touchVideoPlayertouchPlayerGestures+touchPlayerControl组件 ×2触屏操作拆分为两个组件
touchVideoPlayerDoubleTapControldoubleClickControl组件双击控制
customNavbar及一系列customNavbar*选项customNavbar组件内对应选项组件 + 选项自定义导航栏(含顺序/隐藏项重命名映射)
keymap/keymapPreset/customKeyBindingskeymap/.preset/.customKeyBindings组件 + 选项快捷键
downloadVideo/downloadVideoQuality/downloadVideoFormatdownloadVideo/.basicConfig.quality/.basicConfig.api组件 + 选项视频下载(格式映射见下)
downloadVideo.outputs.aria2/.idmgetPlugin(...)插件下载输出插件(借 guiSettings 恒真特性安装)
feedsFilter/feedsFilterPatterns/feedsFilterSideCardsfeedsFilter/.patterns/.sideCards组件 + 选项动态过滤
foregroundColorModesettingsPanel.textColor选项面板文字颜色
updateCdnsettingsPanel.cdnRoot选项更新源
customStylessettings.userStyles样式用户自定义样式

值得注意的是部分映射带有值转换函数,例如:

  • customControlBackgroundOpacity(字符串百分比)→playerControlBackground.opacity时先parseFloatMath.round(value * 100)
  • downloadVideoFormatflv'video.flv'dash→ 根据downloadVideoDashCodec是否以HEVC开头映射为'video.dash.hevc''video.dash.avc'
  • scriptLoadingMode会先去掉值中的(自动)后缀;
  • downloadPackageEmitMode会把 v1 的「分别下载」规范为 v2 的「单独下载」。

这些转换保证了新旧版本数据模型不一致时仍能正确落地。

完整迁移实操步骤

根据 官方迁移教程,从尚未安装 v2 脚本的状态开始,完整迁移共分四步:

  1. 导出 v1 设置:打开旧版脚本的设置面板,在搜索框旁边的菜单中选择「导出设置」,得到settings.json文件(与 v2 内置的「导出设置」动作同源,见 about-page.ts)。

  2. 安装 v2 脚本:删除 v1 脚本,参照 README 安装章节 安装 v2 脚本。

  3. 安装 v1 设置迁移组件:刷新 b 站页面使 v2 生效(设置面板默认仍位于页面左侧中央),打开设置 → 左下角「组件管理」→「在线仓库」,搜索v1 设置迁移并安装,安装完成后刷新页面。

  4. 开始迁移:再次打开设置面板,进入左下角「关于」,此时应出现「导入 v1 设置」按钮。点击后选择第一步导出的settings.json,脚本会依次下载 v1 中开启过的功能并安装。等待 Toast 显示「导入完成」后刷新页面,迁移即完成。

迁移后的检查与限制

  • 检查方式:迁移完成后可前往「组件管理」查看自动安装的组件清单,对照 v1 中开启的功能确认是否齐全;迁移明细(跳过/安装/迁移的项)在浏览器控制台中按console.log输出,可用「导入完成」后的提示配合控制台排查失败的条目。
  • 已知限制:从源码注释可以看到部分功能尚未纳入迁移或已被禁用,包括:defaultVideoQuality(默认清晰度)、feedsTranslatecommentsTranslaterestoreFloorsvolumeOverdrivesimpleHome/minimalHome等(对应行以注释形式保留);v1 的 i18n 多语言设置同样未迁移。这些功能需要用户在 v2 中手动重新配置或等待后续版本支持。

小结

「v1 设置迁移」是 Bilibili-Evolved v2 平滑升级体验的关键组件:对外,它以「关于」面板动作按钮的形式提供一键导入;对内,它通过featureMap(功能级自动安装)、optionMap(选项级值写入与转换)、stylesMap(自定义样式迁移)与导航栏项重命名映射,将 v1 的扁平设置键精确翻译为 v2 的组件体系。对于想要理解迁移机制或自行编写类似配置导入工具的开发者,migrate.ts 是一份完整且可直接参考的实现范例。

【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询