本次利用装饰器配合require实现装饰器配置自执行ts模块程序。实现本功能的目的是通过指定参数来配置哪些模块运行,该模块主要实现逻辑如下
- 扫描指定目录,获取目录下所有ts文件
- 判断是否是文件或文件夹
- 识别文件或对象中是否包含
test
函数 @Init
识别标记,并决定哪些程序运行

目录结构
arduino
.
├── main.ts 入口
├── modules 各种模块
│ ├── config.ts 配置
│ ├── default_modules
│ ├── generator_await
│ ├── stream
│ ├── test.interface.ts
│ ├── test_modules
│ └── thread_model
└── utils 工具
├── decorator.ts 装饰器文件
└── index.ts
main.ts
该文件是整个函数的入口,MODULES
变量指定扫描的入口目录
ts
import { resolve } from "path";
import { readFile } from "./utils";
const basePath = resolve(__dirname);
const MODULES = "./modules";
(async function () {
const path = resolve(basePath, MODULES);
readFile(path);
})();
readFile
函数
该函数的主要功能如下
- 扫描传入的的路径,若是ts文件,则立即执行,
- 否则扫描文件并判断是否应该执行该文件,
- 如果是文件夹,则递归执行该函数
- 如果是文件,则跳转步骤1
ts
/**
* 运行模块
* @param modulePath 模块路径
*/
export async function readFile(path: string) {
const isTsFile = /\.ts$/
if(await isFile(path)){
if (isTsFile.test(path)) {
runCode(path);
}
return
}
const modules = fs.readdirSync(path);
for (const item of modules) {
const modulePath = resolve(path, item);
if (await isFile(modulePath)) {
if (!isTsFile.test(item)) {
continue;
}
runCode(modulePath);
} else {
await readFile(modulePath);
}
}
}
isFile
函数
该函数通过对lstat函数进行封装,判断是否是文件夹,用fs.statSync
效果是一样的
ts
// 判断是否是文件夹
export function isFile(path: string) {
return new Promise((res) => {
try {
fs.lstat(path, (err, stat) => {
if (err) {
console.error(err);
return res(false);
}
if (stat.isFile()) {
res(true);
} else {
res(false);
}
});
} catch (e) {
console.error(e);
return res(false);
}
});
}
runCode
函数
该函数的功能是运行传入的经过校验的ts文件,该文件会通过require函数获取ts文件,并判断该文件是函数或默认导出,然后否包含测试运行的test
函数,如果包含则表示可运行,具体执行通过装饰器混入的isRun
标识是否需要执行,
ts
export function runCode(script: string): void {
const Test = require(script);
try {
if (isFunction(Test.test)) {
Test.test();
} else if (isFunction(Test.default)) {
const testObj = new Test.default();
if (testObj?.test) {
if (!testObj.isRun) {
return;
}
testObj.test();
} else if (isFunction(Test)) {
Test();
}
}
} catch (e) {
console.error(e);
}
}
Init
装饰器
标识是否需要执行,如果isRun
为true,则表示执行,否则不需要执行
ts
export function Init(flag:boolean) {
return function (target:any){
target.prototype.isRun = flag
}
}
Test
测试接口类
该类用于为实现了Test
接口的类提供自动执行入口
ts
export interface Test {
test():void
}
使用
通过实现test函数标识扫描入口,并通过@Init
标识扫描的类是否需要运行
ts
import os from 'os'
import { Init } from '../../../utils/decorator';
import { OS } from '../../config';
import type { Test } from '../../test.interface';
@Init(OS)
export default class OsModule implements Test {
test () {
console.log('获取芯片架构', os.arch())
console.log(os.cpus().map(item=>item.speed+'MHZ'));
console.log(os.devNull);
console.log('返回内存大小端',os.endianness());
console.log('返回空闲内存',os.freemem()/1024/1024/8);
console.log('返回当前进程优先级',os.getPriority());
console.log('主机名',os.hostname());
console.log('返回操作系统的平均负载数组,分别是1分钟5分钟 15分钟',os.loadavg());
// console.log('返回网络接口对象',os.networkInterfaces());
console.log('返回操作系统的平台字符串',os.platform());
console.log('返回操作系统',os.release());
console.log('返回操作系统默认的临时文件目录', os.tmpdir());
console.log('操作系统内存总量', os.totalmem()/1024/1024/8);
console.log('返回操作系统的运行时间,单位秒',os.uptime());
console.log('返回操作系统的用户信息',os.userInfo());
console.log('返回操作系统的内核版本',os.version());
console.log('操作系统常量',os.constants);
}
}
变量OS
通过config.ts
进行维护
arduino
export const OS = true
export const EVENT = false
export const WORK_THREAD = false
export const SQL_GENERATOR= false
export const THREAD = false
export const GENERATOR_AWAIT = false
export const STREAM = false
测试效果
css
取芯片架构 x64
[ '3994MHZ', '3989MHZ', '3982MHZ', '3992MHZ', '3992MHZ', '4000MHZ', '3997MHZ', '3998MHZ', '3992MHZ', '3977MHZ', '3985MHZ', '3984MHZ', '3998MHZ', '3999MHZ', '3998MHZ', '3999MHZ', '3970MHZ', '3993MHZ', '3970MHZ', '3985MHZ', '3999MHZ', '3994MHZ', '3999MHZ', '3999MHZ', '4000MHZ', '3998MHZ', '3985MHZ', '3989MHZ', '3999MHZ', '3998MHZ', '3999MHZ', '3998MHZ']
/dev/null
返回内存大小端 LE
返回空闲内存 2186.59228515625
返回当前进程优先级 0
主机名 XXX-systemproductname
返回操作系统的平均负载数组,分别是1分钟5分钟 15分钟 [ 2.28, 2.83, 2.86 ]
返回操作系统的平台字符串 linux
返回操作系统 6.1.62-1-lts
返回操作系统默认的临时文件目录 /tmp
操作系统内存总量 8025.30126953125
返回操作系统的运行时间,单位秒 1095773.19
返回操作系统的用户信息 {
uid: 1000,
gid: 1001,
username: 'XXX',
homedir: '/home/XXX',
shell: '/usr/bin/zsh'
}
返回操作系统的内核版本 #1 SMP PREEMPT_DYNAMIC Thu, 09 Nov 2023 17:21:17 +0000
操作系统常量 [Object: null prototype] {