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

Webpack打包后出现Uncaught ReferenceError: $ is not defined问题求助

我来帮你拆解这两个问题,都是Webpack处理全局依赖时常见的坑:

一、用glob批量打包时$ is not defined的原因

你猜的没错,这完全是打包顺序的问题。Webpack确实会处理模块依赖,但当你用glob.sync("./src/js/*.js")把所有JS文件都作为入口时,Webpack会把这些文件当成独立的模块并行处理,不会自动识别谁依赖谁——也就是说,如果你的业务代码或者插件在jQuery之前被打包执行,那自然会找不到$。

解决这个问题的核心是强制让jQuery先被加载,有两种简单的方式:

  • 手动指定jQuery在glob数组的最前面,避免它被排在后面:
    entry: {
      bundle: ["./src/js/jquery.js", ...glob.sync("./src/js/*.js").filter(file => file !== "./src/js/jquery.js")]
    }
    
    这样能确保jQuery最先被打包,后面的文件就能拿到全局的$了。
  • 改用单入口文件(也就是你后来尝试的方式),通过import明确依赖顺序,这其实是Webpack推荐的模块化写法,比glob批量引入更可控。

二、单入口import $ from './jquery'后插件找不到jQuery的原因

很多老的jQuery插件(比如某些弹窗、表单插件)是基于全局jQuery/$变量开发的,它们不会主动去导入jQuery模块,而是直接在全局作用域找这个变量。但Webpack的import默认是把模块封装在局部作用域里的,不会自动把$挂载到window上,所以插件就会报错。

这里有几种靠谱的解决方案,按推荐程度排序:

1. 使用Webpack的ProvidePlugin(最推荐)

这个插件的作用是自动给所有模块注入指定的依赖,不用手动import就能用。在你的webpack.config.js里配置:

const webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: "./src/js/entry_file.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist/js")
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery', // 有些插件只认jQuery,所以两个都写上
      'window.jQuery': 'jquery' // 确保window全局对象上也有这个变量
    })
  ]
};

配置后,你甚至可以在入口文件里删掉import $ from './jquery',Webpack会自动把jQuery注入到所有用到$或jQuery的模块里,插件也能在全局找到它了。

2. 手动把jQuery挂载到window上

如果你不想改Webpack配置,也可以在入口文件里手动把$挂到全局:

import $ from './jquery';
// 先挂载全局变量
window.$ = $;
window.jQuery = $;

// 再导入依赖jQuery的插件
import hljs from './highlight';
// 其他插件...

这种方式简单直接,但缺点是需要确保挂载操作在所有插件导入之前执行。

3. 使用expose-loader(适合老项目兼容)

这个loader可以把模块暴露到全局作用域里,先安装它:

npm install expose-loader --save-dev

然后在Webpack配置里添加规则:

module.exports = {
  // ...其他配置
  module: {
    rules: [
      {
        test: require.resolve('jquery'), // 匹配jquery模块
        loader: 'expose-loader',
        options: {
          exposes: ['$', 'jQuery']
        }
      }
    ]
  }
};

或者在入口文件里用内联loader的方式:

import $ from 'expose-loader?$!expose-loader?jQuery!./jquery';

这种方式也能让jQuery成为全局变量,但现在ProvidePlugin是更主流的方案。

总结

  • 批量引入文件时一定要注意依赖顺序,Webpack不会自动猜测谁先谁后;
  • 老插件依赖全局变量时,用ProvidePlugin是最优雅的解决方式,既能保持模块化,又能满足插件的全局依赖需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:01:44