3.1 模块化心得:layui.use、按需加载与新版外部模块扩展

从一个入口说起:layui.use 的两条纪律

layui 的模块系统核心就三个方法:layui.use 负责按需加载并执行回调,layui.extend 负责自定义模块,layui.config 负责设置基础路径。API 本身不复杂,真正决定代码质量的是使用姿势。

新手最常见的问题是 use 套 use:初始化时先加载 table,回调里再加载 layer,layer 回调里又加载 form。两三层下来缩进越来越深,执行顺序越来越难推理,这就是模块加载层面的回调地狱。

我的解法很轻量,就两条纪律:

  • 入口统一:一个页面只保留一个 layui.use 调用,把这一页要用的模块一次性列全,业务代码全部收进回调,不再嵌套加载;
  • 模块清单集中:把项目常用模块组合收敛到公共文件,页面只按组合取用,不在页面上随手拼模块字符串。

三个方法各自的职责与我的使用习惯如下:

方法 职责 我的使用习惯
layui.config 设置基础路径等全局配置 与模块清单一起放进公共文件
layui.extend 注册自定义或外部模块 全项目只出现一处
layui.use 按需加载并执行回调 每页仅一个入口

按这两条纪律,典型写法长这样(以官方文档为准,下同):

layui.use(["table", "form", "layer"], function(){
  var table = layui.table, form = layui.form;
  // 全部业务逻辑都在这一个回调里展开
});

按需加载的真实收益

有人觉得全量引入更省事,何必逐个声明模块。我的体会是收益在三个层面:

  • 首屏体积:管理后台页面多而杂,列表页用不到富文本,详情页用不到表格,按需加载让每个页面只背自己那份;
  • 依赖清晰:模块清单写在 use 的第一个参数里,等于给每个页面留了一份依赖声明,半年后回看不用猜;
  • 升级可控:哪些页面用了哪些组件一目了然,版本升级时逐项核对的成本骤降。

按需加载不是炫技,而是把依赖关系显式化的手段。

layui.extend 的老写法:指定 base、给第三方套壳

在 2.11 之前,想把第三方库纳入 layui 模块体系,流程偏重:先用 layui.config 设置 base 基础路径,再用 layui.extend 把自定义模块名指向对应文件,而且第三方库本身要遵循 layui 模块规范——通常得包一层 define,把别人的代码改造成 layui 认识的样子。

老写法示意:

layui.config({ base: "/static/libs/" }).extend({
  mylib: "mylib"
});

这层套壳的麻烦在于:第三方库每次升级都要重新包一遍,包装代码散落项目各处,作者改一次接口你就跟着改一次壳。

新写法:2.11 起无缝扩展任意外部模块

2.11 之后明显好转:layui.extend 支持无缝扩展任意外部模块,第三方库不再需要遵循 layui 模块规范。一个普通的浏览器全局脚本、一个 jQuery 插件,都能直接挂进模块体系,按 layui.use 的节奏加载,不必再手工套壳。

新老引入方式对照如下:

维度 老派写法(2.11 前) 新派写法(2.11 起)
前置动作 layui.config 指定 base 路径 无需专门设置路径
第三方代码 必须包装成 layui 模块 原样引入,不必遵循模块规范
升级成本 库升级需重做包装层 直接替换文件即可
典型对象 早期自研模块、老项目存量 任意外部库、jQuery 插件

老项目里已有的套壳模块不必急着拆,新项目遇到第三方库,我会优先用新能力直接挂载,省掉一层包装代码。

心得:模块清单集中一处,升级才不乱

最后回到工程层面:模块清单必须集中管理。我的做法是项目里维护一份公共文件,里面放 layui.config 的路径配置、layui.extend 的自定义模块注册,以及常用模块组合的定义。页面代码只做一件事——按组合调用 layui.use。

集中管理的好处要到升级时才显出来:从旧版本升到新版本,基础路径要不要调、模块注册要不要改、哪些组合要增删,只看这一个文件就够。散落在几十个页面里的模块字符串,才是升级时真正的雷区。

顺带一提:2.10 起 layui 引入了 component 组件构建器,把渲染、重载、事件、实例等接口统一了起来,写自研组件时值得了解,能让自研模块与内置组件保持一致的手感。具体用法以官方文档为准。