Rocket.Chat 的 `@rocket.chat/peggy-loader`:在 Webpack 构建中把 Peggy 语法文件编译为 ES 模块解析器
即时通讯后端前端【免费下载链接】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),仅供参考

相关新闻

ComfyUI本地部署与工作流搭建:从零跑通AI绘画环境

ComfyUI本地部署与工作流搭建:从零跑通AI绘画环境

1. 为什么本地跑图这件事值得认真对待如果你最近才开始接触AI绘画,大概率会经历这样一个过程:先用在线工具生成几张图,觉得挺新鲜,然后发现免费额度用完了,或者想调一个特定的姿势、换一个特定的画风,在线工…

2026/10/10 8:54:30 阅读更多 →
水流量示意图制作全指南:类型划分、工具选型与模板复用

水流量示意图制作全指南:类型划分、工具选型与模板复用

干过给排水、环保、水利项目的人都有体会:方案汇报时,一张干净的水流量示意图,比满屏数据表格更能说服人。无论是污水厂提标改造的工艺流程图,还是城市供水管网的水量分配图,甚至是科研论文里的测流时序曲线&#xff0…

2026/10/10 8:54:30 阅读更多 →
KV Cache Offloading 原理详解:GLM5.2 如何用 CPU DRAM 突破 1M 长上下文 HBM 内存墙

KV Cache Offloading 原理详解:GLM5.2 如何用 CPU DRAM 突破 1M 长上下文 HBM 内存墙

KV Cache Offloading 原理详解:GLM5.2 如何用 CPU DRAM 突破 1M 长上下文 HBM 内存墙 【免费下载链接】GLM5.2-KV-Offloading-FusedSfaOverlap 项目地址: https://ai.gitcode.com/Ascend-SACT/GLM5.2-KV-Offloading-FusedSfaOverlap 在 GLM5.2 长文本推理场…

2026/10/10 8:53:28 阅读更多 →

最新新闻

Java+Selenium驱动Chrome 118.0.5958.0实战指南

Java+Selenium驱动Chrome 118.0.5958.0实战指南

简介:本资源是一套面向Java开发者与自动化测试初学者的Selenium爬虫实战教学包,聚焦浏览器自动化采集场景,解决Chrome版本与驱动器严格匹配难、环境配置易出错、代码调试无参照等常见痛点。资源共56个文件,涵盖9个核心Java源码、9…

2026/10/10 10:20:06 阅读更多 →
边缘AI视频分析网关16路部署实战:从算力选型到场景落地全记录

边缘AI视频分析网关16路部署实战:从算力选型到场景落地全记录

做边缘AI视频分析这行有几年了,手头经手的盒子少说也有几百台。前两天刚给一个施工现场部署完一台领嵌的16路边缘AI云盒子,趁着热乎劲儿,把从选型到落地的完整过程梳理一遍。这玩意儿现在在工地、社区、校园、加油站这几个场景里用得越来越多…

2026/10/10 10:20:05 阅读更多 →
PLC能ping通却下载失败?MTU排查顺序与远程维护实战经验

PLC能ping通却下载失败?MTU排查顺序与远程维护实战经验

做PLC远程维护的人,几乎都遇到过这种“半通不通”的怪问题:设备在本地调试时一切正常,一旦放到远程链路里,PLC明明能ping通,组态软件却下载程序失败,要么提示“目标站无响应”,要么卡在进度条某…

2026/10/10 10:20:05 阅读更多 →
3亿token批量生成实战:大模型自动化管线与PV创意项目拆解

3亿token批量生成实战:大模型自动化管线与PV创意项目拆解

1. 从“3亿token”这个数字说起:它到底意味着什么第一次看到“花费3亿token”这个说法,我的反应和大多数人一样——这数字听着唬人,但到底是个什么量级?如果你平时只是拿大模型聊聊天、写写周报,可能对token没什么概念…

2026/10/10 10:20:05 阅读更多 →
跨平台存储适配实战:从设计到排查的完整指南

跨平台存储适配实战:从设计到排查的完整指南

1. 跨平台存储适配为什么总被低估1.1 一个真实到让人头疼的场景去年我帮一个朋友处理过一个项目,他们做了一款本地优先的笔记工具,在桌面端跑得挺稳,用户量也慢慢起来了。后来团队决定做移动端,想着“逻辑都是现成的,U…

2026/10/10 10:20:05 阅读更多 →
MySQL数值函数详解:ROUND、TRUNCATE、CEIL、FLOOR与精度避坑指南

MySQL数值函数详解:ROUND、TRUNCATE、CEIL、FLOOR与精度避坑指南

写SQL的人,没有一天能绕开数值处理。上一篇文章把字符串函数过了一遍,这篇轮到数值函数。你别觉得数值函数就是加减乘除加个四舍五入,真到用的时候,round、truncate、ceil、floor这几个函数到底谁是谁,金额对不上账、评…

2026/10/10 10:19:04 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →