import fs from "fs";
import path from "path";
import vm from "vm";
export class LoadComponent {
componentsPath: string = path.resolve("../first/components/");
componentName: string = "";
componentIndex: string = "";
loadCodeFile() {
this.componentIndex = path.join(
this.componentsPath,
this.componentName,
"res/js/index.js"
);
const file = fs.readFileSync(this.componentIndex).toString();
return file;
}
loadComponent(componentName: string) {
this.componentName = componentName;
const componentFolder = fs
.readdirSync(this.componentsPath)
.find((val) => val === componentName);
if (componentFolder === undefined) throw Error("component does not exist!");
interface sample {
name: string;
params: string[];
entity: (...args: any) => any;
}
// mock require
const repository: sample[] = [];
const collectParams = (arr: string[], exports: object) => {
return arr.map((val) => {
if (val === "exports") return exports;
val = path.join(this.componentsPath, val);
if (cache[val]) return cache[val];
let rep = repository.find((rep) => rep.name === val);
if (rep === undefined) {
if (!fs.existsSync(val)) return undefined;
aux.window.modulePath = val;
const defineModule = fs.readFileSync(val).toString();
const script = new vm.Script(defineModule);
vm.createContext(aux);
script.runInContext(aux);
rep = repository.find((rep) => rep.name === val) as sample;
}
let exportsObj: any = {};
const ret = rep.entity(...collectParams(rep.params, exportsObj));
cache[val] = ret ? ret : exportsObj;
return cache[val];
});
};
const moduleRequire = (...args: any) => {
let prep: any[] = [];
if (Object.prototype.toString.call(args[0]) === "[object Array]") {
const first = args[0] as string[];
const exportObj = {};
prep = collectParams(first, exportObj);
}
if (Object.prototype.toString.call(args[1]) === "[object Function]") {
args[1](...prep);
}
};
const cache: { [moduleName: string]: any } = {
require: moduleRequire,
};
// mock require end
const script = new vm.Script(
this.loadCodeFile() +
`\n require(['/${this.componentName}/res/js/index.js'], (module)=>{ window.auxClass = Object.values(module)[0] })`
);
const aux = {
window: {
auxClass: null,
modulePath: this.componentIndex,
},
require: moduleRequire,
define: (params: string[], fun: (...args: any) => undefined | object) => {
repository.push({
name: aux.window.modulePath,
params,
entity: fun,
});
},
// console,
};
vm.createContext(aux);
script.runInContext(aux);
return aux.window.auxClass;
}
}
loadTest() {
const load = new LoadComponent();
const com = load.loadComponent("head");
console.log(com);
}
标签:const,string,val,nodejs,rep,AMD,return,aux,加载 From: https://www.cnblogs.com/laremehpe/p/18087678