跳到主要内容
版本:5.x

常见问题

single-spa做了什么?

single-spa是一个顶层路由。当路由处于活动状态时,它将下载并执行该路由的相关代码。

路由的代码被称为应用,每个代码都可以(可选)拥有自己的git仓库、CI进程,并且可以独立部署。这些应用即可以用相同框架实现,也可以用不同框架实现。

有没有推荐设置?

当然,请查看相关设置文档

我应该有一个根应用和子应用吗?

不。我们强烈推荐你的single-spa-config或根应用不要使用任何js的ui-frameworks(如:React,Angular,Angularjs,Vue等等)。根据我们的经验,简单的js模块最合适single-spa-config,并且只有已注册的应用程序世纪使用ui-frameworks框架(如:angular, react, vue, etc等)。

为什么?你最终创建的结构具有微服务的所有缺点,并没有任何优点:你的应用相互耦合,并且同时更改多个应用程序才能进行更新。

对性能有什么影响?

当按照推荐方式进行配置时,您的代码性能和包的大小将与已被拆分的单个应用程序基本相同。主要区别在于添加single-spa库(如果你选择使用SystemJS)。其他差别主要归结为一个(webpack/rollup等等)的代码包和浏览器内ES模块之间的差异。

我可以只加载一个版本(React, Vue, Angular等等)吗?

是的,并且非常推荐你这样做。使用推荐设置,你可以配置导入映射,以便你的库只定义一次。然后,通知每个应用程序not绑定该库;反之,该库将在运行时在浏览器中提供给你。请参见webpack外部工具(其他的包也有相似选项)。

你可以选择not排除那些库(例如你想尝试使用较新的版本或其他库),但请注意这将对用户的包大小和应用程序速度的产生影响。

重要的映射有什么?

