乐于分享
好东西不私藏

从零到一:构建优雅的 Vite 插件开发框架 —— @meng-xi/vite-plugin 深度解析

从零到一:构建优雅的 Vite 插件开发框架 —— @meng-xi/vite-plugin 深度解析

当你在 Vite 项目中反复编写相似的构建逻辑时,是否想过拥有一套标准化的插件开发范式?本文将带你深入剖析 `@meng-xi/vite-plugin` 的设计哲学与实现细节,揭示它如何将"造轮子"变成"搭积木"。

一、核心价值与应用场景

为什么需要 @meng-xi/vite-plugin?

在现代前端工程化体系中,Vite 以其极快的冷启动和高效的 HMR 成为构建工具的首选。然而,随着项目复杂度的增长,开发者常常面临以下痛点:

  1. 重复构建逻辑:每个项目都在写文件复制、版本号生成、图标注入等相似逻辑

  2. 插件开发门槛高:Vite 插件 API 灵活但缺乏规范,缺少统一的开发范式

  3. 配置校验缺失:插件参数错误只能在运行时暴露,调试成本高

  4. 错误处理不一致:不同插件的异常处理方式各异,难以统一管控

  5. 日志输出混乱:多插件并行时日志交织,难以追踪问题来源

@meng-xi/vite-plugin的核心价值在于双重定位

1.开箱即用的插件集

提供 copyFilegenerateRoutergenerateVersioninjectIco 四大内置插件,覆盖常见构建场景

2.完整的插件开发框架

导出 BasePluginValidatorLoggercreatePluginFactory 等核心组件,让自定义插件开发变得标准化、类型安全

典型应用场景

┌─────────────────────────────────────────────────────┐│                  @meng-xi/vite-plugin               │├─────────────────────┬───────────────────────────────┤│   内置插件(直接使用)  │   开发框架(构建自定义插件)   │├─────────────────────┼───────────────────────────────┤│ • 构建后静态资源复制    │ • 标准化插件生命周期管理       ││ • uni-app 路由生成   │ • 流畅的配置验证 API            ││ • 自动版本号管理     │ • 统一的错误处理策略             ││ • HTML 图标注入     │ • 单例日志管理器                 ││                     │ • 工厂模式 + 类型推导           │└─────────────────────┴───────────────────────────────┘

二、架构全景:模块化设计一览

项目采用清晰的分层架构,各模块职责分明:

子路径导出设计支持按需加载,减少打包体积:

// 完整导入import { copyFile, BasePluginLogger } from '@meng-xi/vite-plugin'// 按模块导入 — Tree-shaking 友好import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin/factory'import { Logger } from '@meng-xi/vite-plugin/logger'import { copyFile, generateRouter } from '@meng-xi/vite-plugin/plugins'import { Validator, readFileContent, writeFileContent } from '@meng-xi/vite-plugin/common'

三、内置插件:开箱即用的生产力工具

3.1 copyFile — 智能文件复制

场景:构建完成后将静态资源(图片、字体、配置文件等)复制到输出目录。

