Pit*_*sty 13 javascript typescript reactjs webpack
我试图在模块联合(webpack 5 功能)的帮助下在运行时获得一个动态系统。一切都很好,但是当我将钩子添加到“生产者”模块(主机应用程序从中动态导入组件的模块)时,我收到大量“无效的钩子规则”错误。
Warning: Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see [LINK RULES OF HOOKS]
Run Code Online (Sandbox Code Playgroud)
Warning: React has detected a change in the order of Hooks called by PluginHolder. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: [LINK RULES OF HOOKS]
Run Code Online (Sandbox Code Playgroud)
我已经使用了 externals 字段并在 html 文件中添加了 script 标签,我使用了共享选项来添加 singleton 字段: true 并指定了 React 和 React-dom 版本 每次控制台都会吐出大量错误
这是我直接从文档加载模块的方法
Warning: Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see [LINK RULES OF HOOKS]
Run Code Online (Sandbox Code Playgroud)
为了加载remoteEntry.js文件,我使用makeAsyncScriptLoader HOC和react-async-script,如下所示:
Warning: React has detected a change in the order of Hooks called by PluginHolder. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: [LINK RULES OF HOOKS]
Run Code Online (Sandbox Code Playgroud)
PluginHolder 是一个简单的组件,它包装了加载脚本中的加载模块(加载实际上已完成)
const loadComponent = (scope: string, module: string) => async (): Promise<any> => {
// @ts-ignore
await __webpack_init_sharing__('default');
// @ts-ignore
const container = window[scope];
// @ts-ignore
await container.init(__webpack_share_scopes__.default);
// @ts-ignore
const factory = await window[scope].get(module);
return factory();
};
Run Code Online (Sandbox Code Playgroud)
最重要的是开胃菜:
const withScript = (name: string, url: string) => {
const LoadingElement = () => {
return <div>Loading...</div>;
};
return () => {
const [scriptLoaded, setScriptLoaded] = useState<boolean>(false);
const AsyncScriptLoader = makeAsyncScriptLoader(url, {
globalName: name,
})(LoadingElement);
if (scriptLoaded) {
return <PluginHolder name={name}/>;
}
return (
<AsyncScriptLoader
asyncScriptOnLoad={() => {
setScriptLoaded(true);
}}
/>
);
};
};
Run Code Online (Sandbox Code Playgroud)
我不使用 React.Lazy 因为我无法使用 import()。更重要的是,在主机应用程序中,我在react和react-dom中设置了 field eager: true
我的 webpack.config.js (主机)如下:
useEffect((): void => {
(async () => {
const c = await loadComponent(name, './Plugin')();
setComponent(c.default);
})();
}, []);
return cloneElement(component);
Run Code Online (Sandbox Code Playgroud)
还有第二个模块中的 webpack.config.js:
const [plugins, setPlugins] = useState<PluginFunc[]>([]);
useEffect((): void => {
pluginNames.forEach(desc => {
const loaded = withScript(desc.name, desc.url);
setPlugins([...plugins, loaded]);
});
}, []);
Run Code Online (Sandbox Code Playgroud)
您对此有任何经验或任何线索吗?我认为重点是 2 个应用程序使用 2 个 React 实例,但这些是我的猜测。我的配置有问题吗?
确保将共享依赖项添加到 webpack.config 文件中。
请参阅下面的示例:
plugins: [
new ModuleFederationPlugin(
{
name: 'MFE1',
filename:
'remoteEntry.js',
exposes: {
'./Button':'./src/Button',
},
shared: { react: { singleton: true }, "react-dom": { singleton: true } },
}
),
new HtmlWebpackPlugin({
template:
'./public/index.html',
}),
],
};
Run Code Online (Sandbox Code Playgroud)
我使用此共享属性设置了主机和远程项目。当钩子破坏了我的主机应用程序时,为我修复了它。这是因为存在重复的react依赖项,无论版本是否相同,您都会收到此错误。
| 归档时间: |
|
| 查看次数: |
14904 次 |
| 最近记录: |