不能重构成layui模块化架构,只能在layui环境中安全复用原有jquery代码;因其内置jquery移除了全局$和jquery变量,老旧插件依赖window.jquery导致报$ is not defined或cannot read property 'fn' of undefined。

直接说结论:不能“重构成 Layui 模块化架构”,只能“在 Layui 环境中安全复用原有 jQuery 代码”。Layui 不是重构目标,而是运行约束环境;它的模块机制不兼容全局 $,强行迁移旧插件会报 $ is not defined 或 Cannot read property 'fn' of undefined。
为什么直接引入老旧 jQuery 插件会报错
Layui 内置了 jQuery(v1.12.4),但主动移除了全局 $ 和 jQuery 变量——这是为避免与页面已存在的 jQuery 冲突。而绝大多数老旧插件(比如 siam.js)依赖立即执行函数包裹的 (function($){ ... })($) 模式,且默认从 window.jQuery 取值。Layui 的模块加载顺序又常早于你手动引入的外部 jQuery,导致闭包里传入的 $ 是 undefined。
常见错误现象:
-
Uncaught ReferenceError: $ is not defined(插件脚本第一行就崩) -
TypeError: Cannot read property 'fn' of undefined(插件试图挂载方法到$.fn) - 插件初始化成功,但后续调用时报
$(...).siam is not a function
必须用 layui.define 封装旧插件
把插件逻辑包进 Layui 模块,显式声明对 jquery 模块的依赖,并通过 layui.$ 获取受控的 jQuery 实例。这是唯一能绕过全局变量缺失、又能复用原逻辑的方式。
实操步骤:
jQuery 1.12.4是jQuery 1.x系列的最后一个正式稳定版本,由jQuery团队于2016年发布。该版本主要面向需要兼容旧版浏览器环境的网站和Web应用,尤其适用于仍需支持Internet Explorer 6、Internet Explorer 7、Internet Explorer 8等老旧浏览器的项目。
- 新建文件
src/modules/siam.js(路径需与layui.js同级或按layui.config({base: 'xxx/'})配置) - 内容结构固定:
layui.define('jquery', function(exports){ var $ = layui.$; // ✅ 此处粘贴原 siam.js 的核心函数体(去掉外层 IIFE 包裹) // ❌ 不要保留 (function($){ ... })(window.jQuery); $.fn.siam = function(params) { var dom = this; dom.html(params); return this; // 记得链式返回 }; exports('siam', {}); // 模块名与文件名一致,值可空 }); - 使用时必须先
layui.use(['jquery', 'siam'], function(){...}),否则layui.$还没加载完成
遇到依赖其他 jQuery 插件怎么办
比如你的 siam.js 内部调用了 $.fn.draggable,而该方法来自另一个老旧插件 jquery-ui-draggable.js。这时不能只封装 siam,必须一并封装依赖项:
- 将
jquery-ui-draggable.js同样改写为src/modules/draggable.js,导出空对象即可 - 在
siam.js的layui.define第一个参数里加上'draggable',确保加载顺序 - 注意:Layui 不支持 AMD/CMD 的依赖自动解析,所有依赖必须显式声明在数组里
参数差异关键点:layui.define(['jquery', 'draggable'], callback) 中,callback 执行时,draggable 模块已加载完毕,其内部对 layui.$ 的扩展已生效,siam 才能安全调用 $.fn.draggable。
别碰 layui.config({jquery: true}) 这个坑
文档里提过这个配置项,它会让 Layui 放弃内置 jQuery、转而使用全局 $。看起来是捷径,但实际埋雷:
- 若你页面引入的是 jQuery 3.x,而 Layui 组件(如
form、table)内部依赖 1.12.4 的行为(比如事件委托写法),大概率崩溃 - 多个第三方库共存时,
$.noConflict()会破坏 Layui 对 jQuery 的控制权 - FastAdmin 等基于 Layui 的框架明确禁用此配置,因其破坏模块隔离性
真正需要的不是“让 Layui 屈服于旧代码”,而是“让旧代码适应 Layui 的模块契约”。最易被忽略的一点:所有 DOM 操作必须发生在 layui.use 回调内——哪怕只是 $('#test').siam('xxx'),也得等模块加载完,否则 layui.$ 还没准备好,$ 就是 undefined。