import { defineConfig } from 'vite'import { copyFile } from '@meng-xi/vite-plugin'export default defineConfig({  plugins: [    copyFile({      sourceDir'src/assets',      targetDir'dist/assets',      overwritetrue,      recursivetrue,      incrementaltrue // 增量复制,只复制变更文件    })  ]})

核心配置项

技术亮点:增量复制通过比较源文件与目标文件的 mtimeMs(修改时间戳)和 size(文件大小)来判断是否需要更新,避免全量复制带来的性能开销。同时,底层使用并发控制(runWithConcurrency)限制同时执行的文件 IO 操作数,在保证性能的同时避免资源耗尽。

3.2 generateRouter — uni-app 路由自动生成

场景:从 uni-app 的 pages.json 自动生成类型安全的路由配置文件,告别手动维护路由表。

import { defineConfig } from 'vite'import { generateRouter } from '@meng-xi/vite-plugin'export default defineConfig({  plugins: [    generateRouter({      pagesJsonPath'src/pages.json',      outputPath'src/router.config.ts',      nameStrategy'camelCase',      includeSubPackagestrue,      watchtrue,      metaMapping: {        navigationBarTitleText'title',        requireAuth'requireAuth'      }    })  ]})

核心配置项

生成的路由配置示例

// src/router.config.ts(自动生成)export interface RouteMeta {  title?: string  isTab?: boolean  requireAuth?: boolean  [keystring]: unknown}export interface RouteConfig {  pathstring  name?: string  meta?: RouteMeta}export const routesRouteConfig[] = [  {     path'/pages/index/index',    name'pagesIndexIndex',    meta: { title'首页'isTabtrue }  },  {     path'/pages/user/profile',    name'pagesUserProfile',    meta: { title'个人中心'requireAuthtrue }  }]export default routes

技术亮点

  • 智能合并:开启 preserveRouteChanges 后,重新生成时会保留用户对 routes 数组的手动修改(如自定义 meta 字段),新字段以 pages.json 为基础,用户修改覆盖其上

  • 文件监听:开发模式下自动监听 pages.json 变化,实时重新生成路由配置

  • JSON 注释兼容:内置 stripJsonComments 函数,支持解析含注释的 pages.json

3.3 generateVersion — 多格式版本号生成

场景:在构建过程中自动生成版本号,支持输出到文件、注入全局变量或两者兼有。

import { defineConfig } from 'vite'import { generateVersion } from '@meng-xi/vite-plugin'export default defineConfig({  plugins: [    // 语义化版本 + 前缀 + 附加信息    generateVersion({      format'semver',      semverBase'2.0.0',      prefix'v',      outputType'both',      defineName'__APP_VERSION__',      extra: {        environment'production',        author'MengXi Studio'      }    }),    // 自定义格式模板    generateVersion({      format'custom',      customFormat'{YYYY}.{MM}.{DD}-{hash}',      hashLength6    })  ]})

支持的版本号格式

自定义模板占位符

{YYYY}  四位年份     {MM}    两位月份     {DD}    两位日期{HH}    两位小时     {mm}    两位分钟     {ss}    两位秒数{timestamp} 时间戳   {hash}  随机哈希{major}  主版本号    {minor} 次版本号     {patch} 补丁版本号

输出方式

  • file — 生成 version.json 文件到构建输出目录

  • define — 通过 Vite 的 define 注入全局变量(如 __APP_VERSION__

  • both — 同时使用以上两种方式

在代码中使用注入的版本号:

// 通过 define 注入后,可直接访问console.log(__APP_VERSION__) // "v2.0.0"console.log(__APP_VERSION_INFO__) // { version: "v2.0.0", buildTime: "...", ... }

3.4 injectIco — HTML 图标注入

场景:将网站图标(favicon)链接自动注入到 HTML 的 <head> 中,同时支持图标文件复制。

import { defineConfig } from 'vite'import { injectIco } from '@meng-xi/vite-plugin'export default defineConfig({  plugins: [    // 简写:只指定 base 路径    injectIco('/assets'),    // 完整配置:多图标 + 文件复制    injectIco({      base'/assets',      icons: [        {          rel'icon',          href'/favicon.svg',          type'image/svg+xml'        },        {          rel'icon',          href'/favicon-32x32.png',          sizes'32x32',          type'image/png'        },        {          rel'apple-touch-icon',          href'/apple-touch-icon.png',          sizes'180x180'        }      ],      copyOptions: {        sourceDir'src/assets/icons',        targetDir'dist/assets/icons'      }    })  ]})

核心配置项

优先级链link > icons > url > base + favicon.ico

技术亮点:优先使用 Vite 原生 HtmlTagDescriptor API 注入标签(更可靠、更规范),仅在用户提供自定义 link HTML 时才降级为字符串替换方案。同时通过 OptionsNormalizer 支持字符串简写配置。

四、插件开发框架:BasePlugin 核心机制

BasePlugin 是整个框架的灵魂,它将 Vite 插件开发的通用逻辑抽象为标准化的生命周期和开发范式。

4.1 生命周期管理

┌──────────────────────────────────────────────────────────┐│                    BasePlugin 生命周期                     │├──────────────────────────────────────────────────────────┤│                                                          ││  ① constructor                                           ││     ├── mergeOptions()     合并默认配置与用户配置          ││     ├── initLogger()       初始化插件日志代理             ││     ├── new Validator()    初始化配置验证器               ││     └── validateOptions()  执行配置验证                   ││                                                          ││  ② configResolved(Vite 钩子)                            ││     └── onConfigResolved() 存储 Vite 解析后的配置         ││                                                          ││  ③ addPluginHooks()        注册业务钩子(子类实现)        ││                                                          ││  ④ closeBundle(Vite 钩子)                               ││     └── destroy()          销毁资源、注销日志             ││                                                          │└──────────────────────────────────────────────────────────┘

子类只需关注两个核心方法:

abstract class BasePlugin<T extends BasePluginOptions> {  /** 必须实现:返回插件名称 */  protectedabstractgetPluginName(): string  /** 必须实现:注册 Vite 插件钩子 */  protected abstract addPluginHooks(plugin: Plugin): void}

4.2 钩子自动组合

toPlugin() 方法自动组合 configResolved 和 closeBundle 钩子,确保基类逻辑与子类逻辑有序执行:

configResolved 执行顺序:  BasePlugin.onConfigResolved()  →  子类注册的 configResolved 钩子closeBundle 执行顺序:  子类注册的 closeBundle 钩子  →  BasePlugin.destroy()

设计意图:配置解析时基类先初始化(存储 viteConfig),子类再使用;销毁时子类先清理(如关闭 watcher),基类再注销日志。顺序不可颠倒。

4.3 配置验证器 Validator

Validator 提供流畅的链式 API,让配置验证声明式、可读性强:

protectedvalidateOptions(): void {  this.validator    .field('sourceDir').required().string()    .custom(val => val.trim() !== '''sourceDir 不能为空字符串')    .field('targetDir').required().string()    .field('overwrite').boolean().default(true)    .field('incremental').boolean().default(true)    .validate()}

支持的验证规则

4.4 错误处理策略

通过 errorStrategy 配置项统一管控错误行为,配合 safeExecute / safeExecuteSync 实现安全执行:

// 三种策略interface BasePluginOptions {  errorStrategy?: 'throw' | 'log' | 'ignore'}

使用方式

// 包裹可能出错的操作const result = await this.safeExecute(async () => {  return await someRiskyOperation()}, '执行风险操作')// result 在 throw 策略下:要么是正常返回值,要么已抛出异常// result 在 log/ignore 策略下:正常返回值或 undefined

4.5 日志系统 Logger

Logger 采用 单例 + 代理 模式,全局唯一实例管理所有插件的日志输出:

Logger(单例)  ├── pluginConfigs: Map<string, boolean>    // 各插件日志开关  ├── create({ name, enabled })              // 注册插件日志配置  ├── unregister(name)                       // 注销插件日志配置  └── createPluginLogger(name)               // 创建插件级日志代理        ├── info(message, data?)        ├── success(message, data?)        ├── warn(message, data?)        └── error(message, data?)

日志输出格式(带颜色和图标):

ℹ️ [@meng-xi/vite-plugin:generate-router] 路由配置文件已生成: src/router.config.ts

✅ [@meng-xi/vite-plugin:copy-file] 复制文件成功:从 src/assets 到 dist/assets

⚠️ [@meng-xi/vite-plugin:generate-version] 版本文件路径未配置

❌[@meng-xi/vite-plugin:inject-ico] 图标文件不存在: /assets/favicon.ico

设计优势

每个插件通过 verbose 选项独立控制日志开关

插件销毁时自动注销日志配置,防止内存泄漏

统一前缀格式 [@meng-xi/vite-plugin:插件名],便于在多插件并行时快速定位来源

4.6 工厂函数 createPluginFactory

createPluginFactory 将插件类转换为符合 Vite 规范的工厂函数,同时支持 选项标准化器

// 基本使用const myPlugin = createPluginFactory(MyPlugin)// 带标准化器 — 支持字符串简写配置const injectIco = createPluginFactory<InjectIcoOptions, InjectIcoPlugin, string | InjectIcoOptions>(InjectIcoPlugin, options => (typeof options === 'string' ? { base: options } : options || {}))// 使用时支持简写injectIco('/assets'// 字符串 → 自动转换为 { base: '/assets' }injectIco({ base'/assets' }) // 对象 → 直接使用

返回值增强:工厂函数返回的 Vite 插件对象附带 pluginInstance 属性,可访问插件内部状态:

import type { PluginWithInstance } from '@meng-xi/vite-plugin/factory'const routerPlugin = generateRouter({ watchtrue }) as PluginWithInstance<GenerateRouterOptions>console.log(routerPlugin.pluginInstance?.options// 访问合并后的完整配置

五、技术实现亮点与创新点分析

1. 深度合并策略 —deepMerge

// undefined 值不覆盖已有默认值,null 值会覆盖deepMerge({ a1 }, { a: undefined }) // { a1 } ← 保留默认值deepMerge({ a1 }, { a: null }) // { a: null } ← 允许显式置空deepMerge({ a: { b1 } }, { a: { c: 2 } }) // { a: { b1, c: 2 } } ← 嵌套合并deepMerge({ a: [12] }, { a: [34] }) // { a: [34] } ← 数组覆盖

这一设计确保了 BasePlugin.mergeOptions() 的三层合并(基础默认值 → 插件默认值 → 用户配置)行为可预测:用户未提供的字段使用默认值,显式传入 undefined 不会意外覆盖默认值。

2. 并发控制的文件复制 —runWithConcurrency

async function runWithConcurrency<T, R>(items: T[], handler(item: T) => Promise<R>, concurrencynumber): Promise<R[]>

采用 Worker Pool 模式,通过共享索引实现并发限制。相比 Promise.all(无限制并发)和串行执行(效率低),这种方式在 IO 密集场景下实现了性能与资源占用的平衡。

3. 增量复制 — 基于文件元数据的智能判断

async function shouldUpdateFile(sourceFilestringtargetFilestring): Promise<boolean> {  const [sourceStats, targetStats] = await Promise.all([fs.promises.stat(sourceFile), fs.promises.stat(targetFile)])  return sourceStats.mtimeMs > targetStats.mtimeMs || sourceStats.size !== targetStats.size}

同时比较修改时间和文件大小,避免因时间戳精度问题导致的误判。在大型项目中,增量复制可将重复构建的文件复制耗时从秒级降至毫秒级。

4. 路由配置智能合并 —preserveRouteChanges

generateRouter 插件在重新生成路由时,会解析已有的 router.config.ts,提取用户手动修改的字段,并与新生成的配置合并:

新生成的配置(来自 pages.json) + 用户手动修改 → 合并结果─────────────────────────────────────────────────────────────path'/home', meta: { title: '首页' } }              +path'/home', meta: { title: '首页', custom: true } }              ↓path'/home', meta: { title: '首页', custom: true } }

合并策略path 始终以 pages.json 为准(它是标识符),meta 先以新生成的为基础,再用用户修改覆盖(用户优先)。

5. 双模式图标注入 — HtmlTagDescriptor 优先

injectIco 插件优先使用 Vite 原生 HtmlTagDescriptor API(更规范、更可靠),仅在用户需要注入自定义 HTML 字符串时降级为 transformIndexHtml 字符串替换。这种渐进降级策略兼顾了规范性和灵活性。

6. 类型安全的完整闭环

从 BasePluginOptions 到具体插件选项(如 CopyFileOptions extends BasePluginOptions),从 PluginFactory 到 PluginWithInstance,整个类型链确保了:

  • 工厂函数的输入类型与插件类的配置类型一致

  • pluginInstance 的类型与实际插件实例匹配

  • Validator<T> 的字段名与配置对象的键名对应

六、实战案例:从零开发一个自定义插件

下面我们开发一个构建时间统计插件,在构建开始和结束时记录耗时:

import { BasePlugin, createPluginFactory } from '@meng-xi/vite-plugin'import type { BasePluginOptionsPluginWithInstance } from '@meng-xi/vite-plugin/factory'import type { Plugin } from 'vite'// 1. 定义配置接口interface BuildTimerOptions extends BasePluginOptions {  /** 是否输出详细时间节点 */  detailed?: boolean  /** 自定义日志标签 */  label?: string}// 2. 继承 BasePlugin 实现插件类class BuildTimerPlugin extends BasePlugin<BuildTimerOptions> {  private startTimenumber = 0  protected getDefaultOptions(): Partial<BuildTimerOptions> {    return {      detailedfalse,      label'Build Timer'    }  }  protected validateOptions(): void {    this.validator.field('detailed').boolean().field('label').string().validate()  }  protected getPluginName(): string {    return 'build-timer'  }  protected addPluginHooks(pluginPlugin): void {    plugin.buildStart = {      order'pre'// 确保最先执行      handler() => {        this.startTime = Date.now()        this.logger.info(`${this.options.label}: 构建开始`)      }    }    plugin.closeBundle = {      order'post'// 确保最后执行      handler() => {        const elapsed = Date.now() - this.startTime        this.logger.success(`${this.options.label}: 构建完成,耗时 ${elapsed}ms`)        if (this.options.detailed) {          this.logger.info(` 开始时间: ${newDate(this.startTime).toLocaleString()}`)          this.logger.info(` 结束时间: ${newDate().toLocaleString()}`)        }      }    }  }}// 3. 使用 createPluginFactory 导出工厂函数export const buildTimer = createPluginFactory(BuildTimerPlugin)

使用方式

import { defineConfig } from 'vite'import { buildTimer } from './plugins/build-timer'export default defineConfig({  plugins: [buildTimer({ detailedtruelabel'My App' })]})

控制台输出

ℹ️ [@meng-xi/vite-plugin:build-timer] My App: 构建开始

✅ [@meng-xi/vite-plugin:build-timer] My App: 构建完成,耗时 3247ms

ℹ️ [@meng-xi/vite-plugin:build-timer] 开始时间: 2026/5/18 15:30:00

ℹ️ [@meng-xi/vite-plugin:build-timer] 结束时间: 2026/5/18 15:30:03

七、注意事项与最佳实践

⚠️ 常见陷阱

1. 不要忘记调用 super.destroy()

// ❌ 错误:资源未清理,日志未注销protecteddestroy(): void {  this.stopWatching()}// ✅ 正确:先清理子类资源,再调用基类销毁protecteddestroy(): void {  this.stopWatching()  super.destroy()}

2. closeBundle 钩子不要手动注册

BasePlugin.toPlugin() 已自动组合 closeBundle 钩子,子类只需重写 destroy() 方法。手动注册 closeBundle 会导致基类销毁逻辑被覆盖。

3. configResolved 钩子不要手动注册

同理,toPlugin() 已自动组合 configResolved。如需在配置解析后执行逻辑,重写 onConfigResolved() 方法:

// ❌ 错误protected addPluginHooks(pluginPlugin): void {  plugin.configResolved = (config) => { /* ... */ }}// ✅ 正确protected onConfigResolved(configResolvedConfig): void {  super.onConfigResolved(config) // 存储配置  // 自定义逻辑...}

4. 异步操作务必使用 safeExecute

// ❌ 错误:异常未被捕获,可能导致构建进程崩溃plugin.writeBundle = async () => {  await this.copyFiles()}// ✅ 正确:异常按 errorStrategy 处理plugin.writeBundle = async () => {  await this.safeExecute(() => this.copyFiles(), '复制文件')}

💡 最佳实践

1. 合理设置 errorStrategy

// 生产构建:严格模式,任何错误立即中断copyFile({  sourceDir'...',  targetDir'...',  errorStrategy'throw'})// 开发辅助:宽松模式,非关键操作失败不影响主流程generateVersion({  format'hash',  errorStrategy'log'})

2. 利用 verbose 控制日志噪音

// 生产环境关闭非关键插件的日志generateVersion({ verbosefalse })

3. 使用 pluginInstance 进行运行时交互

const versionPlugin = generateVersion({ outputType'define' }) as PluginWithInstance<GenerateVersionOptions>// 在其他构建脚本中访问版本号console.log(versionPlugin.pluginInstance?.options)

4. 善用 OptionsNormalizer 提供简写 API

// 为你的插件支持字符串简写export const myPlugin = createPluginFactory(MyPluginopt => (typeof opt === 'string' ? { path: opt } : opt || {}))// 用户可以更简洁地使用myPlugin('./custom-path')myPlugin({ path'./custom-path'verbosetrue })

5. 增量操作优先

对于文件操作类插件,始终默认开启增量模式(incremental: true),在大型项目中效果显著。

八、总结与展望

@meng-xi/vite-plugin 的设计哲学可以概括为三个关键词:

如果你正在寻找一套 Vite 插件开发的最佳实践,或者需要开箱即用的构建工具集,@meng-xi/vite-plugin 值得一试。

# 安装pnpm add @meng-xi/vite-plugin -D

项目地址:https://github.com/MengXi-Studio/vite-plugin

完整文档:https://mengxi-studio.github.io/vite-plugin/

本文基于 @meng-xi/vite-plugin@0.0.6 版本撰写,如有更新请以最新文档为准。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-18 21:45:46 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/642793.html
  2. 运行时间 : 0.101490s [ 吞吐率:9.85req/s ] 内存消耗:4,639.88kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=4e5f1fbbee4ec92d8bd401ae7d6e2c3d
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000640s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000676s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000306s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000296s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000500s ]
  6. SELECT * FROM `set` [ RunTime:0.000193s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000585s ]
  8. SELECT * FROM `article` WHERE `id` = 642793 LIMIT 1 [ RunTime:0.000696s ]
  9. UPDATE `article` SET `lasttime` = 1779111946 WHERE `id` = 642793 [ RunTime:0.009629s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000338s ]
  11. SELECT * FROM `article` WHERE `id` < 642793 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000514s ]
  12. SELECT * FROM `article` WHERE `id` > 642793 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000421s ]
  13. SELECT * FROM `article` WHERE `id` < 642793 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000694s ]
  14. SELECT * FROM `article` WHERE `id` < 642793 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000555s ]
  15. SELECT * FROM `article` WHERE `id` < 642793 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001738s ]
0.103145s