ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

razzle-plugin-php:让 Razzle 应用直接编写并编译 PHP 的 Webpack 插件实战

razzle-plugin-php:让 Razzle 应用直接编写并编译 PHP 的 Webpack 插件实战 前端构建工具前端构建后端【免费下载链接】razzle✨ Create server-rendered universal JavaScript applications with no configuration项目地址https://gitcode.com/gh_mirrors/ra/razzle点击查看免费下载Razzle 是一款无需配置即可构建「服务端渲染的通用 JavaScript 应用」的工具而razzle-plugin-php是官方仓库中一个特殊的 Webpack 插件它通过接入babel-preset-php让 Razzle 项目中的.php文件能够像 JavaScript 一样被 Babel 转译后打包进客户端与服务端产物。读完本文你将掌握该插件的安装配置方法、它对 Webpack 配置所做的每一处修改及其背后原理以及如何在 Razzle 项目里实际编写、导入并运行 PHP 代码。官方 README 的原话是 Note this is kind of a joke, but actually works.——这虽然是个偏「整活」性质的插件但它的技术实现是完全真实可用且自洽的。插件是什么一行简介razzle-plugin-php位于仓库 packages/razzle-plugin-php做的事情只有一件为 Razzle 的 Webpack 编译链路添加babel-preset-php。安装并启用后你在项目里写的.php文件会被 Babel 以 PHP 语法预设进行解析与转译生成可运行的 JavaScript进而被 Webpack 打包进 client浏览器端与 serverNode.js 端两套构建产物中。从 packages/razzle-plugin-php/package.json 可以看到它的依赖关系运行时依赖babel-preset-php^1.2.0这是负责将 PHP 语法转换为 JS 的核心转译器对等依赖peerDependenciesrazzle与razzle-dev-utils版本与本插件保持一致当前为4.2.18。也就是说它不自己实现任何解析器而是完全复用 Razzle 现成的 Babel/Webpack 基础设施只是把 PHP 预设接进去。安装与启用按 README 的步骤在 Razzle 项目中安装插件yarn add razzle-plugin-php --dev如果使用 npmnpm install razzle-plugin-php --save-dev然后在项目根目录的razzle.config.js中注册// razzle.config.js module.exports { plugins: [php], };这里plugins数组中写字符串php即可。Razzle 在加载插件时会自动做名称解析见下文插件是如何被加载的所以不需要写全razzle-plugin-php。插件如何被加载名称解析与选项透传从源码 packages/razzle/config/loadPlugins.js 看razzle.config.js中的plugins数组支持多种写法字符串形式php等价于{ name: php }以默认空选项应用插件{ name: php, options: {...} }对象形式可携带自定义选项直接传入插件函数或插件对象便于测试与本地开发。对于字符串/对象形式Razzle 会按以下顺序在node_modules中尝试require解析完整包名如果是 scoped 包则先尝试${scope}/razzle-plugin-${name}razzle-plugin-${plugin.name}例如razzle-plugin-php${plugin.name}/razzle-plugin。解析成功后返回[pluginModule, pluginOptions]元组随后在构建配置阶段被依次调用详见 createConfigAsync.js 与 createConfigAsync.js。插件内部做了什么逐行拆解 modifyWebpackConfigrazzle-plugin-php的核心只有一个导出对象即 packages/razzle-plugin-php/index.js 中的modifyWebpackConfig(opts)方法。Razzle 在生成客户端web与服务端node两套 Webpack 配置后都会调用该方法让它分别对两套配置做同样的改造。整个方法依次完成四件事use strict; const makeLoaderFinder require(razzle-dev-utils/makeLoaderFinder); module.exports { modifyWebpackConfig(opts) { const config Object.assign({}, opts.webpackConfig); // 1. 让 Webpack 能够解析 .php 扩展名 config.resolve.extensions.push(.php); // 2. 把 .php 从 file-loader 的匹配中排除 config.module.rules[ config.module.rules.findIndex(makeLoaderFinder(file-loader)) ].exclude.push(/\.(php)$/); // 3. 禁止 Webpack 把 .php 当普通 JS 做 noParse 解析 config.module.noParse config.module.noParse ? config.module.noParse.concat([/.php$/]) : [/.php$/]; // 4. 追加一条针对 .php 的 babel-loader 规则 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; }, };下面按步骤说明每一处修改的作用。步骤 1让 .php 成为可解析的模块扩展名config.resolve.extensions.push(.php);Webpack 通过resolve.extensions决定模块导入时可以省略的扩展名。追加.php后代码中import foo from ./foo或require(./foo)会优先命中foo.js找不到时才尝试foo.php。这一步让.php文件真正进入了模块系统可以被import/require引用。步骤 2把 .php 从 file-loader 中排除config.module.rules[ config.module.rules.findIndex(makeLoaderFinder(file-loader)) ].exclude.push(/\.(php)$/);Razzle 默认的构建链路中file-loader负责把图片、字体等静态资源拷贝为文件并返回 URL。如果不加排除.php文件会被file-loader当成普通静态资源处理返回一个文件 URL而不是被 Babel 转译。因此插件用makeLoaderFinder(file-loader)找到默认的file-loader规则并在其exclude中加入\.(php)$正则把.php从资源处理中抢出来。makeLoaderFinder是 Razzle 官方工具 razzle-dev-utils/makeLoaderFinder.js 提供的高阶函数它通过构造[/\\]loaderName[/\\]正则去匹配规则中的 loader 字符串兼容rule.loader字符串形式与rule.use数组形式从而在复杂的 Webpack 规则中精确定位某个 loader 对应的规则。步骤 3禁止 noParse 兜底解析config.module.noParse config.module.noParse ? config.module.noParse.concat([/.php$/]) : [/.php$/];noParse是 Webpack 用来跳过模块内容解析的优化手段被匹配的模块不会经过依赖解析。若不加处理Webpack 可能对未知扩展名的.php文件走noParse兜底路径导致内容被原样塞进产物。插件把/.php$/追加进noParse的反向补充列表——需要说明的是这里实际上是把.php从默认的 JS 解析路径中摘除交由专门的 babel-loader 规则接管从而保证 PHP 代码一定经过转译而非被跳过。步骤 4追加 .php 专属的 babel-loader 规则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, }, }, ], });这是整个插件最关键的一步新增一条test: /\.php$/的规则并做了两件细致的事复用默认 babel-loader 的include通过makeLoaderFinder(babel-loader)找到 Razzle 默认的 JS babel-loader 规则直接沿用其include通常是src目录保证新规则只处理项目源码目录下的 PHP 文件不误伤node_modules只启用babel-preset-php并关闭.babelrcpresets: [require.resolve(babel-preset-php)]用require.resolve锁定实际安装的预设路径避免解析歧义babelrc: false确保 PHP 文件不会被项目根目录的.babelrc/ Babel 配置干扰PHP 代码只按 PHP 预设的规则转译。由于rules是数组、追加在末尾且test精确匹配.php这条规则与原有的.jsbabel-loader 规则互不冲突形成了JS 走默认预设、PHP 走 PHP 预设的双轨并行结构。在项目里怎么用一个最小可运行示例启用插件后你可以在src目录下新建一个 PHP 文件插件沿用了默认 babel-loader 的include即src目录?php // src/greet.php function greet($name) { return Hello, . $name . from PHP!; }然后在任意 JS/JSX 模块中导入并使用它// src/App.js import greet from ./greet; export default function App() { return div{greet(Razzle)}/div; }babel-preset-php会把上述 PHP 语法转译成可执行的 JavaScript 函数Webpack 随后将其分别打包进 client 与 server 两份产物。由于modifyWebpackConfig对 web / node 两个 target 都会被调用见 createConfigAsync.js 中插件循环位于最终配置生成阶段因此 PHP 模块在浏览器端和服务端都能正常运行天然支持服务端渲染场景。适用前提与注意事项这是一个能用但别较真的插件babel-preset-php只是将 PHP 语法的子集翻译成 JS并非完整的 PHP 运行时不适用于真实的 PHP 业务逻辑适合作为实验、演示或技术玩味场景正如 README 自嘲的 kind of a joke, but actually works。必须与 Razzle 4.x 配套peerDependencies锁定了razzle与razzle-dev-utils的4.2.18版本使用前请确保项目 Razzle 版本与之兼容。不要和静态资源处理混淆启用插件后src下的.php会被当作代码模块转译而不是被file-loader拷贝为静态文件若确有静态.php文件需求请放在public目录由静态服务直接提供。插件顺序与冲突插件在最终配置阶段按plugins数组顺序依次执行若同时启用多个会改写module.rules的插件注意它们在数组中的先后顺序。深入阅读想继续深挖可以阅读仓库中的以下文件插件核心实现packages/razzle-plugin-php/index.js插件元信息与依赖声明packages/razzle-plugin-php/package.json插件加载与名称解析逻辑packages/razzle/config/loadPlugins.js插件modifyWebpackConfig的调用时机packages/razzle/config/createConfigAsync.jsloader 查找工具函数packages/razzle-dev-utils/makeLoaderFinder.js官方文档页面website/pages/plugins/razzle-plugin-php.md赞分享前端构建工具前端构建后端【免费下载链接】razzle✨ Create server-rendered universal JavaScript applications with no configuration项目地址https://gitcode.com/gh_mirrors/ra/razzle点击查看免费下载相关推荐Razzle 插件 razzle-plugin-php 实战在 Universal React 应用中用 Babel 编译 PHP 代码Razzle 插件 razzle plugin php 实战在 Universal React 应用中用 Babel 编译 PHP 代码 razzle plu前端构建工具前端构建后端在 Razzle 中通过 razzle-plugin-php 使用 babel-preset-php 编写「PHP 版」通用 JavaScript 应用在 Razzle 中通过 razzle plugin php 使用 babel preset php 编写「PHP 版」通用 JavaScript 应用 Raz前端构建工具前端构建后端razzle-plugin-bundle-analyzer为 Razzle 应用接入 webpack-bundle-analyzer 包体积分析razzle plugin bundle analyzer为 Razzle 应用接入 webpack bundle analyzer 包体积分析 本指南围绕前端构建工具前端构建后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表