如何在多个库之间共享上下文?
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 行代码)的额外好处我的测试应用程序)。
我正在开发一个包含一系列前端库的 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 行代码)的额外好处我的测试应用程序)。