首页 文章 精选 留言 我的

精选列表

搜索[Node.js],共4438篇文章
优秀的个人博客,低调大师

Node.js 中 require 和 import 混用导致的循环依赖问题排查

在一个维护中的 Express 项目里,最近加了一个新的业务模块,启动时偶尔报 `TypeError: Cannot read properties of undefined`,刷新页面有时正常有时挂掉。看堆栈指向一个工具函数文件,但单独跑这个文件没问题。这个项目历史比较久,代码里有些文件用 `require` 加载依赖,有些新写的文件用 `import`,tsconfig 虽然开了 esModuleInterop,但并没有统一模块格式。Node 在 CommonJS 和 ESM 混用时,循环依赖的解析顺序会变得很不直观:`require` 拿到的是未完成的 `module.exports`,而 `import` 的绑定提升又会让某些变量在初始化前被访问。这篇文章从实际报错出发,梳理循环依赖在两种模块系统下的表现差异,说明 Node 的模块加载时序如何影响导出对象的赋值,并给出几种在不改动整体架构的前提下定位和规避这类问题的做法。 先看一个能复现问题的最小结构。项目里有三个文件:`config.js` 负责导出配置对象,`logger.js` 依赖 config 并导出日志方法,`app.js` 又同时依赖两者。 ```js // config.js const logger = require('./logger'); const config = { env: process.env.NODE_ENV || 'development', logLevel: 'info' }; logger.init(config); module.exports = config; ``` ```js // logger.js const config = require('./config'); let currentConfig = null; function init(cfg) { currentConfig = cfg; } function log(msg) { console.log(`[${currentConfig ? currentConfig.logLevel : 'unknown'}]`, msg); } module.exports = { init, log }; ``` `app.js` 只要先引 logger 再引 config,就会出问题。Node 的 CommonJS 加载流程是:遇到 `require('./logger')` 时开始执行 logger.js,logger 内部 `require('./config')` 会去加载 config.js,config 内部又 `require('./logger')`,此时 logger 在缓存里但 `module.exports` 还是初始的空对象,于是 config 拿到的 logger 是 `{}`,调用 `logger.init` 直接报错。如果 app.js 先引 config,同样的环依然存在,只是报错位置换到 config 里。 改一下加载顺序能绕过,但这不是可靠做法,因为入口文件多了以后顺序很难保证。更实际的方式是在出现环的地方延迟加载: ```js // config.js let logger = null; function getLogger() { if (!logger) { logger = require('./logger'); } return logger; } const config = { env: process.env.NODE_ENV || 'development', logLevel: 'info' }; getLogger().init(config); module.exports = config; ``` 把 `require` 挪到函数内部,保证 config 导出对象已经构建完成后再去取 logger,环就被打破了。这种写法在旧项目里改动成本低,也不需要调整模块系统。 ESM 下的循环依赖表现不同。`import` 是静态提升的,绑定是活引用,但初始化顺序仍然按依赖图深度优先执行。比如: ```js // a.mjs import { b } from './b.mjs'; export const a = 'a-value'; console.log('a module sees b:', b); ``` ```js // b.mjs import { a } from './a.mjs'; export const b = 'b-value'; console.log('b module sees a:', a); ``` 入口是 a.mjs 时,a 先执行到 import b,转去执行 b,b 里访问 a 得到的是暂时性死区里的未初始化绑定,直接抛 `ReferenceError: Cannot access 'a' before initialization`。如果 b 只是把 a 存起来稍后使用,不立即读取,就不会报错,因为 ESM 的绑定是活引用,等 a 初始化完成后能拿到值。这个差异意味着从 CommonJS 迁到 ESM 时,原本靠“先拿到空对象再赋值”苟活的循环依赖会直接暴露成运行时错误。 混合使用 `require` 和 `import` 时,问题会叠加。Node 对 `.mjs` 和 `type: module` 的文件按 ESM 处理,对 `.cjs` 和默认的 `.js` 按 CommonJS 处理。ESM 里用 `createRequire` 去 require 一个 CJS 模块,如果这个 CJS 模块又通过动态 `import()` 反向依赖 ESM,加载时序就取决于调用发生的时刻。我曾遇到一个情况:CJS 侧在模块顶层调用了 `require('./esm-wrapper')`,而 esm-wrapper 顶层又 `await import('./cjs-module')`,结果 CJS 模块的导出还没完成,ESM 侧拿到的 default 是 undefined。 排查这类问题,比较直接的办法是在可疑文件顶部打日志,记录模块开始执行和 `module.exports` 赋值完成的时间点: ```js console.log('[config] start'); // ... 模块逻辑 module.exports = config; console.log('[config] exports assigned'); ``` 同时在 require 之后打印拿到的对象,看它是空对象还是缺少某个属性。Node 的 `--trace-warnings` 对循环依赖没有直接提示,但 `require.cache` 里能看到模块是否处于已缓存但未加载完成的状态。 如果项目里循环依赖数量不多,用 `madge` 扫一遍依赖图比较省事: ```bash npx madge --circular --extensions js,ts src/ ``` 它会列出所有环,再结合上面的日志定位具体是哪个环在运行时触发。对于新代码,尽量让依赖方向单向:工具函数不反向依赖业务模块,配置模块不依赖使用配置的模块。已经存在的环,优先用函数内延迟 require 或依赖注入把环打断,而不是调整文件加载顺序,后者在代码分割和懒加载场景下很容易再次失效。 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-200.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-201.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-202.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-203.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-204.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-205.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-206.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-207.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-208.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-209.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-210.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-211.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-212.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-213.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-214.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-215.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-216.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-217.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-218.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-219.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-220.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-221.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-222.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-223.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-224.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-225.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-226.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-227.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-228.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-229.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-230.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-231.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-232.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-233.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-234.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-235.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-236.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-237.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-238.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-239.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-240.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-241.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-242.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-243.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-244.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-245.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-246.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-247.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-248.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-249.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-250.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-251.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-252.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-253.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-254.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-255.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-256.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-257.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-258.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-259.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-260.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-261.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-262.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-263.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-264.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-265.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-266.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-267.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-268.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-269.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-270.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-271.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-272.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-273.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-274.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-275.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-276.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-277.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-278.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-279.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-280.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-281.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-282.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-283.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-284.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-285.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-286.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-287.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-288.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-289.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-290.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-291.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-292.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-293.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-294.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-295.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-296.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-297.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-298.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-299.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-300.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-301.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-302.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-303.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-304.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-305.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-306.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-307.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-308.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-309.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-310.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-311.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-312.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-313.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-314.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-315.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-316.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-317.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-318.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-319.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-320.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-321.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-322.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-323.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-324.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-325.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-326.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-327.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-328.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-329.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-330.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-331.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-332.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-333.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-334.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-335.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-336.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-337.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-338.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-339.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-340.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-341.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-342.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-343.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-344.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-345.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-346.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-347.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-348.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-349.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-350.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-351.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-352.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-353.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-354.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-355.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-356.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-357.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-358.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-359.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-360.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-361.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-362.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-363.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-364.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-365.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-366.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-367.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-368.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-369.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-370.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-371.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-372.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-373.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-374.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-375.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-376.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-377.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-378.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-379.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-380.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-381.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-382.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-383.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-384.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-385.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-386.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-387.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-388.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-389.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-390.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-391.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-392.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-393.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-394.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-395.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-396.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-397.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-398.html 推荐查看天气:http://www.tianqi98.com/jizhuanwan/list-399.html

