
前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载本指南基于 wp-calypso 官方开发者文档《Hello, World!》完整讲解如何在 CalypsoThe JavaScript and API powered WordPress.com中新增一个异步加载的 Section并用 React 组件构建页面视图。读完本文你将掌握 feature flag 开关、五步建区流程、路由中间件链siteSelection→navigation→ 自定义 controller →makeLayout→clientRender以及组件样式接入的完整实战方案可以立即在自己的本地仓库中复现。在动手之前请先确保已经按照 docs/install.md 完成本地环境搭建。启动开发服务器后在浏览器中打开http://calypso.localhost:3000/。本示例要求你已经登录 WordPress并且至少创建了一个站点——因为后面的路由配置会用到站点选择机制。一、认识 SectionCalypso 的页面组织单元在 Calypso 中Section是应用里较大的功能区域它拥有自己独立的代码块chunk并且只在对应 URL 被访问时才异步加载。这一设计让首屏体积保持可控也让每个业务模块可以独立演进。官方文档将创建新 Section 的过程拆解为五个步骤在config/development.json中添加你的功能开关feature flag建立 Section 文件夹client/my-sites/my-section创建控制器client/my-sites/my-section/controller.js在client/my-sites/my-section/index.js中配置入口路由在client/sections.js中注册 Section。下面依次展开每个步骤。二、五步创建新 Section1. 添加功能开关Feature Flag打开config/development.json在features对象中加入一条新条目hello-world: true实际的文件结构如下节选自 config/development.json{ env: development, env_id: development, hostname: calypso.localhost, port: 3000, features: { 100-year-plan/vip: true, ad-tracking: false, blackbox: true, // ... 按字母序排列的众多 feature flag } }Feature flag 是 Calypso 在特定环境启用/禁用功能的惯用手段代码可以先合并进trunk但通过 flag 隐藏起来等到时机成熟再灰度放开。关于 flag 的完整机制参见 config/README.md#feature-flags。几个关键规则值得注意按字母序添加新增 flag 时应保持features对象有序方便查找同步所有环境配置一个 flag 通常需要同步写入client.json、development.json、production.json、horizon.json、stage.json、test.json、wpcalypso.json等所有配置文件环境递进WordPress.com 的 flag 推进路径是development → wpcalypso → horizon → stage → production左边环境已开启的 flag右边环境通常也应开启Jetpack 与 A4A 也有各自的递进序列上线后清理功能正式发布到生产后应清理 flag 判断代码保持代码库整洁。Calypso 提供了多种本地调试 flag 的快捷方式环境变量临时开关构建期生效ENABLE_FEATURESsome/flag-name DISABLE_FEATURESreader yarn startURL 查询参数动态开关仅开发、stage 与 calypso.live 生效生产环境不适用?flagsfoo # 启用 foo ?flags-bar # 禁用 bar ?flagsfoo,-bar # 同时启用 foo、禁用 bar例如访问http://calypso.localhost:3000/?flagssome/flag-name即可临时开启对应功能。仅本地持久生效在仓库根目录创建.env文件写入ACTIVE_FEATURE_FLAGS变量值为逗号分隔的 flag 列表。在代码中flag 通过automattic/calypso-config包读取。该包的入口文件 packages/calypso-config/src/index.ts 导出了isEnabled即config.isEnabled( key )的别名对应实现见packages/calypso-config/src/index.ts#L123同时包内还提供config( key )读取任意配置项。2. 建立文件夹结构本教程把 Hello World 页面放在 my-sites 分区下。在本地 Calypso 项目根目录执行mkdir client/my-sites/hello-world3. 创建控制器文件控制器controller.js里存放每个路由命中时被调用的函数touch client/my-sites/hello-world/controller.js在其中写入一个名为helloWorld的控制器函数export const helloWorld ( context, next ) { console.log( Hello, world? ); next(); };每个控制器函数都会被注入context与next两个参数context携带当前路由、store、primary/secondary 内容区等运行时信息next用于把执行权交给路由链上的下一个中间件。4. 配置入口路由创建 Section 的主文件index.jstouch client/my-sites/hello-world/index.js写入路由设置代码import { isEnabled } from automattic/calypso-config; import page from automattic/calypso-router; import { makeLayout, render as clientRender } from calypso/controller; import { navigation, siteSelection } from calypso/my-sites/controller; import { helloWorld } from ./controller; export default () { if ( isEnabled( hello-world ) ) { page( /hello-world/:site?, siteSelection, navigation, helloWorld, makeLayout, clientRender ); } else { page.redirect( / ); } };这段代码的每一行都有明确职责flag 守卫先用isEnabled( hello-world )判断功能是否开启未开启则跳过路由注册并重定向回首页路由注册page()注册/hello-world路由命中后按顺序执行一串函数可选站点参数:site?结尾的问号表示该参数可选使路由支持站点级页面如/hello-world/example.wordpress.com中间件链每个函数都接收context与next前一个调用next()后执行权移交下一个siteSelection来自 my-sites 主控制器负责站点选择流程见下文源码分析navigation同样来自 my-sites 主控制器把侧边栏导航插入context.secondaryhelloWorld我们刚写的控制器处理函数makeLayout创建Layout元素其中包含context.primary与context.secondary的内容clientRender把Layout元素渲染进 DOM。关于page模块与 ES6 模块语法export/import可参考 MDN 与相关 ES6 模块文档学习此处不再展开外部链接。5. 注册 Section打开client/sections.js在sections数组末尾追加const sections [ // ** lots of sections here ** // add new section: { name: hello-world, paths: [ /hello-world ], module: calypso/my-sites/hello-world, }, ];真实仓库中的 client/sections.js 正是这样一个大型数组每个元素描述一个 Sectionname是逻辑名称paths是该 Section 对应的 URL 前缀列表module指向异步加载的模块入口。除了这三个基础字段实际代码中还会出现group如sites、me、enableLoggedOut允许未登录访问、meta如 robots noindex等附加属性例如根 Section 定义{ name: root, paths: [ / ], module: calypso/root, group: root, enableLoggedOut: true, },即使 flag 关闭也要注册 Section——这正是五步流程的精妙之处注册始终存在而路由是否生效由第 4 步的isEnabled决定。当 flag 关闭时/hello-world路由不会被注册自然就回退到了首页重定向。运行验证重启开发服务器yarn start打开http://calypso.localhost:3000/hello-world。如果一切正常控制台会输出Hello, world?页面会出现 My Sites 的侧边栏。三、构建 React 视图The View接下来用 React 组件构建主视图分三步创建main.jsx、创建style.scss、接通控制器。1. 创建主视图 main.jsxtouch client/my-sites/hello-world/main.jsx先引入 React 外部依赖和内部MainUI 组件来自calypso/components/main再导出组件骨架import { Component } from react; import Main from calypso/components/main; export default class HelloWorld extends Component {}随后添加render()方法用Main组件输出标记import { Component } from react; export default class HelloWorld extends Component { render() { return ( Main h1Hello, World!/h1 /Main ); } }关于项目编写 React 组件的整体规范参见 docs/components.md。2. 创建 style.scss按照组件规范每个组件只有一个样式文件命名为style.scss与组件同目录。创建空文件touch client/my-sites/hello-world/style.scss写入 HelloWorld 组件样式.hello-world { background-color: #fafafa; } .hello-world__title { color: #37a000; font-size: 3rem; }把样式类应用到组件上import { Component } from react; export default class HelloWorld extends Component { render() { return ( Main classNamehello-world h1 classNamehello-world__titleHello, World!/h1 /Main ); } }最后一步在组件的 JavaScript 源文件顶部引入样式文件import ./style.scss;这样 webpack 才会把 SCSS 编译并打包进该组件的 chunk。SCSS 书写的完整约定见 docs/coding-guidelines/css.md。3. 接通控制器回到/hello-world/controller.js在文件顶部引入新组件import HelloWorld from calypso/my-sites/hello-world/main;然后删除原来的console.log改为把组件挂到context.primaryexport const helloWorld ( context, next ) { context.primary HelloWorld /; next(); };这里HelloWorld元素被放入context.primary属性最终会被渲染进Layout元素的#primarydiv 中context.secondary则对应#secondary即侧边栏区域。四、源码级原理路由中间件与布局渲染路由链上的关键函数都能在仓库源码中找到真实实现帮助我们理解每一步背后的机制。siteSelection定义在 client/my-sites/controller.jsx#L610它从context.params.site或路径中解析站点标识getSiteFragment并处理多种边界情况无站点用户渲染NoSitesMessage、站点全部隐藏时提示用户、单站点用户直接重定向到单站点上下文等。这解释了文档中至少设置一个站点的前提要求——站点选择是整个 my-sites 体系的公共前置逻辑。navigation定义在 client/my-sites/controller.jsx#L855export function navigation( context, next ) { // Render the My Sites navigation in #secondary if ( ! context.hideLeftNavigation ) { context.secondary createNavigation( context ); } next(); }它把 My Sites 导航渲染进context.secondary即#secondary区域并尊重context.hideLeftNavigation标记。makeLayout与clientRender来自 client/controller/index.web.jsx服务端对应index.node.jsx前者根据context.primary、context.secondary等属性创建Layout元素后者负责将Layout挂载到 DOM。context.primary的消费逻辑正是文档中提到的 client/layout/index.jsx。五、完整验收再次确认服务器在运行yarn start浏览器打开http://calypso.localhost:3000/hello-world你应该看到页面显示 Hello, World! 标题位于 My Sites 侧边栏旁边标题为绿色#37a000、3rem 字号页面背景为浅灰#fafafa由于路由中挂载了siteSelection在侧边栏切换站点时hello-world Section 会随之联动切换站点上下文。至此一个从零搭建、带 feature flag 控制、异步加载、包含 React 视图与样式的完整 Calypso Section 就大功告成了。Happy calypsoing相关阅读上一章项目价值观 Values | 下一章Calypso 背后的技术 The Technology Behind Calypso赞分享前端CMS【免费下载链接】wp-calypsoThe JavaScript and API powered WordPress.com项目地址https://gitcode.com/gh_mirrors/wp/wp-calypso点击查看免费下载相关推荐Databus核心组件详解Relay、Client、Bootstrap和ProducerDatabus核心组件详解Relay、Client、Bootstrap和Producer Databus是一个与源无关的分布式变更数据捕获系统能够实时捕获和Lagom框架入门从零开始构建Hello World服务Lagom框架入门从零开始构建Hello World服务 什么是Lagom框架 Lagom是一个基于响应式编程理念的微服务框架专为构建高可扩展、高并发的分布Express.js 入门指南从零构建Hello World应用Express.js 入门指南从零构建Hello World应用 什么是Express.js Express.js是一个基于Node.js平台的极简Web应文档教程技术博客上一篇如何快速掌握国家图书馆ISBN插件Calibre图书信息自动化管理的终极指南下一篇Yarn 的 yarnpkg/plugin-compat 插件解析内置补丁与 packageExtensions 如何让 PnP 兼容整个生态创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考