Vite模块加载顺序问题:enableMapSet调用晚于immer默认导入
解决Vite React中Immer MapSet插件加载时机过晚的问题
问题核心
你的项目里immer是@lauf/store-edit的peer依赖,Vite的模块解析机制会提前处理@lauf/store-edit的导入,导致immer在你调用enableMapSet()之前就已经被加载初始化,从而触发插件未加载的报错。
可行解决方案
方案1:拆分初始化脚本,强制优先加载
- 在
src目录下创建单独的初始化文件immer-init.ts,只处理Immer的插件启用:
import { enableMapSet } from "immer"; enableMapSet();
- 修改项目根目录的
index.html,把这个初始化脚本放在React入口脚本之前:
<!-- 先加载Immer初始化脚本 --> <script type="module" src="/src/immer-init.ts"></script> <!-- 再加载应用入口 --> <script type="module" src="/src/main.tsx"></script>
浏览器会按顺序执行模块脚本,确保enableMapSet()在任何依赖Immer的代码加载前完成执行。
方案2:在入口文件中动态加载应用核心代码
如果不想修改index.html,可以在main.tsx里先执行Immer初始化,再动态导入依赖Immer的应用代码:
import React from "react"; import ReactDOM from "react-dom/client"; import { enableMapSet } from "immer"; // 先启用Immer插件 enableMapSet(); // 动态导入应用核心组件,确保Immer配置完成后再加载依赖 import("./App").then(({ default: App }) => { ReactDOM.createRoot(document.getElementById("root")!).render( <React.StrictMode> <App /> </React.StrictMode> ); });
然后把所有依赖@lauf/store-edit的代码移到App.tsx或其子组件中,这样这些依赖会在动态导入时才被加载,此时Immer的插件已经启用。
为什么之前的modulePreload配置无效?
你修改的build.modulePreload.resolveDependencies只控制生产构建时的预加载依赖列表,但Vite在解析入口文件时,依然会提前处理@lauf/store-edit的静态导入,导致Immer被提前初始化,所以这个配置无法解决加载顺序问题。
内容的提问来源于stack exchange,提问作者cefn
相关产品推荐
相关产品推荐

