即时通讯后端前端【免费下载链接】Rocket.ChatThe Secure CommsOS™ for mission-critical operations项目地址https://gitcode.com/GitHub_Trending/ro/Rocket.Chat点击查看免费下载rocket.chat/peggy-loader是 Rocket.Chat 官方维护的 PeggyPEG.js 的继任者Webpack loader其职责是在构建阶段把.pegjs语法描述文件直接编译为可直接import的解析器模块从而让聊天消息的 Markdown 解析、提及、表情符号等语法规则在浏览器端以纯 ES 模块形式运行。本文以 packages/peggy-loader/README.md 为主线结合其源码 packages/peggy-loader/src/index.ts 与仓库内真实消费方 packages/message-parser 的配置完整讲解安装、接入、原理与工程实践读完后你可以直接在任意 Webpack 5 项目中把 Peggy 语法文件接入构建链。背景为什么需要“Peggy loader”Peggy 是一种 PEGParsing Expression Grammar解析表达式文法解析器生成器它接收一份.pegjs语法文件生成对应的 JavaScript 解析器。Rocket.Chat 的消息解析器 packages/message-parser/src/grammar.pegjs约 900 行就承载了消息文本的完整文法涵盖 Markdown、引用、提及用户/频道、表情符号、时间戳、表格、任务列表等规则。问题在于语法文件本身不是 JS不能直接被import。传统做法有两条路——运行时编译在 Node 环境里用peggy.generate()把语法字符串现场编译例如仓库中基准测试用的 packages/message-parser/loaders/pegjs-register.js构建时编译本 loader 的做法在 Webpack 打包阶段把.pegjs文件当作一种资源经 loader 转换为 ES 模块源码再交给打包器。rocket.chat/peggy-loader走的是第二条路它把“语法→解析器”的编译从运行时挪到构建时运行时只保留一份纯 JS 的解析器减少每次解析的开销这也是 packages/peggy-loader/CHANGELOG.md 中多次提到“改进消息解析器性能”的实现基础之一。安装两条依赖缺一不可README 明确指出peggy与webpack是本包的对等依赖peer dependencies必须先安装。使用 npmnpm i peggy webpack npm i rocket.chat/peggy-loader使用 yarnyarn add peggy webpack yarn add rocket.chat/peggy-loader这一点与 packages/peggy-loader/package.json 中声明的依赖关系完全一致peerDependencies为peggy: *与webpack: *即由使用方决定这两个包的版本而仓库内部开发时锁定的组合是peggy 4.1.1、webpack ~5.104.1、typescript ~5.9.3见devDependencies。也就是说只要你的项目里同时存在 Peggy 与 Webpack 5这个 loader 即可无缝接入。在 Webpack 配置中接入message-parser 的真实用法仓库中最直接的消费案例是 packages/message-parser/webpack.config.ts。它针对\.pegjs$后缀文件启用本 loaderimport { resolve } from node:path; export default [ { entry: ./src/index.ts, module: { rules: [ { test: /\.ts$/, use: { loader: ts-loader, options: { configFile: resolve(./tsconfig.build.json), }, }, include: [resolve(./src)], exclude: [resolve(./tests)], }, { test: /\.pegjs$/, use: [rocket.chat/peggy-loader], }, ], }, resolve: { extensions: [.ts, .js, .pegjs], }, mode: production, experiments: { outputModule: true, }, output: { path: resolve(./dist), filename: messageParser.js, library: { type: module, }, }, }, ];几个值得注意的细节规则声明use: [rocket.chat/peggy-loader]即调用 loader 的默认导出这里未传任何 options依赖源码内的默认行为后文详述解析扩展名resolve.extensions中加入了.pegjs保证import * as grammar from ./grammar.pegjs这样的语句能被正确解析见 packages/message-parser/src/index.ts 第 2 行ESM 输出experiments.outputModule: true与library.type: module配合输出为真正的 ES 模块这与 loader 默认生成的format: es源码是配套的——如果你的产物面向 CommonJS 环境则需要通过 options 覆盖格式见下文“可配置项”。源码原理一个函数完成全部编译整个 loader 的实现浓缩在 packages/peggy-loader/src/index.ts全文仅一个函数import type { BuildOptionsBase, OutputFormatAmdCommonjsEs, OutputFormatBare, OutputFormatGlobals, OutputFormatUmd, SourceOptionsBase, } from peggy; import peggy from peggy; import type { LoaderContext } from webpack; type Options BuildOptionsBase ( | OmitOutputFormatAmdCommonjsEssource, keyof SourceOptionsBasesource | OmitOutputFormatUmdsource, keyof SourceOptionsBasesource | OmitOutputFormatGlobalssource, keyof SourceOptionsBasesource | OmitOutputFormatBaresource, keyof SourceOptionsBasesource ); function peggyLoader(this: LoaderContextOptions, grammarContent: string): string { return peggy.generate(grammarContent, { output: source, format: es, ...this.getOptions(), }); } export default peggyLoader;逐行拆解其行为函数签名loader 接收grammarContent.pegjs文件的原文并返回一段 JS 源码字符串符合 Webpack loader 的“输入源文件、输出编译后代码”契约this是 Webpack 注入的 LoaderContext核心调用peggy.generate(grammarContent, ...)把语法文本编译为解析器默认值output: source表示返回可读的 JS 源码而非序列化后的函数体format: es表示默认生成 ES 模块选项合并...this.getOptions()把 webpack 规则中options字段透传给peggy.generate且位于默认值之后——这意味着使用方传入的任意选项会覆盖默认的output/format。例如在 message-parser 的基准测试场景中如需 CommonJS 产物可传入{ format: commonjs }这也与 packages/message-parser/loaders/pegtransform.js 中运行时编译采用format: commonjs的方式形成对照。可配置项Options 类型与合并机制从type Options可以看出loader 支持的配置即 Peggy 的BuildOptionsBase与四种output: source输出格式选项的并集类型来源说明BuildOptionsBase文法编译的基础选项例如allowedStartRules允许的起始规则、cache是否启用解析缓存、trace是否生成轨迹等 Peggy 构建期参数OutputFormatAmdCommonjsEssourceAMD / CommonJS / ES 模块三种格式的源码输出选项OutputFormatUmdsourceUMD 格式源码输出选项OutputFormatGlobalssource全局变量挂载格式输出选项OutputFormatBaresource裸函数体输出选项联合类型|与Omit的组合保证了类型系统层面只接受合法的输出格式配置。由于this.getOptions()的展开位于默认值之后README 未单独罗列参数表但通过这个类型定义即可确认任何 Peggy 官方peggy.generate支持的选项都可以作为 webpack rule 的options传入例如{ test: /\.pegjs$/, use: { loader: rocket.chat/peggy-loader, options: { format: umd, allowedStartRules: [Start], }, }, }TypeScript 类型声明让import语法文件有类型Peggy 语法文件被编译成 JS 后TypeScript 并不知道.pegjs是什么。message-parser 通过 packages/message-parser/src/typings/peg.d.ts 声明了该模块的形状declare module *.pegjs { import type { ParserOptions } from peggy; import type { ASTMessage } from ../definitions; export const parse: (input: string, options?: ParserOptions) ASTMessage; }它把任意.pegjs导入描述为“暴露一个parse(input, options)函数、返回ASTMessage”的模块。由此packages/message-parser/src/index.ts 才能安全地写出import type { Root } from ./definitions; import * as grammar from ./grammar.pegjs; ... export const parse (input: string, options?: Options): Root grammar.parse(input, options);在 packages/message-parser/src/index.ts 中parse只是对编译后解析器的一层薄封装上层如 apps/meteor/client/lib/messageStateHandler.ts 中的import { parse } from rocket.chat/message-parser拿到的是同一份 AST。这一整套“loader 编译 d.ts 类型声明 包装导出”的链路正是本项目把 Peggy 引入前端构建体系的标准范式值得其他 PEG 使用者借鉴。构建与代码规范monorepo 下的标准动作README 的工程实践部分针对本仓库monorepoworkspaces 见根目录 package.json给出了三条命令yarn build # 构建根目录执行turbo 驱动所有 workspace yarn lint # 代码风格检查 yarn lint-and-fix # 自动修复可修复的 lint 问题README 特别强调由于该包依赖仓库内其他 workspace 包首次构建需在仓库根目录执行yarn build根目录脚本为turbo run build。就 peggy-loader 自身而言其构建脚本是rm -rf dist tsc -p tsconfig.build.json见 packages/peggy-loader/package.json即先用 TypeScript 编译产出dist/index.js与dist/index.d.ts配置见 packages/peggy-loader/tsconfig.build.json开启declaration/declarationMap/sourceMap再通过main: dist/index.js、types: dist/index.d.ts暴露给使用方。在提交代码前运行yarn lint可以确保风格与仓库 eslint 配置一致yarn lint-and-fix则能自动修复大部分警告与错误。版本与演进从 fuselage 到 Rocket.Chat 主仓库packages/peggy-loader/CHANGELOG.md 记录了该包的演进脉络0.25.02021-05随 fuselage 引入 Peggy loader作为独立包发布0.26.02021-05修复 “Peggy loader options” 问题即getOptions()合并机制的正确性修正0.31.26 / 0.31.27与消息解析器性能优化相关间接服务于聊天消息解析提速0.31.28升级 ESLint 及其配置当前仓库内版本包version字段同为0.31.28。当前该包已从 fuselage 迁移至 Rocket.Chat 主仓库的packages/目录并以rocket.chat/peggy-loader: workspace:~的形式被 packages/message-parser/package.json 引用属于 yarn workspace 内部依赖yarn.lock中的解析路径为rocket.chat/peggy-loaderworkspace:packages/peggy-loader。小结与使用建议综合 README 与源码可以总结出三条可直接落地的经验依赖配对安装时必须同时提供peggy与webpack两个 peer 依赖loader 本身不锁定它们的版本默认即用不传 options 时rocket.chat/peggy-loader默认把.pegjs编译为 ES 模块源码output: sourceformat: es与 Webpack 5 的outputModule实验特性配合最佳需要 AMD/UMD/CommonJS 等格式时通过 webpack rule 的options覆盖类型配套TS 项目中要同时提供declare module *.pegjs声明才能让语法文件的导入通过类型检查——message-parser 的 packages/message-parser/src/typings/peg.d.ts 是最直接的参考实现。如果你正在维护自己的 Peggy 语法并希望以“构建时编译”的方式把它接入前端打包链路直接复用rocket.chat/peggy-loader的接入模式即可获得与 Rocket.Chat 消息解析器相同的工程体验。赞分享即时通讯后端前端【免费下载链接】Rocket.ChatThe Secure CommsOS™ for mission-critical operations项目地址https://gitcode.com/GitHub_Trending/ro/Rocket.Chat点击查看免费下载相关推荐Rocket.Chat Fuselage UI Kit 指南用 UiKit 为 Rocket.Chat Apps 构建交互界面Rocket.Chat Fuselage UI Kit 指南用 UiKit 为 Rocket.Chat Apps 构建交互界面 rocket.chat/fu即时通讯后端前端探索Peggy高效解析之旅的启航点探索Peggy高效解析之旅的启航点 随着软件工程的发展数据处理和语言解析成为了开发中的关键环节。今天我们向您隆重介绍 Peggy ——一个为JavaScr开发工具代码生成编译器深入解析 Rocket.Chat 的 rocket.chat/ai-search 共享 AI 搜索原语包深入解析 Rocket.Chat 的 rocket.chat/ai search 共享 AI 搜索原语包 rocket.chat/ai search 是 R即时通讯后端前端上一篇华硕笔记本性能优化GHelper轻量控制工具完全指南下一篇RePKG终极指南快速掌握Wallpaper Engine资源提取与转换技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考