我使用微前端创建 Netflix 克隆版的经历
内容
什么是微前端?
为什么是微前端?
微前端框架
皮拉尔
项目
最后的想法
所有代码的快速链接
我使用Piral创建了一个 Netflix 克隆:一个用于创建模块化应用程序的开源框架。
在本文中,我将介绍什么是微前端,它们为何有用,以及有哪些框架可以帮助你更轻松地实现它们。我还将分享我使用 React 和 Piral 独立创建项目的经验:这两项我之前从未接触过的技术。我将介绍我做了哪些工作以及如何完成的。最后,我将分享一些关于这个项目的总结、观点和个人笔记。
“我是如何做到的”部分将以每位开发人员(无论技能水平如何)都能理解的方式编写。请务必尝试一下 Piral 或微前端,然后告诉我您的体验如何!

内容
什么是微前端?
微前端试图将微服务的理念和优势扩展到前端领域。本质上,这种架构模式可以归结为“将前端整体拆分成更小、更易于管理的部分”。
这使得完全跨职能的团队能够专注于特定的业务功能或公司使命。与按层或技术划分的“横向”团队不同,这些团队管理应用程序的“纵向”部分。每个团队都是独立的,并且对其开发的功能负有端到端的责任——从数据库到用户界面。
团队应该能够独立创建和部署这些微前端。这减少了团队间的沟通,从而实现了分布式开发。
这对于规模较大的公司和项目尤其有利,杰夫·贝佐斯的“两个披萨团队”规则(即两个披萨就能喂饱整个团队)会很有帮助。例如,Spotify 将这些规模较小的功能团队称为“小队”。 有趣的内容请阅读这里。
为什么是微前端?
微前端使团队更加敏捷
当将微前端的特点和优势与 12 条敏捷原则进行比较时,会出现很多重叠之处:
-
自治团队
自主团队满足许多敏捷原则。简而言之:能够独立运作的团队不易被拖慢进度,能够快速做出改变,并拥有更强的主人翁意识。
-
增量升级
通过解耦和分散,微前端架构模式确保敏捷软件开发的增量和迭代过程能够成功。
-
独立部署
微前端可以独立部署。这可以缩短发布周期,因为各个部分无需彼此同步。
-
简洁且解耦的代码库
简洁性对于敏捷性至关重要:这使得整个团队更容易上手并快速迭代。解耦使得使用不同的技术成为可能;但即使在整个应用程序中使用相同的技术,它仍然对开发效率非常有益。
微前端框架
虽然您可以采用微前端原则并设计自己的解决方案来管理它们(事实上,这就是我的学士论文的主题);但已经有很多框架可以为您完成一些繁重的工作。
Florian Rappl 在以下博客文章中概述并分类了许多此类框架:
流行的选项包括Single SPA、Open Components、Mosaic、Podium、Luigi和Piral。
这些框架并非相互竞争,而是并存的,它们各自提供了创建微前端解决方案的不同方式。它们在关键属性上有所不同,例如完整性(仅解决部分问题,例如路由,还是提供包含错误边界、工具、生态系统等的完整端到端解决方案)或架构风格(例如,构建时组合、客户端组合、服务器端组合)。
皮拉尔
Piral 是一个用于构建高度灵活的模块化应用程序的开源框架。它基于 React 构建,但也提供大量适用于其他框架和技术的插件。
构建模块和术语
使用 piral 构建的应用程序由多个部分组成。
如果您没有微前端经验,本节内容可能会让您感到困惑。不必担心:下面的“项目”部分会将抽象转化为实际操作,让您更容易理解。
Pilets(功能模块)
这些是独立的功能模块,也称为微前端。它们各自包含自己的依赖项和资源,并且彼此完全独立。
Pilet 可以定义其组件的集成方式。Pilet 是否需要专用页面,还是内容将在现有的 Pilet 中渲染?也许我们需要一个专用页面,并在其他地方注册一个链接到该页面的按钮?这都是可能的。
供稿服务
Pilet 通常发布到 feed 服务(例如 REST API)。Piral 在piral.cloud上提供了自己的 feed 服务。
值得注意的是,Piral 可以在没有 feed 服务的情况下工作,但 feed 服务使得部署变得简单并且消费变得非常动态;展示了 Piral 的所有优势。
Piral 实例(应用程序外壳)
所有功能模块都将集成在这里。piral 实例将从 feed 服务中提取所有已注册的 Pilet,并根据 Pilet 自身定义的位置将它们放置到需要的位置。应用外壳也是放置基本布局的地方:导航栏、页眉、页脚和共享组件。
构建应用程序外壳的结果是一个dist/release
用于托管的目录,以及一个dist/emulator
带有 tarball 的目录,该目录可以发布到 NPM 注册表以帮助开发和调试各个 pilet。
(组件)扩展、页面和菜单项
piral API 支持在您的 Pilet 和 Piral 实例中注册扩展。例如,假设我们有一个包含两个 Pilet 的网店:一个用于列出产品的发现Pilet,以及一个允许用户购买这些商品的结账Pilet(顺便说一下,这是一个经典的微前端示例,点击此处了解更多信息)。发现Pilet 应该包含一个用于购买商品的按钮,但由于这不是该团队的职责,因此结账团队将创建此按钮并将其注册为所有 Pilet 均可使用的扩展。然后,发现Pilet 只需注册一个扩展插槽,App Shell 即可将相应的扩展集成到该插槽中。
Piral 还内置了注册页面和菜单项的功能。这些功能也可以被视为扩展,但实际工作已经为您完成了。
项目
我做了什么
应用程序概述
您可以在netflixclone.deruwe.me上在线找到该应用程序。
这款应用是 Netflix 的克隆版,具备一些基本功能。它有一个Browse
页面,用户可以在其中找到热门剧集和电影的展示、评分最高的剧集和电影等等。
当然,要查找特定的电影或连续剧,用户也可以使用提供的Search
栏。
Favorites
每个媒体模块的右上角都有一个开关。点击它会将剧集或电影添加到用户的收藏列表中,并在收藏页面上找到。
用户可以通过Profile
右上角的选项切换账户。所有收藏夹均与特定账户关联。
值得注意的是,这个演示项目没有附带自定义后端:所有数据都来自第三方 API,帐户是虚拟帐户,收藏夹存储在本地存储中。
印象


