6

我们的平台建立在带有 Web 组件的微前端架构上。我们对其中一些使用 Stencil,这意味着我们在一个网页中有多个 Stencil 应用程序。此外,我们还有一个 UI 库,也是用 Stencil 构建的,我们希望在这些微前端组件中使用它。

我们想使用 Stencil UI 库作为 Stencil 微前端组件的构建时依赖项。但是由于标签名称冲突,这目前是不可能的:

理论上,两个微前端可以发布两个不同版本的 UI 库。但是,在运行时,它们会发生冲突,因为它们都试图用customElements.define. 当然,这不会发生,因为 Stencil 在注册新名称之前会检查现有名称 - 但结果同样糟糕:第一个加载的组件总是获胜,如果它是旧版本或具有不同的 API,其他组件会破裂。

一个解决方案是在构建或运行时命名空间/为标签名称添加前缀,但网络标准中没有任何内容(尚未)。虽然namespaceStencil 中有一个配置选项,但这似乎并不能解决此类问题。

使用纯 ES6,我们至少可以做到以下几点(即注册一个带有动态标签名称的自定义元素):

export class InnerComponent extends HTMLElement
{
    static register(prefix) {
        customElements.define(`my-${prefix}-inner-component`, InnerComponent)
    }

    constructor() {
        super()
        this.shadow = this.attachShadow({ mode: "open" })
    }

    connectedCallback() {
        this.shadow.innerHTML = `<span>this is some UI component</span>`
    }
}

而且我确信我们可以使用某种构建时解决方案和 Webpack 等来实现相同的目标。

但是 Stencil 是否有类似的可能?或者还有什么办法可以解决这个问题?

4

2 回答 2

2

我们面临着类似的问题。我们的解决方案是避免捆绑依赖项并将它们部署为单独的库。所以如果A和B都依赖C,那么A和B都没有C组件,C作为自己的脚本资源包含在前端。

于 2020-01-17T15:13:31.673 回答
2

Stencil 提供tagNameTransform配置以支持在运行时重命名标签名称。默认情况下,其值为 false,请确保将其设置为 true。

此功能有助于我们在微前端架构中使用模板可重用组件,因为每个消费微前端都可以为标记名提供自己的唯一名称,这解决了在微前端平台中使用相同模板可重用组件的多个版本的问题。

将以下配置添加到您的模板配置文件 -

config.extras.tagNameTransform: true

并且在消费微前端确保使用下面的代码覆盖标记名 -

import { defineCustomElements } from '@yourcomponent/libraryname/dist/loader';
...
defineCustomElements(window, { transformTagName: tagName => `unique-prefix-${tagName}` });

注意:如果您stencil-ds-output-targets用于为模板组件创建包装器,则尚未提供对重命名的支持。相同的 PR 仍在等待中 - https://github.com/ionic-team/stencil-ds-output-targets/pull/59。在支持该功能之前可能的解决方法 - 尝试从消费微前端模拟包装器的创建。例如 -

import { JSX } from '@yourcomponent/libraryname';
import { createReactComponent } from '@yourcomponent/libraryname/<react-wrapper>/dist/react-component-lib'; 

const TextBox = createReactComponent('unique-prefix-<tagName>')

// Use this new TextBox component while rendering rather than from stencil wrapper directly
class YourComponent = () => {
    return <TextBox />
}
于 2021-03-27T01:04:44.810 回答