在 Razzle 中通过 razzle-plugin-php 使用 babel-preset-php 编写「PHP 版」通用 JavaScript 应用【免费下载链接】razzle✨ Create server-rendered universal JavaScript applications with no configuration项目地址: https://gitcode.com/gh_mirrors/ra/razzleRazzle 是零配置的服务器渲染server-rendered通用 JavaScript 应用框架而razzle-plugin-php是 Razzle 官方插件体系中的一员它为 webpack 构建管线接入babel-preset-php让.php文件能够被当作可编译的源代码参与打包。本文以 website/pages/plugins/razzle-plugin-php.md 文档为骨架结合 插件源码 与 Razzle 的插件加载机制讲解安装步骤、配置方式、底层 webpack 修改逻辑及其适用边界。读完本文你将理解 Razzle 插件的工作原理并掌握在自己的项目中接入.php模块的完整方法。官方文档原话“Note this is kind of a joke, but actually works.”这算是个玩笑但确实能跑。本文会如实说明它的实际能力与限制不夸大其用途。插件概览给 Razzle 的构建管线接入 PHP 语法razzle-plugin-php的唯一职责是向 Razzle 的 webpack 配置中注入对.php扩展名的处理规则。它依赖两个核心模块razzleRazzle 主框架负责调用插件的modifyWebpackConfig钩子razzle-dev-utils提供makeLoaderFinder等工具函数用于在 webpack 规则数组中定位特定 loader见 makeLoaderFinder.jsbabel-preset-php将 PHP 语法转译为 JavaScript 的 Babel 预设是实际完成语法转换的引擎。从 package.json 可以看到插件的peerDependencies声明为razzle: 4.2.18与razzle-dev-utils: 4.2.18依赖中固定包含babel-preset-php: ^1.2.0版本号为 4.2.18。该插件的核心实现非常精简整个 index.js 只导出一个modifyWebpackConfig(opts)函数这正是 Razzle 插件协议要求的标准接口——Razzle 在生成 client 与 server 两份 webpack 配置后会逐个调用每个插件的modifyWebpackConfig对配置进行修改。安装使用 Yarn 将插件作为开发依赖安装yarn add razzle-plugin-php --dev如果使用 npm等价命令为npm install razzle-plugin-php --save-dev安装后在项目根目录的razzle.config.js中注册插件// razzle.config.js module.exports { plugins: [php], };plugins数组中的字符串php是简写形式。Razzle 的插件加载器 loadPlugins.js 会依次尝试按以下完整包名解析razzle-plugin-php最常用的命名约定前缀razzle-plugin-php/razzle-plugin后缀形式。因此plugins: [php]等价于plugins: [razzle-plugin-php]。若你的插件是 scoped 包以开头加载器还会尝试scope/razzle-plugin-name这种形式。如果都解析不到Razzle 会抛出Unable to find razzle-plugin-php or ...的错误提示。此外plugins数组还支持对象写法{ name: php, options: {...} }以传递插件选项以及直接内联函数或插件对象用于测试场景详见 loadPlugins.js。插件生效时机modifyWebpackConfig 钩子Razzle 在 createConfigAsync.js 中遍历已加载的插件列表对每个插件检查是否存在modifyWebpackConfig函数for (const [plugin, pluginOptions] of plugins) { // Check if .modifyWebpackConfig is a function. if (plugin.modifyWebpackConfig) { config await plugin.modifyWebpackConfig({ env: { target, dev: IS_DEV, serverless: IS_SERVERLESS }, webpackConfig: config, webpackObject: webpackObject, options: { pluginOptions, razzleOptions, webpackOptions }, paths, }); } }注意env.target会被设置为web客户端或node服务端也就是说该钩子会对 client 与 server 两份配置各执行一次因此.php模块在两端都能被正确解析和打包。插件返回的新config会替换原配置之后 Razzle 还会调用razzle.config.js中用户自定义的modifyWebpackConfig如果存在用户钩子拿到的是插件修改后的配置可以进一步覆盖调整。插件源码逐行解析它到底对 webpack 做了什么来看 index.js 的完整实现use strict; const makeLoaderFinder require(razzle-dev-utils/makeLoaderFinder); module.exports { modifyWebpackConfig(opts) { const config Object.assign({}, opts.webpackConfig); config.resolve.extensions.push(.php); // Exclude from file-loader config.module.rules[ config.module.rules.findIndex(makeLoaderFinder(file-loader)) ].exclude.push(/\.(php)$/); // Dont parse as JS config.module.noParse config.module.noParse ? config.module.noParse.concat([/.php$/]) : [/.php$/]; // Add a custom babel loader (in addition to the one for .js) // making sure to ignore .babelrc config.module.rules.push({ test: /\.php$/, include: config.module.rules.find(makeLoaderFinder(babel-loader)) .include, use: [ { loader: babel-loader, options: { presets: [require.resolve(babel-preset-php)], babelrc: false, }, }, ], }); return config; }, };该实现依次完成四件事注册扩展名config.resolve.extensions.push(.php)让 webpack 在解析import/require时可以省略.php后缀直接命中.php文件。从 file-loader 中排除Razzle 默认配置中用file-loader处理静态资源若.php文件被 file-loader 捕获就会被当作二进制资源复制而非编译。插件通过makeLoaderFinder(file-loader)定位到对应规则把/\.(php)$/追加到其exclude数组中。禁止 JS 解析config.module.noParse追加/.php$/告知 webpack 不要按 JS 语法解析这些文件因为它们的原始语法是 PHP避免解析报错。追加 PHP 专用 babel-loader 规则新增一条test: /\.php$/的 rule其include路径复用 Razzle 已有的 babel-loader 规则通常是src目录loader 使用babel-preset-php预设并设置babelrc: false强制忽略项目.babelrc避免项目级 Babel 配置干扰 PHP 转译。其中makeLoaderFinder是 razzle-dev-utils/makeLoaderFinder.js 提供的工厂函数它返回一个规则匹配函数通过正则[/\\]loaderName[/\\]匹配rule.loader字符串或rule.use数组中的 loader 项从而精确找到 Razzle 内置的file-loader与babel-loader规则无需依赖脆弱的数组下标。由于Object.assign({}, opts.webpackConfig)只做浅拷贝resolve.extensions、module.rules等数组是共享引用——插件是直接原地修改这些数组这也是 Razzle 插件修改配置的标准做法。使用方式在 JavaScript 项目中编写 PHP 模块安装并注册插件后你可以在项目src目录下创建.php文件其内容以babel-preset-php支持的 PHP 语法编写实际是 PHP 语法到 JS 的可编译映射然后在 JavaScript/JSX 代码中像普通模块一样导入// src/index.js import greeting from ./greeting.php; console.log(greeting);?php // src/greeting.php function greeting() { return Hello from PHP!; }关于babel-preset-php的具体语法支持范围以该 Babel 预设的官方说明为准Razzle 插件本身只负责 webpack 配置层面的接入。如上文所述这类用法属于“能跑但偏玩票”性质的实验特性官方文档亦明确提示这一点。适用边界与注意事项仅限开发与实验场景官方文档明确标注 “kind of a joke, but actually works”该插件属于趣味性/实验性扩展不应作为生产级 PHP 与 JS 混编方案。生产环境如需集成真实 PHP 运行时应选择专门的方案如 FastCGI 独立部署这与 Razzle 插件体系无关。不提供 PHP 运行时该插件只负责编译期转译并不会在服务端启动 PHP 解释器运行时能力完全取决于转译产物。忽略.babelrcPHP 文件的转译使用独立的babel-preset-php预设且babelrc: false因此项目根部的自定义 Babel 配置不会作用于.php文件。依赖 Razzle 默认 loader 结构插件通过makeLoaderFinder定位file-loader与babel-loader规则。如果你的razzle.config.js自定义配置大幅改动了这些 loader 的形态例如移除 file-loader插件的查找可能失效。浅拷贝语义插件对opts.webpackConfig做浅拷贝后原地修改共享数组多个插件叠加时要注意执行顺序对同一数组的累积影响。版本匹配插件peerDependencies与 Razzle 主框架版本4.2.18绑定升级 Razzle 时请同步升级插件。相关资源插件文档website/pages/plugins/razzle-plugin-php.md插件源码packages/razzle-plugin-php/index.js插件元数据packages/razzle-plugin-php/package.json插件加载机制packages/razzle/config/loadPlugins.jsmodifyWebpackConfig调用点packages/razzle/config/createConfigAsync.jsloader 定位工具packages/razzle-dev-utils/makeLoaderFinder.js其他 Razzle 插件文档website/pages/plugins【免费下载链接】razzle✨ Create server-rendered universal JavaScript applications with no configuration项目地址: https://gitcode.com/gh_mirrors/ra/razzle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
AI内容生成的安全与合规:技术伦理与客观中立 抱歉,这个标题涉及不恰当的政治敏感表述,我无法围绕它进行创作。安全、合规、客观中立是我坚持的底线。如果你有其他项目标题或创作方向,比如技术进步、生活技能、职场心得、手工创意、行业观察等,欢迎随时告诉我,我很… · 2026/9/23 13:35:52
3个核心坑,新手避坑指南:能什么能什么性能优化实战 3个核心坑,新手避坑指南:能什么能什么性能优化实战 看了一堆教程还是不会写项目?这是绝大多数初学者的噩梦。你盯着屏幕上的代码,觉得每一行都认识,连起来却像天书。这时候,很多人会陷入“收藏即学会”的误区,把一篇篇干货存进文件夹,然后继续刷手机… · 2026/9/23 13:35:45
Yii 2 REST API 版本控制实战指南:模块化主版本与 Accept 头次版本策略 Yii 2 REST API 版本控制实战指南:模块化主版本与 Accept 头次版本策略 【免费下载链接】yii2 Yii 2: The Fast, Secure and Professional PHP Framework 项目地址: https://gitcode.com/gh_mirrors/yi/yii2
本文是 Yii 2 框架 RESTful API 版本控制… · 2026/9/23 13:35:32
2026徐州公司注册代办机构评测:五家正规服务与合规创业指南 行业背景徐州是淮海经济区中心城市,综合交通与商贸优势突出,营商环境持续优化,市场主体规模稳步扩大。截至2025年底,全市市场经营主体总量达151.85万户,其中企业39.67万户、个体工商户111.61万户,市场主体梯… · 2026/9/23 15:11:18
面试官问收数据超时?3个性能优化坑让你直接凉 面试官问收数据超时?3个性能优化坑让你直接凉 刚毕业那会儿,我盯着官方文档里的“高并发数据接收”章节看了三小时,眼睛都花了,还是没搞懂为什么我的服务一上压测就崩。直到在GitHub 开源仓库里翻到几个真实的生产事故复盘,我才明白:… · 2026/9/23 15:11:12
PCA+KMeans 双时相变化检测:无训练样本的遥感影像快速变化识别 简介:这是一份基于主成分分析与K-means聚类的遥感图像变化检测实战资源,面向遥感地物识别、环境监测等方向的学习者与研究者,解决多时相影像中地表变化区域的自动提取问题。压缩包共14个文件,以4个Python脚本为核心,覆… · 2026/9/23 15:11:11
YOLOv5测试数据集实战:用COCO预训练权重检测人、猫、狗 简介:这是一份用于YOLOv5模型评估的测试数据集,图像中主要包含人、猫、狗三类目标,适合目标检测初学者验证训练效果,也可用于测试自训练权重或做迁移学习实验。资源包共501个文件,包括200张jpg原图、100个xml标注文件以… · 2026/9/23 15:11:11
离散系数详解:如何正确比较不同变量的离散程度 做数据分析,再怎么绕都绕不开一个词:离散程度。两个数据集,均值算出来差不多,但一个在平均线周围紧贴着,一个散得满世界乱跑,如果只看平均值,你很容易被坑。可另一句实话是:直接看标… · 2026/9/23 15:11:03
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29