注入 scope 导入
这个卡片使用 docs-islands 构建图中的 VitePress logger 导入。logger runtime 会读取 createDocsIslands() 注入的 scope,不再暴露通用 runtime 配置能力。
- 状态
- 正在运行探针...
- setLoggerConfig(...) 行为
- 由 createDocsIslands({ logging }) 管理
- 可见消息是否输出
- 否
- 隐藏消息是否输出
- 否
- 捕获到的 warning
- 否
logging logging 用来控制 createDocsIslands() 产生的包内日志,以及这个包公开暴露的 logger helper。它不会改变渲染逻辑,只决定 @docs-islands/* 在 Node 和浏览器里哪些消息可见。
每个 createDocsIslands() 实例都会持有隔离的 logger scope。VitePress 会把这个 scope 注入到构建图中,通用的 @docs-islands/logger runtime 会在没有显式 scope 时读取它,所以并行的多个 VitePress 实例或测试不会互相覆盖 logging 配置。框架无关的直接 logger 用法请使用 @docs-islands/logger。
当集成本身正常、但终端或浏览器控制台太吵时,可以用 logging 收窄输出范围,尤其适合按 docs-islands 内部子系统聚焦日志。接入初期通常只保留 warn 和 error;排查问题时,可以打开 debug,查看是哪几条规则放行了当前日志,以及 logger 已运行的相对耗时。
import { createDocsIslands } from '@docs-islands/vitepress';
import { react } from '@docs-islands/vitepress/adapters/react';
import { hmr } from '@docs-islands/vitepress/logger/presets';
const islands = createDocsIslands({
adapters: [react()],
logging: {
levels: ['warn', 'error'],
plugins: { hmr },
rules: {
'hmr/markdownUpdate': 'off',
'hmr/viteAfterUpdate': {},
},
},
});
islands.apply(vitepressConfig);这个配置只保留选中的 docs-islands HMR 日志的 warn 和 error。hmr/viteAfterUpdate 使用预设默认匹配器,hmr/markdownUpdate 则被显式关闭。'off' 是 { enabled: false } 的简写。
当没有配置 logging.rules 时,logger 使用默认可见级别:
debug: false:输出 error、warn、info、success。debug: true:输出 error、warn、info、success、debug。当配置了 logging.rules 时,logger 会先展开 plugin 规则,再进入规则模式:
enabled: false 的 rule。它们不参与 scope 匹配、不参与 level 放行,也不会出现在 debug label 中。main、group、message 做匹配。只要 rule 声明了多个字段,这些字段就必须同时命中。rule.levels ?? logging.levels 作为自己的 effective levels。若两者都没写,则使用默认非 debug 级别集合。levels。多条 rule 可以同时放行同一条日志。它们的可见级别按并集生效,debug label 按 logging.rules 中的声明顺序展示。
| 配置项 | 含义 |
|---|---|
debug | 启用诊断输出。可见的 error、warn、info、success 日志会带上命中的 label,以及 12.34ms 这样的相对耗时后缀。 |
levels | 根可见级别集合。在规则模式下,它是没有声明 rule.levels 的 rule 的默认 effective levels;它不是用来强制收窄所有 rule 的上限。 |
plugins | 可选的预设 plugin 注册表。对象 key 会成为 logging.rules["<plugin>/<rule>"] 里的命名空间。 |
rules | 既支持原始规则数组,也支持 plugin 规则对象。它存在且规范化后非空时,日志是否输出只由 active 且命中的 rules 决定。 |
如果你只是想过滤 docs-islands 内部日志,推荐优先使用 logging.plugins。
import { hmr, runtime } from '@docs-islands/vitepress/logger/presets';
const logging = {
debug: true,
levels: ['warn'],
plugins: { hmr, runtime },
rules: {
'hmr/viteAfterUpdate': {},
'runtime/reactDevRender': {
levels: ['warn', 'error'],
},
'runtime/renderValidation': 'off',
},
};plugins 用来注册 logging 预设 plugin,例如 hmr。rules["<plugin>/<rule>"] = {} 表示启用该预设规则并使用默认匹配器。rules["<plugin>/<rule>"] = 'off' 表示关闭该预设规则,等价于 { enabled: false }。enabled、message、levels;group 和 main 始终继承 preset matcher。@docs-islands/vitepress/logger/presets 导出的 preset,本质上是一组内建日志的默认 main/group 匹配器。下面这张目录会列出所有 preset、所有 rule,以及它们默认约束到的范围。
可以把 preset 理解成按子系统打包好的 matcher 集合,而 rule 则对应到一条具体的内建日志流。
下面这份目录直接按当前导出的 preset 定义展开。你可以点击任意 preset 名、rule 名或 main/group matcher 直接复制。你会先看到一张 preset 总表,随后每个分组表会继续展开对应 rule 的主要作用、约束范围,以及默认的 main/group matcher。
Preset
| Preset | 主要作用 | 约束范围 | 规则数 |
|---|---|---|---|
| 构建阶段里与 framework bundling、SSR 产物以及最终集成收尾相关的日志。 | 覆盖 browser bundle、SSR bundle、MPA 集成、shared client runtime metafile,以及最终 HTML 处理这类 VitePress 侧 build 分组。 | 7 条 rule | |
| 功能流水线正式开始之前的配置解析与环境前置检查日志。 | 当前只覆盖 VitePress 侧的 Node 版本校验流程。 | 1 条 rule | |
| 开发阶段里 Markdown 容器热更新和 React runtime 后续处理相关的日志。 | 覆盖 Markdown HMR 重解析、React runtime 预备、SSR-only 重渲染,以及 Vite 更新后的渲染阶段。 | 5 条 rule | |
| Markdown 页面、框架脚本块以及 React 引用分析相关的解析日志。 | 覆盖页面结构扫描、脚本块发现,以及 React import / 组件引用解析这两类 parser 分组。 | 2 条 rule | |
| VitePress 插件层里,把渲染策略接入站点的那部分日志。 | 当前只覆盖 rendering-strategy plugin 在 VitePress 侧的运行流程。 | 1 条 rule | |
| 从 VitePress 上下文派生页面或模块引用时的解析日志。 | 当前只覆盖 inline page 解析流程。 | 1 条 rule | |
| 浏览器端加载、渲染编排,以及部分共享 core 运行时校验相关的日志。 | 同时覆盖 VitePress 侧 runtime 分组,以及 core 侧的运行时校验 / React manager 分组。 | 11 条 rule | |
| Site DevTools 的 AI 服务与 build report 相关日志。 | 覆盖 VitePress 侧 Site DevTools AI server 与 AI build report 分组。 | 2 条 rule | |
| core 侧 Markdown 转换与 SSR 集成相关的 transform 日志。 | 覆盖 Markdown 组件标签转换、SSR 容器集成,以及 SSR CSS 注入这三类 core transform 分组。 | 3 条 rule |
Rule 明细
7 条 rule覆盖 browser bundle、SSR bundle、MPA 集成、shared client runtime metafile,以及最终 HTML 处理这类 VitePress 侧 build 分组。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪 Browser 侧 framework bundle 的生成和产物组织。 | |||
| 用于跟踪构建末尾的结果整理与收尾阶段。 | |||
| 用于跟踪 MPA 模式下的 framework integration 流程。 | |||
| 用于跟踪共享 client runtime 的 metafile 收集与分析。 | |||
| 用于跟踪 SSR bundle 的生成和产物布局。 | |||
| 用于跟踪 SSR 集成产物的接线与构建处理。 | |||
| 用于跟踪最终 HTML 注入、改写与框架产物落位。 |
Rule 明细
1 条 rule当前只覆盖 VitePress 侧的 Node 版本校验流程。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪 Node 版本检查与相关环境 guardrail。 |
Rule 明细
5 条 rule覆盖 Markdown HMR 重解析、React runtime 预备、SSR-only 重渲染,以及 Vite 更新后的渲染阶段。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪 Markdown 文件改动后,对容器脚本重新解析的流程。 | |||
| 用于跟踪 HMR 继续推进前的 React runtime 预备工作。 | |||
| 用于跟踪开发期更新后 ssr:only 容器的重渲染。 | |||
| 用于跟踪 Vite 完成更新后 docs-islands 的后续处理。 | |||
| 用于跟踪 Vite 更新处理完成后的渲染阶段。 |
Rule 明细
2 条 rule覆盖页面结构扫描、脚本块发现,以及 React import / 组件引用解析这两类 parser 分组。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪框架无关的页面解析与脚本块发现。 | |||
| 用于跟踪 React 专属的 import 解析、组件绑定与引用校验。 |
Rule 明细
1 条 rule当前只覆盖 rendering-strategy plugin 在 VitePress 侧的运行流程。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪渲染策略插件的挂载与运行状态。 |
Rule 明细
1 条 rule当前只覆盖 inline page 解析流程。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪 inline page 的定位与解析决策。 |
Rule 明细
11 条 rule同时覆盖 VitePress 侧 runtime 分组,以及 core 侧的运行时校验 / React manager 分组。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪 core 层 React component manager 的生命周期。 | |||
| 用于跟踪 core 层 React render strategy 的解析流程。 | |||
| 用于跟踪运行时 CSS 预加载与加载状态管理。 | |||
| 用于跟踪浏览器端 React client 入口模块的加载。 | |||
| 用于跟踪 VitePress 层 React component manager 的生命周期。 | |||
| 用于跟踪开发期内容更新落地后的运行时响应。 | |||
| 用于跟踪开发期挂载流程走向 fallback 分支时的状态。 | |||
| 用于跟踪开发期挂载阶段采用的渲染分支。 | |||
| 用于跟踪开发期 React 渲染执行流程。 | |||
| 用于跟踪开发期 runtime loader 的启动过程。 | |||
| 用于跟踪 core 层对渲染结果的校验。 |
Rule 明细
2 条 rule覆盖 VitePress 侧 Site DevTools AI server 与 AI build report 分组。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪 AI build report 的生成、缓存与读取。 | |||
| 用于跟踪 Site DevTools AI server 请求与服务端集成状态。 |
Rule 明细
3 条 rule覆盖 Markdown 组件标签转换、SSR 容器集成,以及 SSR CSS 注入这三类 core transform 分组。
| Rule | 主要作用 | main | group |
|---|---|---|---|
| 用于跟踪运行时产物输出前的 Markdown 组件标签转换。 | |||
| 用于跟踪 SSR 容器与页面输出的整合过程。 | |||
| 用于跟踪 SSR 相关 transform 阶段的 CSS 注入处理。 |
@docs-islands/vitepress/logger 是 VitePress logger facade。它只暴露 createLogger 与 formatDebugMessage;通用的直接 runtime 配置能力位于 @docs-islands/logger。
logging 定义的是 logger 的运行时可见性策略。它决定日志在运行时是否输出;在 debug 模式下,也会决定可见日志附带哪些规则标签和相对耗时信息。
@docs-islands/logger 保持 framework-agnostic。docs-islands 内部通过 @docs-islands/utils/logger 把 bundler 注入的 __DOCS_ISLANDS_LOGGER_SCOPE_ID__ 显式桥接给底层 logger,而 @docs-islands/vitepress/logger.createLogger(...) 只有在该注入 scope 存在时才可用。
logger tree-shaking plugin 是一个编译期优化层。它会在构建阶段复用已经解析好的 logging 规则,对静态可判定的 logger 调用做裁剪。
这两层相关,但不是同一个概念:
logging 始终定义运行时行为。所以,“运行时会被 suppress” 不等于 “一定会被编译期删除”。
| 维度 | logging | logger tree-shaking plugin |
|---|---|---|
| 生效阶段 | 运行时 | 编译期 |
| 是否决定最终控制台输出 | 是 | 否,runtime 语义仍然是基准 |
| 是否移除 bundle 中的静态文案 | 否 | 是,但仅限受支持的静态子集 |
是否复用已解析的 logging 规则 | 是 | 是 |
| 覆盖范围 | 完整运行时模型 | 静态可判定子集 |
| 无法分析时的退化行为 | 正常运行时匹配 | 保留调用并交给 runtime |
import { createDocsIslands } from '@docs-islands/vitepress';
import { createLogger } from '@docs-islands/vitepress/logger';
const logger = createLogger({
main: '@acme/custom-docs',
}).getLoggerByGroup('userland.metrics');
const hiddenLogger = createLogger({
main: '@acme/custom-docs',
}).getLoggerByGroup('userland.hidden');
const islands = createDocsIslands({
logging: {
debug: true,
rules: [
{
label: 'userland-metrics',
main: '@acme/custom-docs',
group: 'userland.metrics',
levels: ['info'],
},
],
},
});
islands.apply(vitepressConfig);
logger.info('visible userland info');
hiddenLogger.info('suppressed userland info');在这个配置下,userland.metrics 会保留输出,而 userland.hidden 会被抑制。
在 createDocsIslands() 管理的构建链里,docs-islands 已经会自动安装 logger tree-shaking transform。
如果你只是想在 VitePress 站点里使用公开 logger,同时又希望拿到生产环境裁剪能力,可以显式安装公开 plugin:
import { defineConfig } from 'vitepress';
import { loggerTreeShaking } from '@docs-islands/logger/plugin';
export default defineConfig({
vite: {
plugins: [
loggerTreeShaking.vite({
logging: {
levels: ['warn', 'error'],
},
}),
],
},
});如果省略 logging,plugin 会回退到默认 logger 可见性策略,这仍然会裁剪静态可判定的 debug 日志。如果你还希望 createDocsIslands() 模块图之外的动态日志也遵循同一套策略,则需要额外配置 runtime logger。
当 tree-shaking transform 生效时,只要某条用户静态日志能够被证明会被已解析的 logging 规则抑制,这条日志语句就会从生成的 JavaScript 中移除,因此它的静态 message 文案也不会进入最终 bundle。
如果你希望获得 pruning coverage,推荐使用下面这种直接写法:
import { createLogger } from '@docs-islands/vitepress/logger';
const logger = createLogger({
main: '@acme/custom-docs',
}).getLoggerByGroup('userland.metrics');
logger.info('static metric ready');
logger.success('static metric uploaded');
logger.warn('static metric delayed');
logger.error('static metric failed');
logger.debug('static metric details');优化器只分析这个受约束的静态形态:
createLogger 必须是从 @docs-islands/vitepress/logger 命名导入的函数。main、getLoggerByGroup(...) 和日志 message 都必须是字符串字面量。logger.info('message')。| 形态 | 是否参与 pruning |
|---|---|
const logger = createLogger({ main: 'x' }).getLoggerByGroup('y') | 是 |
logger.info('msg') / warn / error / success / debug | 是 |
模板字符串、字符串拼接、变量 message、动态 main、动态 group | 否 |
| alias、destructuring、reassignment、动态 method 访问 | 否 |
const result = logger.info('msg') 这类非独立表达式 | 否 |
动态日志仍然可用,但会刻意保留给运行时过滤:
logger.info(`metric ${name}`);
logger.info(`metric ${name}`);
logger.info(message);
createLogger({ main }).getLoggerByGroup(group).info('dynamic binding');这些写法依然兼容可运行,但 docs-islands 不保证它们的 message 文案会从生产产物中消失。pruning coverage 只是 runtime logging coverage 的静态可判定子集,不是它的替代品。
如果需要在 VitePress 管理的构建链之外直接使用 logger,请从框架无关的包导入:
import { createLogger, setLoggerConfig } from '@docs-islands/logger';
setLoggerConfig({
levels: ['warn', 'error'],
});
const logger = createLogger({
main: '@acme/custom-docs',
}).getLoggerByGroup('userland.metrics');
logger.warn('visible generic warning');不要再把 @docs-islands/vitepress/logger 当作通用 logger 入口使用。它只服务于 createDocsIslands() 建立的 VitePress 构建模块图。
下面这个 playground 会直接在当前 docs 站里运行 VitePress logger facade:
@docs-islands/vitepress/logger 导入会通过 runtime 注入使用当前 createDocsIslands() 实例的 logger scope。@docs-islands/logger runtime 演示已经放在独立 logger 包页面中。VitePress 导入会从 runtime 注入读取当前 docs-islands logger scope,并遵循当前 createDocsIslands({ logging }) 策略。
这个 playground 会在页面里实际运行一组 VitePress logger probe,并把对应的 console 输出回填到组件 UI,用来直接验证注入 logger scope 的行为。
这个卡片使用 docs-islands 构建图中的 VitePress logger 导入。logger runtime 会读取 createDocsIslands() 注入的 scope,不再暴露通用 runtime 配置能力。
复用内建 main/group 的影响
如果你的自定义日志故意或无意复用了 docs-islands 内建日志使用的 main / group,那么它们也可能命中同一批 preset rule 或原始 logging.rules:
debug 模式下,它们可能带上和内建日志相同的 rule label,增加排查歧义。除非你就是希望用户日志和内建日志共用同一套过滤空间,否则更推荐使用独立的 main 与 group 命名,例如 @acme/custom-docs + userland.*。
当你需要写更底层的 group / message 匹配,而不是绑定到某个 preset label 时,依然可以继续使用数组形式的 logging.rules。
| 字段 | 含义 |
|---|---|
label | 必填、稳定的规则标识。开启 debug 后,可见日志会以 [LabelA][LabelB] 的形式展示真正贡献输出的规则。 |
enabled | 可选预过滤开关。false 表示这条 rule 完全不生效;它不是低优先级 deny rule。 |
main | 可选包名精确匹配,例如 @docs-islands/vitepress。main 不使用 glob。 |
group | 可选 logger group 匹配。普通字符串按精确匹配;包含 glob magic 时使用 picomatch,例如 runtime.react.* 或 test.case.?1。 |
message | 可选消息文本匹配。普通字符串按精确匹配;包含 glob magic 时使用 picomatch,例如 *timeout*、request * 或 task-[ab]。 |
levels | 可选的当前 rule effective levels。它会替代根 levels,并和其它命中 rule 的 levels 一起组成并集。 |
原始规则数组仍然适合那种跨 preset 的宽匹配,比如直接按大范围 group 前缀或消息文本筛选。
const islands = createDocsIslands({
adapters: [react()],
logging: {
debug: true,
levels: ['warn'],
rules: [
{
label: 'react-runtime-warnings',
main: '@docs-islands/vitepress',
group: 'runtime.react.*',
},
{
label: 'runtime-timeouts',
group: 'runtime.*',
message: '*timeout*',
levels: ['error'],
},
],
},
});来自 runtime.react.component-manager 的 warn 会由 react-runtime-warnings 放行。包含 timeout 的 error 会由 runtime-timeouts 放行。如果同一条日志同时命中两条 rule,并且当前 level 被它们放行,debug 模式会按声明顺序打印两个 label。
debug 输出示例:
[react-runtime-warnings][runtime-timeouts] @docs-islands/vitepress[runtime.react.component-manager]: request timeout 12.34msconst islands = createDocsIslands({
adapters: [react()],
logging: {
levels: ['warn', 'error'],
rules: [
{
label: 'react-runtime-warn-error',
main: '@docs-islands/vitepress',
group: 'runtime.react.*',
},
],
},
});const islands = createDocsIslands({
adapters: [react()],
logging: {
levels: ['warn'],
rules: [
{
label: 'runtime-warnings',
group: 'runtime.*',
},
{
label: 'timeout-errors',
message: '*timeout*',
levels: ['error'],
},
],
},
});这会保留 runtime 的 warning,同时额外保留任何包含 timeout 的 error。两条 rule 不会互相覆盖,而是一起贡献输出能力。
const islands = createDocsIslands({
adapters: [react()],
logging: {
rules: [
{
label: 'runtime-react',
group: 'runtime.react.*',
levels: ['warn'],
},
{
label: 'runtime-react-disabled',
enabled: false,
group: 'runtime.react.component-manager',
levels: ['error'],
},
],
},
});被禁用的 rule 会被完全忽略。它不会静音或覆盖 active 的 runtime-react rule,也不会污染 debug label。
const islands = createDocsIslands({
adapters: [react()],
logging: {
rules: [
{
label: 'hydration-timeouts',
message: '*hydration*timeout*',
levels: ['warn', 'error'],
},
],
},
});message 规则适合短时间排查问题,尤其是某个高频 group 里只有少数消息值得关注时。