如何在多个库之间共享上下文?

How to share context between multiple libraries?

我正在开发一个包含一系列前端库的 monorepo,并希望在另一个库中使用一个库中的上下文,这两个库都将在同一个应用程序中使用。

例如,我们有库“a”,其中包含一些组件(调用其中一个<ComponentA>)使用的上下文ContextA,以及库“中的一些组件” b" 也使用 ContextA(调用其中之一 <ComponentB>)。

在应用程序中,库“b”中的组件无法找到 ContextA 的提供程序。我相信这是因为在构建和缩小库时,ContextA 的最终变量名称在每个构建文件中都是不同的。不过我可能是错的,它也可能与范围界定有关。

有没有办法在两个库之间共享上下文?

如果问题只是缩小,有没有办法控制上下文的最终名称,以便它们在库中保持相同? (顺便使用 rollup 和 babel 插件)


附加信息:

我天真的方法只是在 <ComponentA><ComponentB> 都可以使用的应用程序中为 ContextA 使用提供程序。

例如(在应用中):

function App() {
    return (
        <ContextA.Provider value={100}>
            <ComponentA/>
            <ComponentB/>
        </ContextA.Provider>
    )
}

但是,如上所述,我发现库“b”中的组件无法找到 ContextA 的提供程序。

所以我转向了一种使用依赖上下文管理器的新方法,它只接收上下文值并在库“b”中呈现该上下文的提供者,以便库“b”中的组件可以找到上下文。像这样(在申请中):

function App() {
    return (
        <ContextA.Provider value={100}>
            <BContextManager>
                <ComponentA/>
                <ComponentB/>
            </BContextManager>
        </ContextA.Provider>
    )
}

function BContextManager({children}) {
    const contextValue = React.useContext(ContextA);
    return (
        <DependentContextManagerB contextValue={contextValue}>
            {children}
        </DependentContextManagerB>
    )
}

其中 <DependentContextManagerB> 看起来像这样(在库“b”中定义):

function DependentContextManagerB({contextValue, children}) {
    return (
        <ContextA.Provider value={contextValue}>
            {children}
        </ContextA.Provider>
    )
}

如果有点笨拙,此方法适用于全局上下文(整个应用程序只有一个提供程序的上下文)。然而,这种方法过于笨重,无法在更多本地上下文中使用(应用程序中可能有许多提供程序的上下文)。


我看过this question,这似乎是关于为应用程序中的库创建上下文的提供程序(仅处理一个库)。

在 React 的问题页面上找到相关问题:Bug: React Context API is not working from custom NPM library

解决方案是将“b”对“a”的依赖移动到对等依赖(同样的方式通常包含 React,因此只有一个 React 实例存在)。

所以如果 b/package.json 看起来像这样:

{
    "name": "b",
    "dependencies": {
        "a": "^0.0.0"
    }
}

更新为:

{
    "name": "b",
    "peerDependencies": {
        "a": "^0.0.0"
    }
}

这有减少库“b”的包大小(在我的例子中相当显着:减少 12%)和应用程序的最终构建大小(不太显着但基本上有 30 行代码)的额外好处我的测试应用程序)。