96SEO 2026-02-19 22:36 0
在项目比较小的时候可能不怎么会遇到这个问题但项目一旦有一定的体量后就可能会遇到了。

CommonJS模块采用深度优先遍历并且是加载时执行即脚本代码在require时就全部执行。
一旦出现某个模块被“循环加载”就只输出已经执行的部分没有执行的部分不会输出。
执行a.js为moduleA添加属性,发现第一行导入b.js模块a还没执行完执行b.js
执行b.js发现导入a.js此时moduleCache有moduleA,不会重复执行模块a的代码会直接用moduleCache中模块a已经导出的内容。
moduleCache.moduleA因为此时模块a的内容还未完全执行完所以解构的变量a是undefined还不是function所以报错。
(__unused_webpack_module,__webpack_exports__,__webpack_require__)
{__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__,
_b_js__WEBPACK_IMPORTED_MODULE_0__
__webpack_require__(./src/b.js);var
(__unused_webpack_module,__webpack_exports__,__webpack_require__)
{__webpack_require__.r(__webpack_exports__);var
_a_js__WEBPACK_IMPORTED_MODULE_0__
__webpack_require__(./src/a.js);(0,
_a_js__WEBPACK_IMPORTED_MODULE_0__.A)();},};var
__webpack_module_cache__[moduleId];if
(__webpack_module_cache__[moduleId]
{},});__webpack_modules__[moduleId](module,
(__webpack_require__.o(definition,
!__webpack_require__.o(exports,
{Object.defineProperty(exports,
definition[key],});}}};})();(()
Object.prototype.hasOwnProperty.call(obj,
{Object.defineProperty(exports,
Module,});}Object.defineProperty(exports,
{};__webpack_require__.r(__webpack_exports__);var
_a__WEBPACK_IMPORTED_MODULE_0__
__webpack_require__(./src/a.js);
(__unused_webpack_module,__webpack_exports__,__webpack_require__)
{__webpack_require__.r(__webpack_exports__);
标记模块为ES模块__webpack_require__.d(__webpack_exports__,
_b_js__WEBPACK_IMPORTED_MODULE_0__
__webpack_require__(./src/b.js);var
(__unused_webpack_module,__webpack_exports__,__webpack_require__)
{__webpack_require__.r(__webpack_exports__);var
_a_js__WEBPACK_IMPORTED_MODULE_0__
__webpack_require__(./src/a.js);(0,
_a_js__WEBPACK_IMPORTED_MODULE_0__.A)();},};webpack自定义require导入函数
__webpack_module_cache__[moduleId];if
(__webpack_module_cache__[moduleId]
{},});__webpack_modules__[moduleId](module,
查看缓存是否有模块导出结果如果模块执行过了返回模块导出结果在执行模块代码之前先创建模块导出对象module.exports将模块导出对象传入执行模块代码
将模块导出对象标记ES模块如果模块有导出内容会将这些内容定义到模块导出对象
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__,
_b_js__WEBPACK_IMPORTED_MODULE_0__
__webpack_require__(./src/b.js);
定义了一个A属性A属性是一个存取器属性有gettergetter就是返回真正导出的A。
__webpack_require__.r(__webpack_exports__);
_a_js__WEBPACK_IMPORTED_MODULE_0__
__webpack_require__(./src/a.js);(0,
_a_js__WEBPACK_IMPORTED_MODULE_0__.A)();跟Commonjs的问题一样模块A还没有执行完A还没有赋值所以A这里是undefined不能作为函数调用。
打包结果中模块代码执行前会去先定义导出属性为属性设置一个getter因此在代码模块执行前这些导出属性就已经在导出对象中有getter。
这里因为配置babel打包结果会把const转成var所以变量声明提升了如果是const就会变成变量在声明前使用。
项目会形成循环依赖实际开发中很难避免有可能引入了某个模块就会导致形成依赖链路。
形成循环依赖链路并不一定会报错但是在执行到对应模块时之前模块因为导入其他包模块代码还没完全执行完内容还没完全导出就有可能导致报错。
其实导致报错还好因为可以提前在本地就感知到处理但是如果你只是定义了一个变量那么这个变量可能是在你还没有赋值的时候就引用了所以其实模块导出的变量并不是一定可信的。
其实在遇到函数调用报错时可以通过把一些函数表达式改成函数声明就好因为打包结果模块的执行其实是执行一个函数在执行前会有函数声明提升但尽量不要用这种规范来处理因为很可能会遇到更多坑。
其实有模块循环依赖后还报错本身就是这条依赖链路有问题应该找到不合理的地方解决而不是去规避。
用函数声明解决一些问题反倒会留下一些坑可能某些环境的值原本因为循环依赖导致引用时是undefined,但是碰巧你用函数声明避免了一些报错导致埋了一个坑。
有一些工具可以分析项目中的循环链路eslint也有相应的配置。
至于如何找到循环依赖的不合理地方就凭经验吧这里就不展开了毕竟是个人观点。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback