多文件模块化开发(CommonJS)
当插件变得复杂时,将所有代码写在一个 main.js 中会变得难以维护。EasyBot 插件运行环境以 CommonJS 为主,ES 模块支持非常有限。推荐使用 CommonJS 的 require 与 module.exports 将代码拆分为多个文件,实现清晰的模块化组织。
项目结构
一个典型的多文件插件项目结构如下:
my_plugin/
├── manifest.json
├── main.js
├── utils/
│ ├── helper.js
│ └── config.js
└── handlers/
├── commands.js
└── events.js
创建工具模块
创建 utils/helper.js 文件:
utils/helper.js
function formatTime(date = new Date()) {
return date.toLocaleString('zh-CN');
}
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getTimestamp() {
return Date.now();
}
module.exports = { formatTime, randomInt, getTimestamp };
创建配置模块
创建 utils/config.js 文件:
utils/config.js
const config = {
pluginName: '多文件示例插件',
version: '1.0.0',
maxRetries: 3,
timeout: 5000
};
function getConfig(key) { return config[key]; }
function setConfig(key, value) { config[key] = value; }
function getAllConfig() { return { ...config }; }
module.exports = { getConfig, setConfig, getAllConfig, config };
创建命令处理模块
创建 handlers/commands.js 文件:
handlers/commands.js
const { formatTime, randomInt } = require('../utils/helper.js');
const { getConfig } = require('../utils/config.js');
function handleTimeCommand() {
const currentTime = formatTime();
logger.info(`当前时间: ${currentTime}`);
return currentTime;
}
function handleRandomCommand(min = 1, max = 100) {
const result = randomInt(min, max);
logger.info(`随机数 (${min}-${max}): ${result}`);
return result;
}
function handleInfoCommand() {
const name = getConfig('pluginName');
const version = getConfig('version');
logger.info(`插件信息: ${name} v${version}`);
return { name, version };
}
function handleHelpCommand() {
const commands = ['time', 'random', 'info', 'help'];
logger.info(`可用命令: ${commands.join(', ')}`);
return commands;
}
module.exports = {
handleTimeCommand,
handleRandomCommand,
handleInfoCommand,
handleHelpCommand
};
创建事件处理模块
创建 handlers/events.js 文件:
handlers/events.js
const { formatTime } = require('../utils/helper.js');
function registerEvents() {
bus.on('enable', () => {
const time = formatTime();
logger.info(`[${time}] 多文件插件已启用`);
});
bus.on('disable', () => {
const time = formatTime();
logger.info(`[${time}] 多文件插件已禁用`);
});
bus.on('bridge.connected', (data) => {
const time = formatTime();
logger.info(`[${time}] 服务器已连接: ${data.serverName}`);
});
}
function registerRobotEvents() {
bus.on('robot.message', (data) => {
const time = formatTime();
logger.info(`[${time}] 收到消息: ${data.message}`);
});
}
module.exports = { registerEvents, registerRobotEvents };
主入口文件
修改 main.js 文件,使用 CommonJS 导入并使用这些模块:
main.js
/// <reference path="easybot-sdk/easybot.d.ts" />
const {
handleTimeCommand,
handleRandomCommand,
handleInfoCommand
} = require('./handlers/commands.js');
const { registerEvents } = require('./handlers/events.js');
const { setConfig } = require('./utils/config.js');
logger.info('多文件插件被加载');
setConfig('pluginName', '我的多文件插件');
registerEvents();
setTimeout(() => {
handleTimeCommand();
handleRandomCommand(1, 10);
handleInfoCommand();
}, 2000);
CommonJS 导入规则
在 EasyBot 插件中使用 CommonJS 时,需要注意以下规则:
基本语法
const helper = require('./utils/helper.js');
const { formatTime, randomInt } = require('./utils/helper.js');
module.exports = { handleTimeCommand };
exports.handleRandomCommand = handleRandomCommand;
路径示例
// handlers/commands.js
const { formatTime } = require('../utils/helper.js');
const { getConfig } = require('../utils/config.js');
// main.js
const { handleTimeCommand } = require('./handlers/commands.js');
const { registerEvents } = require('./handlers/events.js');
ESM 支持现状
EasyBot 插件环境原生支持 ES Modules。虽然本教程主要介绍 CommonJS 写法,但你也可以使用 import / export 语法进行开发。
关于 CommonJS
由于 V8 引擎特性,EasyBot 通过兼容层支持 CommonJS。在绝大多数情况下,它的行为与你预期的通过 require 加载模块一致。
更新插件清单
更新 manifest.json 文件:
manifest.json
{
"name": "多文件示例插件",
"version": "1.0.0",
"plugin_id": "multi_file_example",
"author": "MiuxuE",
"description": "演示如何使用多文件模块化开发EasyBot插件",
"tags": ["示例", "模块化"],
"entry": "main.js",
"contents": "# 多文件模块化插件\n\n这个插件演示了如何使用多个JavaScript文件来组织代码,提高代码的可维护性。"
}
测试插件
重启 EasyBot 后,你应该能看到类似以下的输出:
[2024-01-01 12:00:00] 多文件插件被加载
[2024-01-01 12:00:00] [2024-01-01 12:00:00] 多文件插件已启用
[2024-01-01 12:00:02] 当前时间: 2024-01-01 12:00:02
[2024-01-01 12:00:02] 随机数 (1-10): 7
[2024-01-01 12:00:02] 插件信息: 我的多文件插件 v1.0.0
最佳实践
1. 目录结构建议
plugin/
├── manifest.json
├── main.js
├── utils/
│ ├── helper.js
│ └── config.js
├── handlers/
│ ├── commands.js
│ └── events.js
├── models/
│ └── player.js
└── services/
└── database.js
2. CommonJS 导出规范
function myFunction() {}
const myConstant = 'value';
module.exports = { myFunction, myConstant };
3. 导入最佳实践
const { formatTime, randomInt } = require('./utils/helper.js');
const { getConfig: getPluginConfig } = require('./utils/config.js');
const { config } = require('./utils/config.js');
4. 避免循环依赖
// A.js
const { functionB } = require('./B.js');
// B.js
const { functionA } = require('./A.js');
提示
按功能拆分文件能让插件更清晰、可维护、可测试。
注意
- 使用 CommonJS(
require、module.exports) - 路径以当前文件为基准,建议显式写
.js - 避免循环依赖
- 将所有依赖文件打包到插件中
- ESM 支持有限,请优先选择 CommonJS
遇到麻烦了?
我们提供有偿代安装服务,解决您的环境配置烦恼。