跳到主要内容
版本:2.0.0

多文件模块化开发(CommonJS)

当插件变得复杂时,将所有代码写在一个 main.js 中会变得难以维护。EasyBot 插件运行环境以 CommonJS 为主,ES 模块支持非常有限。推荐使用 CommonJS 的 requiremodule.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 支持现状

ES 模块在 EasyBot 中支持有限,不建议在插件中直接使用 import/export。如确有需要,请在打包阶段转换为 CommonJS,或在受控环境中使用 .mjs 并谨慎验证。

更新插件清单

更新 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(requiremodule.exports
  • 路径以当前文件为基准,建议显式写 .js
  • 避免循环依赖
  • 将所有依赖文件打包到插件中
  • ESM 支持有限,请优先选择 CommonJS