You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack分包时报TypeError: callbacks[i] is not a function错误求助

解决Webpack分包vendor后bundle-loader触发TypeError: callbacks[i] is not a function的问题

问题根源分析

我帮你梳理了下,这个错误的核心原因是生产环境中你给所有业务JS都全局配置了bundle-loader,但你的模块导入逻辑是同步的,两者的使用方式完全不匹配,再加上分包(splitChunks)的打包逻辑,最终触发了回调相关的异常。

具体来说:

  • bundle-loader的作用是实现模块的异步加载,它会返回一个加载函数,而不是直接返回模块导出的内容。但你在main.js里是直接同步导入responsiveMenu,然后直接执行responsiveMenu()——这相当于你在调用bundle-loader返回的加载函数,而不是真正的responsiveMenu函数,自然会出现"callbacks[i] is not a function"的错误。
  • 禁用分包时,模块打包的顺序和加载逻辑刚好没触发这个矛盾,但这只是暂时规避了问题,bundle-loader的错误使用才是根本原因。

分步解决方案

1. 移除全局的bundle-loader配置(最直接的修复)

你的业务代码都是同步导入使用的,完全不需要bundle-loader。把生产环境下的JS规则里的bundle-loader去掉:

// 修改Webpack配置中module.rules里的生产环境JS规则:
{
  test: /\.js$/,
  exclude: /(node_modules|bower_components)/,
  include: path.resolve(__dirname, 'assets/js'),
  use: ['happypack/loader']
}

2. 若确实需要异步加载模块(按需调整)

如果某个模块需要按需异步加载,不要全局配置bundle-loader,而是在导入该模块时单独使用:

// 比如异步加载responsiveMenu的写法:
import loadResponsiveMenu from 'bundle-loader!./responsiveMenu';

// 在需要使用的时候调用加载函数,传入回调
loadResponsiveMenu(function(responsiveMenu) {
  responsiveMenu();
});

3. 优化模块导出逻辑(可选)

你的responsiveMenu.js导出是正常的,不过可以稍微优化下写法,确保初始化逻辑能正确触发:

export default function responsiveMenu() {
  // Responsive Menu
  function init() {
    const toggleTrigger = $('.mobile-toggle');
    const menuWrap = $('.menu-responsive');
    menuPositionSetup(menuWrap);
    triggerMenu(toggleTrigger, menuWrap);
    childItemsHandler();
  }
  function menuPositionSetup(menu) {
    let headerHeight = $('.header').outerHeight(true);
    $(menu).css('top', headerHeight);
    $(menu).css({ height: 'calc(100% - ' + headerHeight + 'px)' });
  }
  function triggerMenu(toggle, menu) {
    $(toggle).on('click', function(e) {
      mobileToggle($(this), menu);
    });
  }
  function mobileToggle(trigger, menu) {
    $(menu).toggleClass('is-active');
    $(trigger).toggleClass('is-active');
    $('body').toggleClass('is-overflow-h');
  }
  function childItemsHandler() {
    $('.menu-item-has-children > a').on('click', function(e) {
      if ($(this).hasClass('is-active')) {
        // Go to the link
      } else {
        // Open the sub menu
        $(this).addClass('is-active');
        $(this)
          .parent()
          .find('.sub-menu')
          .slideDown();
        e.preventDefault();
      }
    });
  }
  // 调用初始化函数,确保导入后执行responsiveMenu()能触发逻辑
  init();
}

额外提示

  • Webpack的splitChunks已经可以很好地处理vendor(node_modules)和业务代码的分包,bundle-loader是用于按需异步加载特定模块的场景,不要把两者的用途混淆。
  • 检查HappyPack里的babel-loader配置,确保和你的.babelrc.js预设一致,避免编译时出现差异。

内容的提问来源于stack exchange,提问作者Freddie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:06:23