-
Notifications
You must be signed in to change notification settings - Fork 159
/
Copy pathmoduleLoader.js
135 lines (115 loc) · 4 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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));
// 创建一个函数,接受一个回调来模拟同步行为
function fetchModuleCodeSync(jsm_path) {
let result = null;
let error = null;
// 返回一个 Promise,用于等待异步请求完成
return new Promise((resolve, reject) => {
axios.get(jsm_path)
.then((response) => {
result = response.data; // 保存结果
resolve(result); // 成功时 resolve
})
.catch((err) => {
error = new Error(`Error fetching module from URL: ${err.message}`); // 错误信息
reject(error); // 失败时 reject
});
});
}
// 模拟同步的处理方法
function requireModule(jsm_path) {
let result = null;
let error = null;
// 阻塞直到 Promise 完成
try {
result = fetchModuleCodeSync(jsm_path); // 等待异步请求完成
result.then(data => {
console.log("Module Code:", data);
}).catch(err => {
throw err;
});
} catch (err) {
error = err;
console.error(error.message);
}
return result; // 返回模块内容
}
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;
*/
js_code = requireModule(jsm_path);
} 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;
}
};