优秀的个人博客,低调大师

Midway 2.13.3 发布,适用于构建 Serverless 服务的 Node.js 框架

临近双十一,我们的发版会更加的慎重,周期变长,请谅解。 Features 1、提供了一批新的组件 1、tablestore 组件,for aliyun tablestore,并提供了完整的多实例方案和 ts 定义 使用文档 2、view 系列的组件,比如 view-ejs 和 view-nunjucks,使用文档 Bugfix 1、provide uuid 改造后的循环注入问题 感谢社区 @HuJingKang 提供此 PR。 在 v2.13.0 版本新增了providerUUId 之后,在组件中使用循环依赖会导致程序卡死,这一 PR 修复了该问题并提供了 case,后续可以避免再次出现。 2、修复一个隐藏的内存泄露问题 在 Serverless 场景下是,运行时使用了一个 node 内置的 perf_hooks 的 performance 打点 API,该模块在记录后不会清理数据,导致在请求量过大时内存溢出。 由于该泄露点非常小,在大量的压测后我们才定位发现该问题,现已修复。 3、修复函数式 configuration 的异步问题 在之前提供的函数式 configuration 写法中遗漏了 async 函数的处理,导致 onReady 中的异步会返回 Promise,在某些情况下会卡住进行,在新版本中处理了该问题。 4、orm 组件中 geRepository 系列 API 的问题 在之前版本中,我们提供了多个 connection 的写法,同时将获取连接池的注入变成了回调形式,但是漏改了 getRepository 系列 API,导致这些 API 不可用。新版本修复了该问题。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册