在this answer之后的问题Is it possible to import modules from all files in a directory, using a wildcard?中,我能够在一个声明中导入多个模块,并像这样导出它们:
/hooks/index.ts
部分
export { default as useSections } from './useSections';
export { default as useArtworkEvents } from './useArtworkEvents';
export { default as useEventBusListener } from './useEventBusListener';
然后将它们导入到一个组件中,如下所示:
Packaging.tsx
部分
import { useSections, useArtworkEvents, useEventBusListener } from 'src/hooks';
我在另一个没有问题的项目中做了同样的事情,但是这里我从模块中导入了大型库,所有这些库都进入了vendor文件夹。
库的导入方式如下:
其中一个钩子的示例
import { autorun, IReactionDisposer } from 'mobx';
// body of the module
// and the export in the end
export default useArtworkEvents;
而这就是目前的情况:
它看起来像是导入其中一个文件的第一个地方(假设是App.tsx
)是加载所有库的地方,即使只有一个应该被导入(在我的意图中)。
我想补充的是,即使使用库的组件是通过React Suspense动态加载的,这种情况也会发生:
示例来自App.tsx
const PackagingComponent = lazy(
() => import('src/components/PackagingComponent' /* webpackChunkName: "packaging" */)
);
然后呢
<ErrorBoundary locale={props.locale}>
<Suspense fallback={<Loader />}>
{props.componentType === AcceptedComponentTypes.PACKAGING && (
<DesignStackPackaging
locale={props.locale}
tenant={props.tenant}
/>
)}
{/* ...other conditions */}
</Suspense>
</ErrorBoundary>
解决方案?
如果我删除索引文件中的导出(项目中有两个,一个用于普通脚本,另一个用于钩子)并直接导入模块,问题就会消失。
/hooks/index.ts
部分
export {};
Packaging.tsx
部分
import useSections from 'src/hooks/useSections';
import useArtworkEvents from 'src/hooks/useArtworkEvents';
import useEventBusListener from 'src/hooks/useEventBusListener';
你可以看到这个问题似乎已经解决了:
所以我有两个要求
1.有人知道为什么会这样吗?
1.有没有更方便的方法来公开模块(而不用为每个新导入添加新行)?
我想也许我可以把所有导入大型库的模块放在一个单独的文件夹中,在那里我不使用索引文件导出它们,同时将较小的模块保存在一些常用的文件夹中,在那里我使用索引文件导出它们,但我不喜欢这个解决方案,因为它感觉不一致,并且不知道的同事可能会收回这个问题。
对于上下文,我还添加了Webpack Split Chunks配置:
splitChunks: {
chunks: 'all',
name: true,
},
(BTW如果name
被设置为false
,则发生相同的情况)。
1条答案
按热度按时间wfsdck301#
所以,在发布问题后,我在相关部分找到了另一个问题:Barrel file and Tree Shaking,这让我明白了我所指的
index
文件有一个名称,即桶文件,并且有各种关于该主题的文章。例如,This article建议不要使用桶文件,因为它们会产生树抖动问题。
幸运的是,我找到了this Github issue(在Next.js存储库中),其中包含我的特定问题的解决方案。
解决方法是关闭桶文件的副作用,这样Webpack就不会在每次需要单个模块时加载整个文件夹。
因此,在我的例子中,Webpack配置的相关部分变为:
其他一切都保持不变。
最后,我想引用同一个用户的一部分回复,给出了解决方案:
Barrel文件实际上是一个API。区分私有代码和公共代码的特定接口。这在带有本地包的monorepo中尤其有意义。同样的概念(为什么包有一个特定的导入接口)利弊适用于monorepo包。
所以最后我很感激我能够保留桶文件,而不必单独导入每个模块。