-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
136 lines (109 loc) · 3.74 KB
/
index.js
File metadata and controls
136 lines (109 loc) · 3.74 KB
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
136
var fs = require('fs');
var path = require('path');
/**
lightRequireCompile
@param {FilePath} mainMod The main js
@param {FilePath} outputFile The output target file
@param {String} exportName The global export name, default won't exposed global
*/
function lightRequireCompile(mainMod,outputFile,exportName) {
var all = findModules(mainMod);
var main = all.main;
var modules = all.modules;
// printModules(modules,0);
// console.log(modules.join("\n"));
var vars = modules.map(function (m){return m.module_id}).concat(['_tmp']);
var prologue = '\n(function () {var '+vars.join(',')+';\n',
epilogue = (exportName?'\nthis.'+exportName+' = '+main.module_id+'\n':'') +
'\n})();\n';
var modCodes = modules.map(wrapModule);
var code = prologue + modCodes.join("\n") + epilogue;
if (outputFile === "-") {
console.log(code);
} else {
fs.writeFileSync(outputFile,code);
}
}
function wrapModule(mod,outputFile) {
return "\n_tmp={exports:{}};\n(function (module) {\n" +
mod.content +
"\n})(_tmp);\n" +
mod.module_id + " = _tmp.exports;\n";
}
function printModules(modules,indent) {
modules.forEach(function (mod) {
console.log(repeats(" ",indent)+"|-"+mod.name);
printModules(mod.deps,indent+1);
});
}
function repeats(s,n) {return new Array(n+1).join(s)}
function findModules(main) {
var modules = [], cache = Object.create(null);
var depFlow = ["#TOP"];
depFlow.toString = function () {return this.join("\n->")};
var mainMod = traverse(main,process.cwd(),depFlow,modules,cache);
return {main:mainMod,modules:modules};
}
var requireRegex = /\brequire\s*\(\s*(['"])(.+)\1\s*\)\s*/g;
function traverse(modName,cwd,depFlow,modules,cache) {
var mod = readModule(modName,cwd,cache);
if (!mod) {
throw new Error("Module ["+ modName + "] not found when processing modules " + depFlow );
}
if (mod._traversed) return mod;
depFlow = depFlow.concat(mod.name);
if (mod._traversing) {
console.log(modules)
throw new Error("Cyclic dependencies detected:" + depFlow)
}
mod._traversing = true;
var deps = [];
mod.content = mod.content.replace(
requireRegex,
function (_,_1,depModName) {
var depMod = traverse(depModName,mod.dir,depFlow,modules,cache);
deps.push(depMod);
return " "+depMod.module_id+" ";
});
mod._traversed = true;
mod._traversing = false;
mod.deps = deps;
modules.push(mod);
return mod;
}
var _AUTO_INCREMENT_ID = 1;
function guid() {
_AUTO_INCREMENT_ID = (_AUTO_INCREMENT_ID + 1) | 0;
var a = _AUTO_INCREMENT_ID.toString(36);
var date = (+(new Date)).toString(36) + a;
var rand = ((Math.random() * 1e8) | 0).toString(36);
return '_'+(date + rand).toUpperCase();
}
function readModule(modName,cwd,cache) {
var modFile = modName;
if (modFile.slice(-3)!=='.js') modFile += '.js';
modFile = path.resolve(cwd,modFile);
if (!fs.existsSync(modFile)) return null;
modFile = fs.realpathSync(modFile);
return cache[modFile] = cache[modFile] || new Module(modName,modFile);
}
function Module(modName,modFile) {
this.name = modName;
this.file = modFile;
this.dir = path.dirname(modFile);
this.module_id = (modName + guid()).replace(/[^\w$]+/g,'_').replace(/^[^a-z_]+/i,'_').replace(/_+/g,'_');
Object.defineProperty(this,'content',{
enumerable:false,
writable:true,
value:fs.readFileSync(modFile,{encoding:'utf-8'})
});
if (this.content.slice(0,2) === '#!') { // remove shebang
this.content = this.content.replace(/^#![^\n\r]+/,'\n');
}
this._traversing = false;
this._traversed = false;
}
Module.prototype.toString = function () {
return this.name;
};
module.exports = lightRequireCompile