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

webpack 5为script标签添加defer="defer" 如何取消jQuery的defer配置

问题原因

defer属性会让脚本在HTML文档解析完成后才执行,而你写在body内的内联调用jQuery的脚本会在HTML解析过程中同步执行,此时jQuery还未加载完成,因此会报$ is undefined错误。
补充说明:expose-loader本身仅负责将模块暴露到全局作用域,不会给script标签添加defer属性,该属性一般由负责自动注入脚本的构建插件(如html-webpack-plugin、框架内置的资源打包工具)添加。

解决方案

方案1:单独给jQuery脚本关闭defer注入

如果你使用html-webpack-plugin自动注入脚本,修改webpack配置,排除jQuery chunk自动注入,手动添加不带defer的引入:

// webpack.config.js
module.exports = {
  // 其余配置不变
  plugins: [
    new HtmlWebpackPlugin({
      // 其余参数不变
      excludeChunks: ['jquery'] // 排除jQuery chunk自动注入
    })
  ]
}

然后在HTML的head标签内手动引入jQuery脚本,不带defer属性:

<script src="/packs/vendors-node_modules_jquery_dist_jquery_js-exposed-e9b29cc0e77d15c93346.js"></script>

方案2:调整业务脚本执行时机

如果不想修改构建配置,可将业务中调用jQuery的代码包裹在DOMContentLoaded事件回调中,等所有带defer的脚本执行完成后再运行:

document.addEventListener('DOMContentLoaded', function() {
  // 此处写入原来调用$的业务代码即可
  console.log($);
})

方案3:Rails Webpacker场景配置

如果是基于Rails + Webpacker的项目,可在布局文件中引入jQuery时强制关闭defer:

  1. 先修改config/webpack/environment.js把jQuery单独拆成chunk:
environment.splitChunks(config => {
  config.optimization.splitChunks.cacheGroups.jquery = {
    test: /jquery/,
    name: 'jquery',
    chunks: 'all',
    enforce: true
  }
  return config
})
  1. 在布局文件head中引入时指定defer: false:
<%= javascript_include_tag "jquery", defer: false %>
<%= javascript_pack_tag "application", defer: true %>

配套expose-loader正确配置

确认webpack中expose-loader配置正确,确保jQuery能暴露到全局作用域:

// webpack.config.js > module.rules
{
  test: require.resolve('jquery'),
  loader: 'expose-loader',
  options: {
    exposes: ['$', 'jQuery']
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:15:08