esbuild 默认将模块封装为 ES 模块作用域,导致通过 import 引入的 jQuery 无法被传统全局依赖脚本(如直接使用 jQuery 或 $ 的 legacy JS 文件)访问;需通过配置或运行时挂载使其成为全局变量。
esbuild 默认将模块封装为 es 模块作用域,导致通过 import 引入的 jquery 无法被传统全局依赖脚本(如直接使用 `jquery` 或 `$` 的 legacy js 文件)访问;需通过配置或运行时挂载使其成为全局变量。
在 esbuild 构建流程中,所有 import 语句均遵循 ES 模块规范:导入的变量仅在当前模块作用域内有效,不会自动注入到全局 window 对象。因此,即使你写了 import jQuery from './jquery-3.7.1.js',该 jQuery 变量也不会自动等价于浏览器中全局可用的 window.jQuery——而许多旧版插件(如 otherFile.js)正是通过 typeof jQuery !== 'undefined' 或直接调用 jQuery(...) 来检测和使用 jQuery 的,这正是报错 "jQuery is not defined" 的根本原因。
✅ 正确解决方案(推荐三选一)
1. 显式挂载到全局(最常用且可控)
确保 jQuery 实例在其他依赖脚本执行前已挂载至 window,且挂载语句必须在 import './otherFile.js' 之前执行并生效:
// main.js import jQuery from './jquery-3.7.1.js'; // ✅ 关键:立即挂载为全局变量(注意:需在依赖脚本加载前) window.jQuery = window.$ = jQuery; // ✅ 此时 otherFile.js 才能访问 window.jQuery import './otherFile.js';
⚠️ 注意:import 声明会被提升(hoisted),但其执行顺序仍严格按代码顺序。因此 window.jQuery = ... 必须写在 import './otherFile.js' 之前,且不能依赖异步逻辑。
2. 使用 esbuild 的 inject 功能(构建时注入)
创建一个注入文件 inject-jquery.js:
// inject-jquery.js import jQuery from './jquery-3.7.1.js'; window.jQuery = window.$ = jQuery;
然后在 esbuild 构建命令中启用 inject:
jQuery 1.12.4是jQuery 1.x系列的最后一个正式稳定版本,由jQuery团队于2016年发布。该版本主要面向需要兼容旧版浏览器环境的网站和Web应用,尤其适用于仍需支持Internet Explorer 6、Internet Explorer 7、Internet Explorer 8等老旧浏览器的项目。
esbuild main.js --bundle --inject:./inject-jquery.js --outfile=dist/bundle.js
esbuild 会自动将注入文件的内容前置到打包结果顶部,确保 jQuery 全局可用性优先于所有其他模块。
3. 外链引入 jQuery(适用于不打包 jQuery 的场景)
若 otherFile.js 是外部遗留脚本(未经过 esbuild 处理),更稳妥的方式是不打包 jQuery,而是通过 <script> 标签外链加载,保证其天然全局可用:
<script src="./jquery-3.7.1.js"></script> <script src="./otherFile.js"></script> <!-- 直接依赖 window.jQuery --> <script src="./dist/bundle.js"></script> <!-- esbuild 打包的主逻辑 -->
此时你的 main.js 可直接使用 window.jQuery,无需 import:
// main.js(无需 import jQuery)
const $ = window.jQuery;
$(document).ready(() => { /* ... */ });? 补充说明:为什么 window.jQuery = jQuery 有时仍失效?
- ❌ 错误写法:import jQuery from '...'; window.jQuery = jQuery; import './otherFile.js';
→ 若 otherFile.js 内部使用的是 import 方式引用 jQuery(而非全局),则它仍会尝试独立解析 jQuery 模块,可能因路径/resolve 问题失败。 - ✅ 验证方式:在 otherFile.js 开头添加 console.log(typeof jQuery, typeof window.jQuery),确认其读取的是 window 上的值。
? 总结
esbuild 的模块隔离机制是特性而非 Bug。要兼容依赖全局变量的传统脚本,核心原则是:在依赖脚本执行前,确保所需全局变量已真实存在于 window 上。优先推荐方案 1(显式挂载)或方案 3(外链),兼顾可维护性与兼容性。此模式同样适用于 lodash、moment 等需全局暴露的库。

















