Bilibili-Evolved 的 SEO 页面重定向组件:源码解析与实现原理
2026/9/19 19:22:14 网站建设 项目流程
  • 前端
  • 音视频

【免费下载链接】Bilibili-Evolved

强大的哔哩哔哩增强脚本

项目地址:https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved
点击查看免费下载

Bilibili-Evolved 是一款面向哔哩哔哩网站的增强脚本,其功能以"组件(Component)"为基本单元组织。本篇文章聚焦于其中一个非常轻量却颇具代表性的组件——seoRedirect(SEO 页面重定向),它以极少的代码完成了一个明确的任务:当脚本运行在哔哩哔哩的 SEO 视频页面(https://www.bilibili.com/s/video/)时,自动跳转到对应的原视频页面。读完本文,你将掌握该组件的完整定义方式、URL 匹配与拦截机制、跳转实现细节,以及它在 Bilibili-Evolved 组件体系中的运行原理,并可据此举一反三,理解整个仓库中大量同类"轻量级入口组件"的编写范式。

一、功能背景:为什么需要 SEO 页面重定向

搜索引擎爬虫通常无法执行 JavaScript,因此哔哩哔哩为视频提供了专供搜索引擎收录的静态 SEO 页面,其 URL 结构为:

https://www.bilibili.com/s/video/BVxxxxxxxxxx

这类页面与正常的视频播放页(https://www.bilibili.com/video/BVxxxxxxxxxx)内容基本相同,但缺少完整播放器与交互功能。当真实用户(而非爬虫)通过搜索引擎结果进入这类页面时,体验会明显受限。Bilibili-Evolved 的seoRedirect组件正是为解决这一问题而生。

该组件的官方说明非常凝练,仅有一句(见 registry/lib/components/video/seo-redirect/index.md):

进入 SEO 视频页面时 (https://www.bilibili.com/s/video/) 自动跳转到原视频页面.

而它的完整实现同样精简,全部逻辑集中在一个组件元数据定义中(见 registry/lib/components/video/seo-redirect/index.ts):

import { defineComponentMetadata } from '@/components/define' export const component = defineComponentMetadata({ name: 'seoRedirect', displayName: 'SEO 页面重定向', entry: () => { window.location.assign(document.URL.replace('/s/', '/')) }, urlInclude: ['//www.bilibili.com/s/video/'], tags: [componentsTags.video], })

整个组件只有 11 行代码,却覆盖了"定义、匹配、执行"三个环节,下面逐层拆解。

二、组件元数据:defineComponentMetadata与入口函数

Bilibili-Evolved 中的每个组件都通过defineComponentMetadata工厂函数声明,该函数定义在 src/components/define.ts:

export const defineComponentMetadata = <O extends UnknownOptions = EmptyOptions>( m: ComponentMetadata<O>, ): ComponentMetadata<O> => m

它本质上是返回一个带类型约束的对象字面量,作用在于让组件声明获得完整的 TypeScript 类型检查。ComponentMetadata接口(见 src/components/types.ts)要求组件至少提供:

  • name:组件唯一名称,用于在设置面板、组件映射(componentsMap)中索引;
  • displayName:在设置界面中展示给用户的名称;
  • tags:组件分类标签,seoRedirect归类于componentsTags.video,即"视频"分类;
  • entry:主入口函数,组件被加载时执行一次(重新开启时不会再次运行,除非另行定义reload)。

除这些必填字段外,FunctionalMetadata(见 src/components/types.ts)还定义了urlIncludeurlExcludeinstantStyleswidgetextraOptions等可选能力。seoRedirect用到的正是entryurlInclude这一经典组合:用 URL 模式限定生效范围,用入口函数执行实际动作

三、URL 白名单匹配:urlInclude的判定机制

urlInclude表示"设置匹配的 URL,不匹配则不运行此组件"。seoRedirect将其设为:

urlInclude: ['//www.bilibili.com/s/video/']

注意这里使用的是协议相对形式(以//开头,省略了https:),这是仓库内 URL 模式约定中的常见写法,可同时匹配httphttps两种协议。该模式既匹配https://www.bilibili.com/s/video/BVxxx,也匹配http://www.bilibili.com/s/video/BVxxx

组件在运行前必须通过 URL 判定,判定逻辑集中在isComponentEnabled(见 src/core/settings/helpers.ts):

export const isComponentEnabled = (component: ComponentMetadata | string) => { // ... 组件存在性检查与启用状态检查 ... // 若指定了排除URL, 任意URL匹配就不加载 if (component.urlExclude && component.urlExclude.some(matchUrlPattern)) { return false } // 若指定了包含URL, 所有URL都不匹配时不加载 if (component.urlInclude && component.urlInclude.every(lodash.negate(matchUrlPattern))) { return false } return true }

判定规则可以总结为:

  1. 组件必须存在且处于启用状态(不可配置组件的启用状态固定为其默认值enabledByDefault);
  2. 若定义了urlExclude,当前 URL 命中任意一条排除规则则不加载(排除优先级高于包含);
  3. 若定义了urlInclude,当前 URL 必须命中至少一条包含规则,否则不加载

matchUrlPattern是这套判定的核心工具函数(见 src/core/utils/index.ts):

/** 以`document.URL`作为被测字符串, 移除URL查询参数并调用`matchPattern` */ export const matchUrlPattern = (pattern: string | RegExp) => matchPattern(document.URL.replace(window.location.search, ''), pattern)

它有两个关键行为:

  • 以当前页面 URL(document.URL)为被测对象,并先移除查询参数(window.location.search),因此像?from=search这类跟踪参数不会干扰匹配;
  • 支持字符串与正则表达式两种模式:字符串模式走子串包含判断(str.includes(pattern)),正则模式走pattern.test(str)

seoRedirect而言,//www.bilibili.com/s/video/作为字符串模式执行的是包含匹配——只要当前 URL 包含该子串,组件即被判定为"应在当前页面生效"。这正是该组件能被限制在 SEO 视频页面运行、而不会在其他页面误触发的根本保障。

同一套urlInclude/urlExclude机制还被用于组件加载时(src/components/component.ts)以及设置面板中组件可见性的判断(src/components/settings-panel/WidgetsPanel.vue),是整个组件体系通用的"页面生效范围"约定。

四、跳转实现:一行代码完成 URL 重写

当 URL 匹配通过后,组件入口函数被调用:

entry: () => { window.location.assign(document.URL.replace('/s/', '/')) }

这行代码包含两个动作:

  1. URL 重写document.URL.replace('/s/', '/')将当前地址中的第一个/s/路径段替换为/。以https://www.bilibili.com/s/video/BV1xx为例,替换后得到https://www.bilibili.com/video/BV1xx,即对应的原视频页面地址。注意String.prototype.replace配合字符串参数只替换第一个匹配,而/s/在 URL 中的出现位置正是路径段,恰好满足需求。

  2. 整页跳转window.location.assign(url)在保留浏览器历史记录的前提下导航到新地址(用户可按后退键返回 SEO 页)。与之相对,若使用window.location.replace(url)则会替换当前历史记录条目。

该组件未定义reloadunload生命周期——跳转是"一次性动作",页面即将离开,无需清理任何副作用,因此保持最小实现是合理的。这一设计也体现了仓库中轻量组件的普遍取舍:能用同步entry完成的逻辑绝不引入状态管理

五、完整运行链路:从页面加载到跳转发生

将上述机制串起来,seoRedirect在一次真实访问中的完整运行链路如下:

  1. 用户通过搜索引擎结果进入https://www.bilibili.com/s/video/BVxxx
  2. Bilibili-Evolved 脚本初始化,遍历组件列表并逐个调用isComponentEnabled判定;
  3. isComponentEnabledseoRedirect检查:组件已启用、urlInclude//www.bilibili.com/s/video/与当前 URL(去除查询参数后)匹配成功;
  4. 组件通过判定,进入loadComponent(src/components/component.ts),调用其entry
  5. entry执行window.location.assign(...),浏览器导航至原视频页面,用户获得完整的播放器与弹幕体验。

在整个过程中,该组件不注入样式、不修改 DOM、不监听事件,属于"纯入口函数"型组件,这也使其成为理解 Bilibili-Evolved 组件最小形态的理想范例。

六、使用与配置

seoRedirect是 Bilibili-Evolved 的内置组件,随脚本默认分发,无需额外安装。它没有暴露任何可配置选项(OptionsMetadata为空),行为固定为"SEO 页面自动重定向"。用户可以在脚本设置面板的"视频"分类(componentsTags.video)下找到"SEO 页面重定向"(displayName),通过开关控制其启用或停用;停用后再次进入 SEO 视频页面将不再自动跳转。

若需扩展类似行为(例如将其他路径也纳入重定向范围),可以参照该组件的结构自行编写用户组件:通过urlInclude限定目标页面模式,在entry中执行 URL 重写与跳转即可,完整类型定义参考 src/components/types.ts 与 registry/lib/components/video/seo-redirect/index.ts。

七、小结

seoRedirect以 11 行代码展示了 Bilibili-Evolved 组件体系的核心范式:defineComponentMetadata声明元数据、urlInclude限定生效范围、entry执行动作。理解它的实现细节,等于掌握了阅读和编写仓库内绝大多数轻量组件的钥匙——从 URL 模式匹配(matchUrlPattern)到启用判定(isComponentEnabled),再到组件加载(loadComponent),这条链路贯穿整个项目,值得每一位希望深入该项目的开发者仔细研读。

  • 前端
  • 音视频

【免费下载链接】Bilibili-Evolved

强大的哔哩哔哩增强脚本

项目地址:https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved
点击查看免费下载

相关推荐

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

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

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

立即咨询