# Configuring single-spa

root config 的配置主要是用于启动微应用

# Index.html文件

内容可参考 该示例 (opens new window)。注意该文件不包含html元素(div, buttons等),只是为了调用registerApplication()方法。

有关根HTML文件的外观,请参见下面的[根配置示例]。

在使用 single-spa 时,不必使用 SystemJS,不过为了能够 独立部署 各应用,很多示例和教程会推荐使用 SystemJS

# 注册应用

注册应用的办法我们在介绍工具的部分其实已经讲过了,这里直接附上官方代码片段,回忆一下即可:

// single-spa-config.js
import { registerApplication, start } from 'single-spa';
// Simple usage
registerApplication(
  'app2',
  () => import('src/app2/main.js'),
  (location) => location.pathname.startsWith('/app2'),
  { some: 'value' }
);
// Config with more expressive API
registerApplication({
  name: 'app1',
  app: () => import('src/app1/main.js'),
  activeWhen: '/app1',
  customProps: {
    some: 'value',
  }
);
start();

# 参数

# name

registerApplication 的第一个参数表示应用名称,name 必须是 string 类型

# 加载函数或应用

registerApplication 可以是一个 Promise 类型的加载函数,也可以是一个已经被解析的应用(Application)

# 应用作为第二个参数

你可以选择将一个已经被解析过的应用作为 registerApplication 的第二个参数,这个应用其实是一个包含各个生命周期函数的对象。我们既可以从另外一个文件中引入该对象,也可以在 single-spa 的配置文件中定义这个对象。

const application = {
  bootstrap: () => Promise.resolve(), //bootstrap function
  mount: () => Promise.resolve(), //mount function
  unmount: () => Promise.resolve(), //unmount function
}
registerApplication('applicationName', application, activityFunction)

# 加载函数

registerApplication 的第二个参数必须是返回 promise 的函数(或"async function"方法)。这个函数没有入参,会在应用第一次被下载时调用。返回的 Promise resolve 之后的结果必须是一个可以被解析的应用。常见的实现方法是使用 import 加载:

() => import('/path/to/application.js')

# 激活函数

registerApplication 的第三个参数需要是一个纯函数,window.location 会作为第一个参数被调用,当函数返回的值为 true 时,应用会被激活。通常情况下,Activity function 会根据 window.location 后面的 path 来决定该应用是否需要被激活

另外一种场景是 single-spa 根据顶级路由查找应用,而每个应用会处理自身的子路由。 在以下场景,single-spa 会调用应用的 activity function

在以下情况下,single-spa将调用每个应用的活动函数:

  • hashchange or popstate 事件触发时
  • pushState or replaceState 被调用时
  • single-spa 上手动调用 triggerAppChange 方法
  • checkActivityFunctions 方法被调用时

# 自定义属性

registerApplication 的第四个可选参数是自定义属性,这些属性传递给应用程序的 single-spa 生命周期函数。 自定义道具可以是对象,也可以是返回对象的函数。 使用应用程序名称和当前 window.location 作为参数调用自定义属性函数。

# 使用对象作为参数

singleSpa.registerApplication({
  name: 'myApp',
  app: () => import('src/myApp/main.js'),
  activeWhen: ['/myApp', (location) => location.pathname.startsWith('/some/other/path')],
  customProps: {
    some: 'value',
  },
});
singleSpa.registerApplication({
  name: 'myApp',
  app: () => import('src/myApp/main.js'),
  activeWhen: ['/myApp', (location) => location.pathname.startsWith('/some/other/path')],
  customProps: (name, location) => ({
    some: 'value',
  }),
});

# config.name

必须是字符串。

# config.app

应用的定义,它可以是一个单spa生命周期的对象,加载函数或者与第二个参数相同。

# config.activeWhen

可以是激活函数,比如参数API、路径前缀或两者的数组。因为最常见的用例是使用window.location 将其URL前缀进行匹配,所以我们帮你实现了这个方法。

# Path prefix

路径前缀会匹配url,允许以下每一种前缀:

'/app1'

  • ✅ app.com/app1
  • ✅ app.com/app1/anything/everything
  • 🚫 app.com/app2

'/users/:userId/profile'

  • ✅ app.com/users/123/profile
  • ✅ app.com/users/123/profile/sub-profile/
  • 🚫 app.com/users//profile/sub-profile/
  • 🚫 app.com/users/profile/sub-profile/

'/pathname/#/hash'

  • ✅ app.com/pathname/#/hash
  • ✅ app.com/pathname/#/hash/route/nested
  • 🚫 app.com/pathname#/hash/route/nested
  • 🚫 app.com/pathname#/another-hash

['/pathname/#/hash', '/app1']

  • ✅ app.com/pathname/#/hash/route/nested
  • ✅ app.com/app1/anything/everything
  • 🚫 app.com/pathname/app1
  • 🚫 app.com/app2

# config.customProps

可选自定义属性提供传递给应用程序的 single-spa 生命周期功能的自定义属性。 自定义属性可以是对象,也可以是返回对象的函数。 使用应用程序名称和当前 window.location 作为参数调用自定义属性函数

# Calling singleSpa.start()

start()`方法 **必须** 被 `single-spa` 配置文件的js调用,这时应用才会被真正挂载。在 `start` 被调用之前,应用先被下载,但不会初始化/挂载/卸载。`start` 方法可以协助我们更好提升应用的性能。举个例子,我们可能会马上注册一个应用(为了立刻下载代码),但不能马上就在DOM节点上挂载该应用,而是需要等一个AJAX请求(可能会获取用户的登录信息)完成后,再根据结果进行挂载。这种情况下,最佳实践是先调用 `registerApplication`,等 `AJAX` 请求完成后再调用 `start
//single-spa-config.js
import { start } from 'single-spa';
 /*在注册应用之前调用start意味着single-spa可以立即安装应用,无需等待单页应用的任何初始设置。*/
start();
// 注册应用。。。。

# 同时注册两个路由

实现此目的的一种方法是为每个应用程序创建一个<div>,这样它们就永远不会尝试同时修改同一DOM。

将需要一个以前缀single-spa-application:开头的id,然后是您的应用程序名称。 例如,如果您有一个名为 app-name 的应用程序,则可以使用id single-spa-application:app-name 创建一个。

具有多个应用程序的示例如下所示:

<div id="single-spa-application:app-name"></div>
<div id="single-spa-application:other-app"></div>
阅读全文