微信小程序集成 Day.js 插件的完整解决方案
在微信小程序开发中,Day.js 是一个非常流行的轻量级日期时间处理库。然而,在实际使用过程中,我们发现微信小程序的 npm 构建工具在处理 Day.js 的插件模块时存在兼容性问题。本文将详细记录问题的排查过程、解决方案以及最佳实践。
问题背景
在项目中引入 Day.js 及其插件(duration、relativeTime、weekday、isBetween)后,在微信开发者工具中构建 npm 时遇到以下问题:
- 插件目录缺失
:构建后的 miniprogram_npm/dayjs/目录下没有plugin子目录 - 模块加载失败
:运行时报错 module 'dayjs/plugin/duration.js' is not defined - 路径解析错误
:尝试使用不同的引用路径都未能解决问题
环境配置
软件版本
- 操作系统
: macOS Sequoia 15.6.1 (Darwin Kernel Version 24G90, arm64) - Shell
: zsh - 微信开发者工具
: 2.01.2510260 darwin-arm64 - 微信小程序基础库
: 3.13.2 / 2.19.4 - Node.js
: v23.11.0 - npm
: 10.9.2
项目依赖
wxapp/package.json
{"name": "wxapp","version": "1.0.0","description": "微信小程序","main": "app.js","dependencies": {"dayjs": "^1.11.20", ... },"devDependencies": {"eslint": "^8.0.0","eslint-config-standard": "^17.0.0","eslint-plugin-import": "^2.25.0","eslint-plugin-node": "^11.1.0","eslint-plugin-promise": "^6.0.0","miniprogram-api-typings": "^3.9.0" }, ...}
小程序配置
wxapp/project.config.json
{"setting": {"es6": true,"packNpmManually": true,"packNpmRelationList": [ {"packageJsonPath": "./package.json","miniprogramNpmDistDir": "./" } ],"nodeModules": true,"libVersion": "3.13.2", ... }, ...}
问题复现与排查
初始代码
utils/date-time.js
const dayjs = require('dayjs')/** * 扩展 duration 插件 */const duration = require('dayjs/plugin/duration.js')dayjs.extend(duration)/** * 扩展 relativeTime 插件(相对时间) */const relativeTime = require('dayjs/plugin/relativeTime.js')dayjs.extend(relativeTime)/** * 扩展 weekday 插件(星期) */const weekday = require('dayjs/plugin/weekday.js')dayjs.extend(weekday)/** * 扩展 isBetween 插件(判断是否在两个日期之间) */const isBetween = require('dayjs/plugin/isBetween.js')dayjs.extend(isBetween)/** * 日期时间工具类 */const DateTimeUtil = { format(date, format = 'YYYY-MM-DD HH:mm:ss') {if (!date) return''return dayjs(date).format(format) },// ... 其他方法}module.exports = DateTimeUtil
问题现象
执行微信开发者工具的”构建 npm”后,检查 miniprogram_npm/dayjs/ 目录:
$ ls -lh miniprogram_npm/dayjstotal 40-rw-r--r--@ 1 yakoo5 staff 8.4K 3 21 22:48 index.js-rw-r--r--@ 1 yakoo5 staff 7.3K 3 21 22:48 index.js.map
关键发现:miniprogram_npm/dayjs/ 目录下没有 plugin 子目录,导致插件文件无法被正确加载。
运行时的错误信息:
页面【pages/paper-detail/paper-detail]错误: Error: module 'dayjs/plugin/duration.js' is notdefined, require args is 'dayjs/plugin/duration' at q (VM2704 WASubContext.js:1) at n (VM2704 WASubContext.js:1) at date-time.js? [sm]:10
解决方案
经过实际测试和验证,我们找到了两种有效的解决方案。
方案一:手动复制插件到 miniprogram_npm 目录
适用场景:希望保持 npm 标准引用方式,不修改代码中的 require 路径。
步骤 1:创建插件目录
cd wxappmkdir -p miniprogram_npm/dayjs/plugin
步骤 2:复制插件文件
# 从 node_modules 复制所需的插件文件到 miniprogram_npm/dayjs/plugin/
cp -vf node_modules/dayjs/plugin/duration.js miniprogram_npm/dayjs/plugin
cp -vf node_modules/dayjs/plugin/isBetween.js miniprogram_npm/dayjs/plugin
cp -vf node_modules/dayjs/plugin/relativeTime.js miniprogram_npm/dayjs/plugin
cp -vf node_modules/dayjs/plugin/weekday.js miniprogram_npm/dayjs/plugin
步骤 3:验证目录结构
$ ls -lh miniprogram_npm/dayjs/plugintotal 40-rw-r--r--@ 1 yakoo5 staff 4.7K 3 21 22:48 duration.js-rw-r--r--@ 1 yakoo5 staff 546B 3 21 22:48 isBetween.js-rw-r--r--@ 1 yakoo5 staff 1.4K 3 21 22:48 relativeTime.js-rw-r--r--@ 1 yakoo5 staff 427B 3 21 22:48 weekday.js
步骤 4:重新编译
在微信开发者工具中选择”工具 > 编译”,验证问题是否解决。
方案二:本地化插件文件(推荐)✅
适用场景:希望完全控制依赖,便于版本管理和团队协作。
步骤 1:创建插件目录
cd wxappmkdir -p utils/plugins/dayjs
步骤 2:复制插件文件
# 从 node_modules 复制所需的插件文件到 miniprogram_npm/dayjs/plugin/cp -vf node_modules/dayjs/plugin/duration.js miniprogram_npm/dayjs/plugincp -vf node_modules/dayjs/plugin/isBetween.js miniprogram_npm/dayjs/plugincp -vf node_modules/dayjs/plugin/relativeTime.js miniprogram_npm/dayjs/plugincp -vf node_modules/dayjs/plugin/weekday.js miniprogram_npm/dayjs/plugin
步骤 3:修改 utils/date-time.js
/** * 日期时间工具类 * 基于 Day.js 实现 */const dayjs = require('dayjs')/** * 扩展 duration 插件 */const duration = require('./plugins/dayjs/duration.js')dayjs.extend(duration)/** * 扩展 relativeTime 插件(相对时间) */const relativeTime = require('./plugins/dayjs/relativeTime.js')dayjs.extend(relativeTime)/** * 扩展 weekday 插件(星期) */const weekday = require('./plugins/dayjs/weekday.js')dayjs.extend(weekday)/** * 扩展 isBetween 插件(判断是否在两个日期之间) */const isBetween = require('./plugins/dayjs/isBetween.js')dayjs.extend(isBetween)/** * 日期时间工具类 */const DateTimeUtil = { format(date, format = 'YYYY-MM-DD HH:mm:ss') {if (!date) return''return dayjs(date).format(format) },// ... 其他方法}module.exports = DateTimeUtil
步骤 4:构建 npm 并重新编译
# 在微信开发者工具中依次执行:# 1. 工具 > 清除缓存 > 全部清除# 2. 工具 > 构建 npm# 3. 工具 > 编译
方案对比
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
微信小程序基础库版本的影响
在实际测试中,我们发现不同的基础库版本对 Day.js 插件的支持存在差异:
测试场景
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
结论:无论使用哪个基础库版本(3.13.2 或 2.19.4),微信小程序的 npm 构建工具都无法自动处理 Day.js 的插件子目录。这是一个普遍存在的问题,与基础库版本无关。
问题根因分析
1. 微信小程序 npm 构建工具的限制
微信小程序的 npm 构建工具在处理某些 npm 包的子模块时存在兼容性问题:
- 路径解析问题
:当使用 require('dayjs/plugin/duration.js')时,构建工具无法正确解析插件子模块的路径 - 构建产物问题
:构建后的 miniprogram_npm/dayjs/目录下缺少plugin子目录
2. Day.js 插件文件的格式
Day.js 的插件文件是 UMD 模块格式,并且是压缩后的单行代码:
!function(t,s){"object"==typeof exports&&"undefined"!=typeofmodule?module.exports=s():"function"==typeof define&&define(s):(t="undefined"!=typeof globalThis?globalThis:t||self).dayjs_plugin_duration=s()}(this,(function(){"use strict";var t,s,n=1e3,...(大量压缩代码)...
补充说明:虽然插件文件是压缩后的单行代码,但在实际测试中,并未出现之前偶现的语法错误(”Missing semicolon”)。只要文件被正确复制到指定目录,微信小程序的模块加载器可以正常解析。
3. 微信小程序的模块解析机制
微信小程序的 require() 机制与 Node.js 的 CommonJS 规范存在差异:
- 不支持 npm 包的子模块路径
: require('package-name/submodule')在小程序中可能无法正确解析 - 需要明确的相对路径
:需要使用相对于当前文件的明确路径
最佳实践建议
1. 项目目录结构
wxapp/├── package.json├── project.config.json├── utils/│ ├── plugins/ # 本地化的第三方插件(如果使用方案二)│ │ └── dayjs/ # Day.js 插件│ │ ├── duration.js│ │ ├── relativeTime.js│ │ ├── weekday.js│ │ └── isBetween.js│ ├── date-time.js # 日期时间工具类│ └── ...├── miniprogram_npm/ # npm 构建产物│ └── dayjs/│ ├── index.js│ ├── index.js.map│ ├── package.json│ └── plugin/ # 手动创建的插件目录(如果使用方案一)│ ├── duration.js│ ├── relativeTime.js│ ├── weekday.js│ └── isBetween.js├── node_modules/ # npm 依赖│ └── dayjs/│ ├── plugin/│ ├── esm/│ └── ...└── ...
2. 依赖管理
- 纳入版本控制
:将本地化的插件文件纳入 Git 版本控制 - 记录版本信息
:在代码注释中记录对应的 dayjs 版本号 - 按需引入
:只复制项目实际使用的插件文件,减少项目体积
3. 构建流程
在引入新的 npm 包或更新 dayjs 版本时,建议按以下步骤操作:
# 1. 清理旧的构建产物cd wxapprm -rf node_modulesrm -rf miniprogram_npm# 2. 安装依赖npm install# 3. 复制插件文件(如果使用方案二)mkdir -p utils/plugins/dayjscp -vf node_modules/dayjs/plugin/duration.js utils/plugins/dayjscp -vf node_modules/dayjs/plugin/isBetween.js utils/plugins/dayjscp -vf node_modules/dayjs/plugin/relativeTime.js utils/plugins/dayjscp -vf node_modules/dayjs/plugin/weekday.js utils/plugins/dayjs# 4. 在微信开发者工具中构建 npm# 工具 > 清除缓存 > 全部清除# 工具 > 构建 npm
4. 团队协作建议
- 编写文档
:在项目的 README 或开发文档中记录插件引入的步骤 - 自动化脚本
:可以编写 npm script 自动化插件复制过程 - 代码审查
:在 Pull Request 中检查插件文件是否正确更新
自动化脚本示例
为了简化插件文件的管理,可以创建一个自动化脚本:
scripts/copy-dayjs-plugins.sh
#!/bin/bash# 复制 Day.js 插件文件的自动化脚本cd"$(dirname "$0")/.."echo"开始复制 Day.js 插件文件..."# 创建插件目录mkdir -p utils/plugins/dayjs# 复制插件文件plugins=("duration.js""relativeTime.js""weekday.js""isBetween.js")for plugin in"${plugins[@]}"; doif [ -f "node_modules/dayjs/plugin/$plugin" ]; then cp -vf "node_modules/dayjs/plugin/$plugin""utils/plugins/dayjs/"echo"✓ 已复制: $plugin"elseecho"✗ 文件不存在: node_modules/dayjs/plugin/$plugin"fidoneecho"Day.js 插件文件复制完成!"
在 package.json 中添加脚本:
{"scripts": {"copy:dayjs": "bash scripts/copy-dayjs-plugins.sh","postinstall": "npm run copy:dayjs" }}
这样在执行 npm install 后会自动复制插件文件。
常见问题 FAQ
Q1: 为什么不直接使用 require(‘dayjs/plugin/duration’)?
A: 微信小程序的 npm 构建工具无法正确处理这种子模块路径,导致 plugin 目录不被复制到 miniprogram_npm 下。
Q2: 方案一和方案二哪个更好?
A: 推荐使用方案二(本地化插件),因为:
- 纳入版本控制,便于团队协作
- 不依赖于构建产物的临时性
- 更容易进行版本管理
Q3: 更新 dayjs 版本时需要注意什么?
A: 需要检查新版本中的插件文件是否有变化,并重新复制插件文件。建议使用自动化脚本减少人为错误。
Q4: 是否需要将复制的插件文件提交到 Git?
A: 如果使用方案二(本地化插件),建议提交到 Git。如果使用方案一(复制到 miniprogram_npm),不推荐提交,应该将其添加到 .gitignore。
Q5: 是否可以使用 esm 版本的插件?
A: 微信小程序目前不完全支持 ES6 模块语法,建议使用 CommonJS 版本的插件文件。
总结
微信小程序的 npm 构建工具在处理 Day.js 插件时存在兼容性问题,主要表现为 plugin 子目录缺失。通过手动复制插件文件到指定目录,可以成功解决问题。
核心要点:
- 问题根源
:微信小程序 npm 构建工具无法正确处理 Day.js 的插件子目录 - 解决方案
:手动复制插件文件到 utils/plugins/dayjs/或miniprogram_npm/dayjs/plugin/ - 推荐方案
:使用方案二(本地化插件),纳入版本控制 - 版本影响
:问题与基础库版本无关(3.13.2 和 2.19.4 都存在此问题) - 最佳实践
:自动化插件复制流程,纳入版本控制,编写团队文档
通过本文提供的解决方案和最佳实践,可以避免在微信小程序项目中遇到类似问题,提高开发效率和团队协作效率。
参考资料
-
Day.js 官方文档 -
微信小程序 npm 支持 -
微信小程序模块加载机制
文档创建日期: 2026-03-21最后更新日期: 2026-03-21文档版本: 1.0测试环境: 微信小程序基础库 3.13.2 / 2.19.4
注:本文基于实际项目经验整理,希望对遇到类似问题的开发者有所帮助。如有疑问或建议,欢迎交流讨论。
夜雨聆风