-
Notifications
You must be signed in to change notification settings - Fork 159
/
Copy pathmoduleLoader.js
92 lines (77 loc) · 2.79 KB
/
moduleLoader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { readFileSync, existsSync } from 'fs';
import path from "path";
import { fileURLToPath } from "url";
import axios from "./axios.min.js"; // 引入 axios
import deasync from "deasync"; // 使用 deasync 实现同步行为
const __dirname = path.dirname(fileURLToPath(import.meta.url));
globalThis.$ = {
/**
* 加载指定的 JavaScript 模块
* @param {string} jsm_path - 模块路径或网络地址
* @returns {any} - 模块的导出内容
* @throws {Error} - 如果路径不存在或模块未导出内容,则抛出错误
*/
require(jsm_path) {
let js_code;
// 检测是否为网络地址
const isURL = /^(https?:)?\/\//.test(jsm_path);
if (isURL) {
// 从网络同步获取模块代码
let error = null;
let result = null;
axios.get(jsm_path)
.then((response) => {
result = response.data;
})
.catch((err) => {
error = new Error(`Error fetching module from URL: ${err.message}`);
});
// 等待 Promise 解决
deasync.loopWhile(() => !result && !error);
if (error) throw error;
js_code = result;
} else {
// 本地路径处理
jsm_path = path.join(__dirname, '../js', jsm_path);
// 检查文件是否存在
if (!existsSync(jsm_path)) {
throw new Error(`Module not found: ${jsm_path}`);
}
// 检查基本文件名是否以 "_lib" 开头
const baseName = path.basename(jsm_path);
if (!baseName.startsWith('_lib')) {
throw new Error(`Invalid module name: ${baseName}. Module names must start with "_lib".`);
}
// 读取文件内容
js_code = readFileSync(jsm_path, 'utf8');
}
// 创建沙箱环境
const sandbox = {
console,
$,
exports: {},
module: { exports: {} }
};
try {
// 在沙箱中执行代码
const script = `
(function () {
try {
${js_code}
} catch (err) {
throw new Error("Error executing module script: " + err.message);
}
})();
`;
eval(script);
} catch (error) {
throw new Error(`Failed to execute script: ${error.message}`);
}
// 检查是否正确设置了 $.exports
if (!$.exports || Object.keys($.exports).length === 0) {
throw new Error(`Module did not export anything.`);
}
// 返回导出的内容
return $.exports;
}
};