如何在多个库之间共享上下文?
Posted
技术标签:
【中文标题】如何在多个库之间共享上下文?【英文标题】:How to share context between multiple libraries? 【发布时间】:2022-01-01 16:17:29 【问题描述】:我正在开发一个包含一组前端库的 monorepo,并希望在另一个库中使用一个库中的上下文,这两个库都将在同一个应用程序中使用。
例如,我们有库“a”,其中包含一些组件使用的上下文ContextA
(称为其中一个<ComponentA>
),库“b”中的一些组件使用ContextA
也可以(致电其中一位<ComponentB>
)。
在应用程序中,库“b”中的组件无法找到ContextA
的提供程序。我相信这是因为在构建和缩小库时,ContextA
的最终变量名称在每个构建文件中都不同。不过我可能错了,它也可能与范围界定有关。
有没有办法在两个库之间共享上下文?
如果问题只是缩小,有没有办法控制上下文的最终名称,以便它们在库中保持相同? (顺便使用 rollup 和 babel 插件)
其他信息:
我的幼稚方法只是在应用程序中使用ContextA
的提供程序,<ComponentA>
和<ComponentB>
都可以使用。
例如(在应用程序中):
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,它似乎是关于从应用程序中的库创建上下文提供程序(仅处理一个库)。
【问题讨论】:
【参考方案1】:在 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 行代码应用程序)。
【讨论】:
以上是关于如何在多个库之间共享上下文?的主要内容,如果未能解决你的问题,请参考以下文章