应用程序的结构
应用程序外壳
应用外壳仅包含徽标、导航和页脚。所有其他组件均由 Pilet 以扩展、页面和菜单项的形式提供。
小猪
皮莱特 | 注册组件 |
---|---|
Browse |
Browse (页) |
Favorites |
FavoritesToggle (组件扩展) |
Watch |
MovieTile (组件扩展)Player (页) |
Search |
Search (组件扩展) |
Profile |
UserProfile (组件扩展)AccountSwitcher (页) |
我是如何做到的
在使用 piral 创建项目的过程中,Piral 文档显然是我的主要灵感来源。文档中也有很多关于 Piral 主题的视频教程。
Piral 文档也讨论了开发工作流程的三个阶段。这也是我尝试开发应用程序的方式。当然,为了进行实验,我有时会稍微突破一下界限。
0.规划阶段
但在遵循 Piral 提供的任何步骤之前,我先寻找了一个可以作为基础的示例项目。我不是设计师,所以寻找一个具有良好样式的 React 项目是最简单的选择。我找到了这个项目,它使用较旧的 React 语法编写,并且所有内容都包含在一个大App
模块中。我把所有内容都转换成了单独的 React 函数组件。这是一个学习 React 工作原理的好方法。
您可以在以下 repo 中看到结果。这里的提交历史记录显示了我所做的操作。
DanteDeRuwe / react-netflix-clone
通过创建一个简单的 Netflix 克隆来学习 React。(我将其转化为微前端解决方案!详情请参阅 https://git.io/netflix-piral)
1. 设置阶段
这个阶段需要做什么?
- 开发螺旋实例
- 设置 feed 服务并将 piral 实例连接到它
- 分发模拟器包
1.1. 创建 Piral 实例(应用程序外壳)
你可以在 github 上找到代码
按照文档的说明,我学会了如何启动并运行它。运行以下命令全局安装 Piral CLI:
npm install piral-cli -g
(也可以使用 npx 来避免不安全的全局安装,见下文)
CLI 公开了以piral
和开头的命令pilet
。在这个阶段,我们当然需要这些piral
命令。
要创建名为netflix-piral的 Piral 实例(应用程序外壳),让我们运行
piral new --target netflix-piral
我们可以使用以下命令运行新创建的 Piral 实例:
piral debug
# or, if you want to open the browser automatically:
piral debug --open
- 使用
npx
-
piral debug
除了只能在目录中起作用的命令之外package.json
,或者如果您已全局安装了 Piral CLI,您还可以使用npx
:
- 如果给定的名称在(修改后的)路径(例如全局路径或
node_modules/.bin
)中不可用,npx 将尝试从 NPM 获取命令并运行它(非全局运行,即从用户权限运行)- 如果给定的名称可用,它将从那里运行它(也可以从用户权限运行)
让我们看一下最重要的文件之一index.tsx
:
import 'piral/polyfills'; | |
import { renderInstance } from 'piral'; | |
import { layout, errors } from './layout'; | |
// change to your feed URL here (either using feed.piral.cloud or your own service) | |
const feedUrl = 'https://feed.piral.cloud/api/v1/pilet/empty'; | |
renderInstance({ | |
layout, | |
errors, | |
requestPilets() { | |
return fetch(feedUrl) | |
.then(res => res.json()) | |
.then(res => res.items); | |
}, | |
}); |
该renderInstance
函数概述了 App Shell 的职责:它负责布局、错误布局,并从 feed 服务请求 Pilet。正如我们在第 6 行看到的,默认情况下,它只是从一个空的 feed 中提取数据。
实际上,这个文件中唯一需要更改的是 feed URL。为此,我们首先要设置一个 feed。
1.2. 设置 feed 服务
虽然您可以(在某些情况下应该)设置自己的 feed 服务,但大多数情况下,Piral 团队提供的服务就足够了。出于开发目的,您可以免费获得多个 feed!此服务可在piral.cloud上找到。
▸ 在piral.cloud上创建 feed
登录该服务后,您将看到以下屏幕
当然,我们要点击+ New Feed
。
接下来,我们将为 feed 指定一个唯一的名称(不可更改),并可选地添加一个描述,以便明确此 feed 的用途。
您还可以配置允许的主机。
- 为了以后能够发布 Pilet,我们需要一个 API 密钥。您可以通过点击
- 要获取应用外壳的 feed url,我们可以点击 feed 标题。url 将会显示出来:
我们将复制 feed url 并将其放置在我们之前想要的位置:在index.tsx
Piral 实例中(第 6 行)。
1.3. 创建应用程序外壳布局
我们现在有了一个 App Shell,它从我们自己的(仍然为空的)Feed 中拉取数据!稍后我们会将 Pilet 添加到这个 Feed 中。但首先,我们或许应该自定义这个 App Shell 的布局。如前所述,我们希望这个 App Shell 的主要功能是 Logo、导航和页脚。
搭建脚手架后,layout.tsx
文件包含许多组件,并将它们组合成一个layout
对象以供使用index.tsx
。虽然这很好,但我喜欢将所有组件拆分成每个组件一个文件,因此结果如下所示:
我们将布局放入./components/App.tsx
,导航模板放入.components/Navigation.tsx
,对于菜单项,它们仅使用进行渲染<li>...</li>
。
记住我之前提到的:
应用外壳仅包含徽标、导航和页脚。所有其他组件均由 Pilet 以扩展、页面和菜单项的形式提供。
确实如此,但我们确实需要定义 Pilet 需要在哪里渲染这些扩展!以下是应用程序外壳的快速线框图。
Pilet 注册的页面将直接作为 传递给App
组件children
。我们可以使用 React-router 来包裹它们。
至于扩展:集成这些扩展的关键在于一个ExtensionSlot
具有特定名称的扩展。Pilet 可以注册扩展,并提供一个名称,然后 App Shell 会将它们放入正确的插槽中。
该组件的代码App
如下。第 14 行name="header-items"
注册了扩展槽,第 19 行渲染不同的页面。
菜单项index.tsx
在 Piral 中是标准化的。在Piral中注册的组件MenuContainer
(在我们的例子中是组件)将像Pilet 注册时Navigation
一样获取菜单项。children
1.4. 在 Netlify(或其他地方)上部署 App Shell
如果您已经了解托管的工作原理,那么这里是 TLDR:执行
piral build --type release
并发布dist/release/
文件夹!当然,您可以设置 CI/CD 来为您完成此操作。别忘了设置一个_redirects
用于路由的文件!
要将应用程序部署到全世界,我们需要将其发布到某个地方。对我来说,最好的地方是Netlify。当然,您可以选择 Azure 静态 Web 应用、Github 页面或其他托管平台,但 Netlify 易于使用,并且拥有许多完全免费的强大功能。
首先,在 Netlify 上创建一个帐户。我喜欢使用我的 Github 帐户,因为这样帐户之间就已经关联了。
接下来在界面的站点选项卡中创建一个“从 git 创建新站点”。
找到你的 App Shell 的 Github 仓库。如果你还没有,可以创建一个 ;)
现在按如下方式配置构建设置:
- 设置分支(我使用 master,你也可以创建自定义
release
分支) - 将构建命令设置为
npm run build
或piral build
或piral build --type release
- 将发布目录设置为
/dist/release/
(不要跳过此步骤!)
然后,只需单击按钮即可部署您的网站!现在,每次您将代码推送到所选分支时,网站都会更新!CI/CD 大获全胜!
▸_redirects
文件
首次部署 App Shell 时,您可能不会注意到,但路由并不完善。为了避免以后出现问题,最好先按照以下步骤操作,这样就无需再次修改 App Shell 了。
如果您访问yourwebsite.netlify.app/test,Netlify 会尝试查找一个test.html
页面来提供服务,但找不到,并显示一条错误消息。我们希望 React Router 能够处理路由。我们必须将所有路由重定向到index.html
……为此,我们创建一个带有路径的文件夹/src/static/
,并将一个_redirects
文件放入其中:
/* /index.html 200
为了确保此文件release
在构建时被复制到目录中,我们需要配置 webpack 来执行此操作。
npm install copy-webpack-plugin --save-dev
在项目的根文件夹中,创建webpack.config.js
这会将目录中的所有内容复制src/static/
到构建目录。这意味着您以后可以static
根据需要将图像和其他文件添加到此目录。
1.5. 发布模拟器
▸ 模拟器的用途是什么?
现在,我们的应用外壳已经启动并运行了。当我们将 Pilet 推送到我们的 feed 服务时,应用外壳可以立即访问这些 Pilet,网站也会随之更新。但是,如果我们想开发新的 Pilet 怎么办?我们肯定不会为了看看效果而发布上百次吧?
幸运的是,Piral 对此有一个很好的解决方案:一个 App Shell模拟器。Pilet 可以使用模拟器查看集成到 App Shell 后的外观,以便快速调试 Pilet。
要创建应用程序外壳模拟器,请运行
piral build --type emulator
模拟器是一个.tar.gz
文件.tgz
(所谓的“tarball”),可以在/dist/emulator/
目录中找到。
太好了。现在我们有了一个文件。如果我们在一台电脑上单独创建 Pilet,这没什么大不了的。但理想情况下,我们希望每个 Pilet 都能访问模拟器,并且在需要新版本的 App Shell 时能够更新模拟器。这就是为什么发布模拟器是有意义的。
▸ 将模拟器包发布到 npm
如果您有使用 npm 的经验,这里有一个 TLDR:运行
npm publish dist/emulator/<emulator_file>
。
为了能够从任何地方访问模拟器,我们将使用 Node 包管理器,即 npm。首先,请访问npmjs.org,如果您还没有帐户,请创建一个。
接下来,在终端中运行
npm login
并使用您的用户名和密码登录。接下来,您可以运行
npm publish dist/emulator/<emulator_file>
<emulator_file>
在本例中,将为或类似的名称netflix-piral-1.0.0.tgz
。如果出现错误(可能意味着您选择的名称已被使用),请参阅本文或npm 文档。
如果你在 npmjs.org 上查看你注册的软件包,你应该能够看到已发布的模拟器软件包!这在下一阶段(即功能阶段)非常有用,我们将在此阶段处理 Pilet 的开发。
2. 功能阶段
这个阶段需要做什么?
- 构建并发布 Pilet 以启用应用程序中的功能。
- 管理关注点分离
- 将应用程序外壳功能提取到 Pilet 中
- 拆分较大的 Pilet 或合并较小的 Pilet
2.1 搭建桩基
创建 Pilet 非常简单。piral CLI 提供了一种基于 Piral 实例构建 Pilet 的简便方法。我们的工作流程如下:
mkdir browse
cd browse
pilet new netflix-piral
这将创建一个文件夹,并在其中browse
放置一个名为“browse”的新 pilet(基于 Piral 实例)。netflix-piral
browse
2.2 Pilet的第一个版本
让我们创建一些功能!这个应用的主页将是“浏览”页面。由于发现新剧集并让用户浏览剧集和电影是该应用相当重要的部分,因此这将由一个 Pilet 负责(因此,也需要一个单独的开发团队)。
Pilet 非常轻量。唯一需要查看的文件是index.tsx
,其中展示了一些 Piral API 的有趣示例:
设置功能是 Pilet 的核心。App Shell 将在这里查找集成指令。
我们不需要通知或磁贴。您可以阅读 Piral 文档,了解更多信息。
对我们来说最有趣的方法是registerMenu
,我们需要这个方法来用于“浏览”菜单项:
app.registerMenu(() => <Link to="/browse">Browse</Link>);
为了注册此菜单项可以链接到的页面,我们需要添加
app.registerPage('/browse', Browse);
Browse
目前,这只是一个常规的 React 组件。其结构看起来有点像这样:
Browse
├── Hero
├── Showcase
│ ├── MovieTile
│ └── ... #more movietiles
└── ... #more showcases with movietiles
▸ 单独调试 Pilet
当然,为了测试 Pilet 集成到 App Shell 后的效果,我们可以直接发布它,然后在网站上进行测试。不过,我无需解释为什么“在生产环境中测试”并非最佳方案。
因此,Piral 提供了一种调试 Pilet 的方法,这就是模拟器发挥作用的地方。要调试 Pilet,您可以运行
pilet debug
构建过程完成后,CLI 将告知您可以在哪个本地地址查看结果(通常是http://localhost:1234)。
有趣的是,这个命令与应用程序外壳的命令几乎相同,但是我们在那里使用了piral
关键字,而现在我们使用pilet
。
本节名为“单独调试 Pilet”,这似乎合乎逻辑,因为我们只定义了一个 Pilet。稍后,我将讨论一个很棒的功能,它使您可以调试包含多个 Pilet 的应用程序中的一个 Pilet。
▸ 发布 Pilet
我们已经发布了 piral 实例(应用程序外壳),使用 Piral 的有趣之处在于,这个应用程序外壳将从 feed 中提取每个 pilet 并将它们集成到客户端。
这意味着,要发布 Pilet,我们无需涉及部署工作。我们只需将 Pilet 发布到我们之前创建的 feed 即可。
我们可以通过以下方式实现这一点:
pilet publish --fresh --url <feed_url> ---api-key <feed_api_key>
提示:我将此代码片段保存为名为的脚本
publish.sh
,并将其添加到.gitignore
(因此我的 API 密钥不会在 Github 上),然后在我想要发布时运行该脚本。
该--fresh
标志确保在发布之前进行全新构建以包含上次构建后所做的任何更改。
如前所述,您可以在 piral feed 服务仪表盘中找到 feed url 和 API key。直接访问的 url 是:
https://www.piral.cloud/feeds/<feed_name>/api-keys
2.3profile
小柱
接下来,我们来处理一个更有趣的案例:profile
Pilet。这个 Pilet 会再次注册一个页面/profile
,但也会做一些其他的事情:它会注册一个组件扩展。
回顾应用程序外壳时,必须将此组件扩展放入扩展槽中header-items
。这就是我们要做的。
配置index.tsx
文件 pilet 将如下所示:
其中ProfileExtension
和ProfilePage
只是常规的 React 组件。
与组件扩展一样:应用程序外壳会将注册的扩展集成到正确的扩展中ExtensionSlot
(具有匹配名称的扩展)。
2.4favorites
小柱
这里我们开始遇到一件有趣的事情。我们想将收藏夹页面设计成一个页面,方便我们找到所有喜欢的电视剧或电影。这意味着很多事情:
- 就像在浏览组件中一样,我们需要一种显示媒体的方式(
MovieTile
) - 我们需要
FavoritesToggle
在每个按钮中提供一个按钮MovieTile
,以便能够将此项目切换为收藏项
▸MovieTile
关于代码重复的思考
我们可以直接从浏览组件复制代码MovieTile
并在这里复用。这是一个非常可行的策略,也是我在回顾提交历史时使用的方法。
– “不要重复自己”?–
虽然 DRY 原则确实可以在一个解决方案的范围内产生更清晰的代码,但它有时会限制应用程序所需的解耦。尤其是在微前端中,有时重复自己可能有用,而反过来往往更困难,也更不可取。这里有一篇有趣的文章可以阅读。
话虽如此,在项目后期,我回顾了 Piral 文档中的这一部分:
“确定何时分割 Pilet,并可能分割较大的 Pilet 或合并较小的 Pilet。”
从那时起,将它们提取MovieTiles
到单独的watch
Pilet 中并注册为组件扩展就变得有意义了。我将在下一节讨论监视 Pilet。
▸FavoritesToggle
我们将提供收藏夹按钮作为组件扩展,以便所有 Pilet 或应用程序外壳都可以将此按钮集成到他们想要的任何位置。
为此,我们需要在setup
收藏夹 pilet 函数中实现这一点:
app.registerExtension('ListToggle', props => <FavoriteToggle {...props.params}></FavoriteToggle>);
这就是将参数传递给组件扩展变得有趣的地方。一个非常基本的FavoriteToggle
组件可能如下所示:
(如果您想查看完整的代码,请检查github repo,为了简洁起见,我省略了一些内容)
对于此切换功能,按钮必须具有一些属性。使用收藏夹切换按钮可能如下所示:
<FavoritesToggle movieId="15165" media_type="tv" />
或类似的东西。所有这些介绍都引出了我们的主要问题:在跨 Pilet 使用组件扩展时,如何将参数传递给组件扩展?
嗯,很简单:Extensionslot
组件有一个属性params
。每当我们想要使用扩展时,我们都会将参数传递给插槽,piral 会将这些参数传递给最终位于该插槽中的扩展。这意味着,已注册的扩展将具有props.params
,该属性来自我们定义扩展插槽的位置。
如果我们想从其他 Pilet 使用这个组件扩展,扩展槽必须看起来像这样:
<ExtensionSlot name="ListToggle" params={/*an object with the params here*/}/>
我们将在下一节中看到有关此问题的示例和最佳实践:
2.5watch
小块
这个 pilet 会注册 2 件事:
- 我们
MovieTile
之前讨论过的。FavoritesToggle
这应该有一个适合我们的组件扩展的位置!
- (这
Player
只是一个简单的页面,我们不会进一步讨论)
▸ 电影方块
这是一个有趣的教训,我喜欢称之为extensionception:我们将注册一个组件扩展,但在该扩展中,我们将使用ExtensionSlot
另一个组件扩展适合的位置:
好的,我们来看一下MovieTile
组件:
此组件接受一系列属性,以便能够显示包含所有信息的影片图块。它是一个纯粹的展示性组件。
▸ 通过 props 传递扩展依赖项
在第 11 行,您可以看到MovieTileProps
还包含一个 React 组件引用的定义:这将是FavoritesToggle
我们之前定义的。
但为什么我们不直接放在<Extensionslot name="ListToggle"/>
那里呢?因为我在阅读Pilet扩展最佳实践时学到了一些东西。
使用其他 Pilet 提供的组件是通过“扩展”来实现的。问题在于,扩展需要集成 Pilet API 的扩展组件。
确实。我们需要在组件扩展文件的顶部执行此操作
import { ExtensionSlot } from 'piral';
这是一种不好的做法:我们将组件与 Pilet API 耦合,现在它们不再可重用、可测试和通用。
修复方法归结为:pilet 中唯一应该依赖于 Piral 框架的文件是index.tsx
包含该setup
函数的文件。从那里,我们可以传递所需的依赖项。对于MovieTile
s 来说,它看起来像这样:
在第 10 行,我们使用了app.Extension
,它的作用与 相同ExtensionSlot
。我们使用它的结果将一个组件传递给另一个组件。这样,MovieTile
就props.Toggle
定义了 ,并且可以像其他 React 组件一样使用它。
▸ 调试一个 Pilet 并观察与其他 Pilet 的交互
在开发browse
Pilet 时,我讨论调试的部分被称为“单独调试 Pilet”。现在,我们要做一些更强大的事情。
让我们回顾一下运行时会发生什么pilet debug
。我们有一个 App Shell 模拟器,Pilet 将集成在其中。就是这样——分为两部分:
- 应用程序外壳(模拟)
- 正在调试的 Pilet
但是如果我们也想查看已经发布的 Pilet,看看我们正在调试的 Pilet 如何融入其中呢?(主要是,在这种情况下,我们想看看扩展是如何集成的)
在撰写本文时,Piral CLI 仍处于 版本v0.12.4
,但我收到建议切换到v1.0.0
预览版本(@next
版本)。在我看来,此版本的 CLI 提供了一个重大的颠覆性功能:能够调试 Pilet,同时还能从源中包含远程 Pilet!
这也很容易做到:
pilet debug --feed <feed_url>
瞧!我们可以看到新的 Pilet 如何融入到 App Shell 以及 Feed 中已经定义的 Pilet 中!太棒了!
说实话,自从了解了这个功能后,我再也没有单独使用过调试功能。这样,当同时包含其他 Pilet 时,就能更容易地看到 Pilet 如何融入应用程序。
为了让我的生活更轻松,这就是我scripts
在每个 pilet 中的样子package.json
:
"scripts": {
//...
"debug": "pilet debug --feed <feed_url>"
},
这样,我就可以运行命令了npm run debug
!
2.6search
小柱
这个 Pilet 只注册了一个组件扩展。我们还将它设置为渲染到header-items
插槽中。这样,我们将在其中同时获取搜索和个人资料扩展。
3. 维护阶段
这主要是修复错误和进行优化。
持久状态
这与 Piral 无关,但我想通过本地存储来存储一些数据,并且我遇到了一种非常酷的方法,即使用这个自定义反应钩子来实现这一点。
延迟加载
在 Pilet 的设置函数中,我们可以将页面设置为延迟加载。这与 bundle splitting 相关:更多信息请点击此处。
例如
const ProfilePage = React.lazy(() => import('./components/ProfilePage'));
app.registerPage('/profile', ProfilePage);
更改应用程序外壳
如果在开发第一个 Pilet 之前花时间思考一下 App Shell 的职责,你就能省去很多麻烦。不过,App Shell 可能需要更新。当然,依赖 App Shell 模拟器进行调试的 Pilet 也需要更新!
幸运的是,这相当简单
- 应用程序外壳已更新、构建,并且更新已推送至 npm
- 在 Pilet 中,运行
pilet upgrade
以拉取最新版本的模拟器
最后的想法
虽然在做这个项目之前我没有任何使用 React 和 Piral 的经验,但我认为这个项目的结果非常好。
使用微前端时,最大的障碍是了解全局。对我来说,想象所有的微前端如何组合在一起真的很复杂。
▸ 学习概念的“黑箱方法”
我最近看了这段视频,印象非常深刻。理解复杂概念时,首先要把它们当成黑匣子,先学会如何使用,然后再学习它们的工作原理。
通过使用概念获得的经验将为您在学习其工作原理时带来巨大的优势,因为您已经了解了期望的结果。
我认为,理解微前端的关键在于亲手构建!一旦你直观地了解它们是如何组合在一起的,就更容易理解这种集成是如何进行的。这就是微前端框架的价值所在。它不仅能提供最佳的开发者体验,而且:很多功能都已为你完成,你可以轻松上手。
顺便说一句,这个比喻也很好地解释了我如何在短短一周内学会使用 React。我没有从零开始,而是对一个现有的项目进行了调整,这已经让我理解了很多概念。(当然,我使用 Angular 的经验也起了些作用)