资讯详情

webpack 5 如何用 require.resolve 获取模块 ID 并清除 require.cache 强制模块重新执行

📅 2026/9/11 4:46:20 | 华诺云谱 👁 阅读
webpack 5 如何用 require.resolve 获取模块 ID 并清除 require.cache 强制模块重新执行
webpack 5 如何用 require.resolve 获取模块 ID 并清除 require.cache 强制模块重新执行【免费下载链接】webpackA bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through loaders, modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff.项目地址: https://gitcode.com/GitHub_Trending/web/webpackWebpack 在打包后会把每个模块的执行结果缓存在运行时第一次require执行模块代码之后的require直接返回缓存实例模块体不会再运行。如果需要让某个模块在运行时真正重新执行一遍例如让它的导出值重新生成可以用require.resolve拿到该模块在 webpack 运行时中的模块 ID再从require.cache里删掉对应条目。webpack 5 仓库自带一个完整可运行的示例 examples/require.resolve演示了这个操作并内置了结果校验本文按这个示例走一遍。示例的两个源文件a.js导出一个随机数保证两次执行的结果必然不同用来区分“命中缓存”和“真的重新执行”module.exports Math.random();入口文件example.js是核心操作所在完整文件见 examples/require.resolve/example.jsvar a require(./a); // get module id var aId require.resolve(./a.js); // clear module in require.cache delete require.cache[aId]; // require module again, it should be reexecuted var a2 require(./a); // verify it if(a a2) throw new Error(Cache clear failed :();逐行拆开看require.resolve(./a.js)返回./a在 webpack 包内的模块 IDdelete require.cache[aId]删除该模块已缓存的执行结果第二次require(./a)不再命中缓存webpack 会重新执行模块函数如果a和a2是同一个引用说明缓存没被清掉代码抛出Cache clear failed :(。编译先在项目里安装 webpack安装命令来自仓库 READMEnpm install --save-dev webpack或使用 yarnyarn add webpack --dev然后写一个构建脚本。仓库的示例测试 test/Examples.test.js 就是用 webpack 的 Node API 编译这个示例的入口为./example.js产物输出到dist。照这个方式可以写一个build.jsconst path require(path); const webpack require(webpack); webpack({ context: __dirname, mode: production, entry: ./example.js, output: { path: path.join(__dirname, dist), filename: output.js } }, (err, stats) { if (err) { console.error(err); process.exit(1); } console.log(stats.toString()); });把build.js、example.js、a.js放在同一目录执行node build.js示例 README 记录的编译输出文档示例结果asset output.js 317 bytes [emitted] [minimized] (name: main) chunk (runtime: main) output.js (main) 313 bytes [entry] [rendered] ./example.js main dependent modules 31 bytes [dependent] 1 module ./example.js 282 bytes [built] [code generated] [no exports used] entry ./example.js main webpack X.X.X compiled successfullyREADME 中另记录了一份未优化Unoptimized编译的输出为 2.41 KiB同为文档示例结果。验证重新执行是否生效分两层验证。第一层用 Node 直接运行产物node dist/output.js这个包本身不打印任何东西。只要a和a2不是同一引用脚本静默跑完、无报错如果缓存清除失败会抛出未捕获的Error: Cache clear failed :(。第二层打开dist/output.js检查源码到运行时代码的转换摘录自 README 中的编译产物var a __webpack_require__(/*! ./a */ 1); // get module id var aId /*require.resolve*/(/*! ./a.js */ 1); // clear module in require.cache delete __webpack_require__.c[aId]; // require module again, it should be reexecuted var a2 __webpack_require__(/*! ./a */ 1); // verify it if(a a2) throw new Error(Cache clear failed :();可以看到三处转换require(./a)变成__webpack_require__(1)参数就是模块 IDrequire.resolve(./a.js)在编译期被直接替换成字面量 ID1require.cache被映射到运行时缓存对象__webpack_require__.c。webpack 运行时通过__webpack_require__.c暴露模块缓存摘自 README 中的 runtime 代码// The module cache const __webpack_module_cache__ {}; // The require function function __webpack_require__(moduleId) { // Check if module is in cache const cachedModule __webpack_module_cache__[moduleId]; if (cachedModule ! undefined) { return cachedModule.exports; } // Create a new module (and put it into the cache) const module __webpack_module_cache__[moduleId] { id: moduleId, loaded: false, exports: {} }; // Execute the module function __webpack_modules__moduleId; // Flag the module as loaded module.loaded true; // Return the exports of the module return module.exports; } // expose the module cache __webpack_require__.c __webpack_module_cache__;__webpack_require__先查__webpack_module_cache__[moduleId]命中就直接返回缓存的 exports只有未命中才创建模块并执行。因此把缓存条目删掉后第二次require必然重新执行模块函数Math.random()返回新的值两次导出不相等。使用时的注意点打包后require.resolve返回的是 webpack 的模块 ID本示例中是数字1不是 Node 环境里require.resolve返回的文件系统路径两者语义不同。本示例的a.js是 CommonJS 模块直接使用module.exports编译产物中带有CommonJS bailout: module.exports is used directly标记。产物启动段带有注释 module cache are used so entry inlining is disabled因为运行时用到了模块缓存入口内联被禁用入口模块以普通模块身份加载本示例中模块 ID 为 0。相关源文件示例说明与编译产物对照examples/require.resolve/README.md入口示例代码examples/require.resolve/example.js被重新执行的模块examples/require.resolve/a.js示例的编译入口webpack Node API 用法参照test/Examples.test.js【免费下载链接】webpackA bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through loaders, modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff.项目地址: https://gitcode.com/GitHub_Trending/web/webpack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。