导入映射通过允许开发者能够编写类似import React from "react"语法,而不需要通过绝对或者相对路径来引入。同样从其他single-spa应用中导入也是如此,如: import {MyButton} from "styleguide"。import-map规范目前正在被接受成为新的web标准,在编写本文时已经实现,并且通过SystemJS >= 3.0已经实现了浏览器(>=IE11)的polyfill。参考[the recommended setup](#is-there-a-recommended-setup)。

如何在应用程序间共享状态?

通常,我们建议尽量避免这种情况-它将会将这些应用结合在一起。如果你发现需要经常共享两个应用的状态,你可以考虑将这些单独的应用划分成一个应用。

一般来说,最好根据每个应用所需的数据发送api请求,尽管其中的一部分已经被其他应用请求过。实际上,如果你正确的设计了应用的边界,那么最终只有很少的应用状态是真正共享的。例如,你的好友列表的数据需求与你的社交需要不同。

然而,那不意味着不能做到。以下是几种方法:

  1. 创建可以缓存请求及其响应的共享API请求库。如果同一个AIP被多个应用重复命中,则使用缓存数据。
  2. 将共享状态公开为导出,其他的库可以导入它。可观测值(如:RxJS) 在这里很有用,因为他们能够将新值流式传输给订阅服务器。
  3. 使用custom browser events来交流。
  4. 使用cookieslocal/session storage或其他能够存取状态的工具。这些方法最适用于不经常改变的内容,例如登陆的用户信息。

请注意,这里只是在讨论共享应用程序状态:共享函数,组件等,就想一个项目中"导出"和另一个项目中的"导入"一样简单。有关详细信息,请参阅import map

我应该使用前端微服务吗?

如果你曾遇到过单一服务引发的问题,你就要考虑使用微服务了。

另外,如果你的结构是在Spotify类型的模型中设置的(例如:拥有完整堆栈功能的自治小队),那么前端的微服务将非常适合你的设置。

然而,如果你刚开始有一个小项目或一个小团队,建议暂时不实用微服务。当到你的项目扩展(如:结构扩展、功能扩展等)变得困难时,别担心,我们会在这里帮你迁移的。

我能使用多个框架吗?

是的。然而,这是你需要认证考虑的问题,因为他将在你的前端结构中分成了不兼容的专业领域(如:React专家可能在使用Angular应用时遇到问题),而且还会导致更多的代码被发送给用户。

然而,它非常适合从旧的或者不需要的库中迁移,这样就可以慢慢的从旧应用中删除代码,并在新库中替换成新的代码(请参见the strangler pattern

这也是一种允许大型项目在不同库上进行实验,而无需要对他们做出强烈承诺的一种方式。

只要意识到它对你的用户即他们使用应用时的体验的影响。

开发人员的体验是怎么样的?

如果你使用recommended setup安装single-spa,你只需要在你的开发环境下,添加指向本地运行代码的导入映射,并刷新页面即可。

你可以在开发中使用library,或者你可以自己实现-你会注意到源码非常的简单。主要的收获是,你可以拥有多个import maps,并且最后的一个会被应用-可以通过添加import map来覆盖应用指向本地localhost的默认url。

我们还打算将该功能作为Chrome/Firefox browser extension的一部分来提供。

最后,此设置还允许你在生产环境中执行覆盖。显然,需要谨慎使用,但是它确实提供了一种强大的调试问题和验证解决方案的方法。

作为参考,几乎所有与我们合作过的开发者都更喜欢微服务+single-spa的开发体验,而不是单一的设置。

每个single-spa应用可以拥有自己的git仓库吗?

当然!你甚至可以为他们提供自己的package.json,webpack配置文件,CI/CD进程,使用SystemJS在浏览器中将他们组合在一起。

single-spa应用可以独立部署吗?

是的!详见下一节有关CI/CD的文档。

CI/CD的流程是什么样子的?

换句话说就是,如何打包部署一个single-spa应用?

使用recommended setup,流程如下:

  1. 打包你的代码并上传至CDN。
  2. 更新开发环境的导入映射,指向新的URL。换句话说,你的导入映射由"styleguide": "cdn.com/styleguide/v1.js"更新为"styleguide": "cdn.com/styleguide/v2.js"

"如何更新导入映射"上的一些选项:

  • 服务器通过导入映射渲染index.html。这不意味这你的所有的DOM元素都需要服务器渲染,但是只要使用<script type="systemjs-importmap>元素, 可以提供更新数据库或服务器的本地文件的API。
  • 将导入映射放在CDN上,并且使用 import-map-deployer 或类似于在CI过程中更新导入映射。这种方法对性能影响很小,如果你没有设置服务端渲染,则通常更容易设置。(你也可以preload导入映射文件来提升速度)。详情见 example travis.yml。其他的CI工具也可以工作。

创建React应用

当前创建React应用(CRA)需要引入ejecting 或者 using a tool 来修改webpack的配置。你也可以考虑一些popular alternatives to CRA

当你使用recommended setup时,需要更改以下内容(从CRA v3.0.1开始):

  1. 移除Webpack optimizations,因为它们添加了多个互不加载的Webpack包。
  2. 移除html-webpack插件。
  3. 修改output.libraryTargetSystem, UMD, 或 AMD

CRA不允许你在弹出或使用其他工具情况下修改上述文件。

代码拆分

Single spa支持代码拆分。代码拆分的方法有很多,我们无法一一涵盖,但是如果你在webpack中使用recommended setup,你至少要做以下两件事:

  1. 设置动态__webpack_public_path__,以便webpack知道从何处获取代码片段(webpack假设他们位于服务器的根目录,在single-spa应用中并不是这样的)。下面的两个解决方案,你的项目应该优先导入,保证项目运行。

    import { setPublicPath } from 'systemjs-webpack-interop';

    setPublicPath('name-of-module-in-import-map');
    • For SystemJS 2-5: Find a code example here
  2. 设置output.jsonpFunctionoutput.library,以确保每个应用的webpack不会和其他的应用冲突。jsonpFunction是首选。

有关webpack配置和single-spa更多信息,详见the recommended setup

single spa是否需要额外的安全考虑?

不需要。single spa不会添加、偏离或试图绕过任何浏览器有关JavaScript的安全措施。应用程序的安全需求与不实用single spa时相同。

除此之外,web应用可能会使用以下资源,这些资源拥有自己的安全考虑,你或许要熟悉这些资源:

single spa 如何写测试用例?

请参阅有关单元测试E2E测试的文档。