-
Notifications
You must be signed in to change notification settings - Fork 391
Expand file tree
/
Copy pathloader.ts
More file actions
158 lines (132 loc) · 3.21 KB
/
Copy pathloader.ts
File metadata and controls
158 lines (132 loc) · 3.21 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* Loader Module
*/
import * as fs from 'fs';
import * as path from 'path';
/**
* Load modules under the path.
* If the module is a function, loader would treat it as a factory function
* and invoke it with the context parameter to get a instance of the module.
* Else loader would just require the module.
* Module instance can specify a name property and it would use file name as
* the default name if there is no name property. All loaded modules under the
* path would be add to an empty root object with the name as the key.
*
* @param {String} mpath the path of modules. Load all the files under the
* path, but *not* recursively if the path contain
* any sub-directory.
* @param {Object} context the context parameter that would be pass to the
* module factory function.
* @return {Object} module that has loaded.
*/
export function load(mpath: string, context : any, reload : boolean)
{
if (!mpath)
{
throw new Error('opts or opts.path should not be empty.');
}
try
{
mpath = fs.realpathSync(mpath);
} catch (err)
{
throw err;
}
if (!isDir(mpath))
{
throw new Error('path should be directory.');
}
return loadPath(mpath, context, reload);
};
export function loadFile(fp: string, context : any, reload : boolean)
{
let m = reload ? requireUncached(fp) : require(fp);
if (!m)
{
return;
}
if (typeof m.default === 'function')
{
// if the module provides a factory function
// then invoke it to get a instance
m = m.default(context);
}
else
{
throw new Error(`${fp} must define export default function(context){}`);
}
return m;
};
export function loadPath(path : string, context : any, reload : boolean)
{
let files = fs.readdirSync(path);
if (files.length === 0)
{
console.warn('path is empty, path:' + path);
return;
}
if (path.charAt(path.length - 1) !== '/')
{
path += '/';
}
let fp, fn, m, res: {[key:string]:any} = {};
for (let i = 0, l = files.length; i < l; i++)
{
fn = files[i];
fp = path + fn;
if (!isFile(fp) || !checkFileType(fn, '.js'))
{
// only load js file type
continue;
}
m = loadFile(fp, context, reload);
if (!m)
{
continue;
}
let name = m.name || getFileName(fn, '.js'.length);
res[name] = m;
}
return res;
};
/**
* Check file suffix
* @param fn {String} file name
* @param suffix {String} suffix string, such as .js, etc.
*/
export function checkFileType(fn : string, suffix : string)
{
if (suffix.charAt(0) !== '.')
{
suffix = '.' + suffix;
}
if (fn.length <= suffix.length)
{
return false;
}
let str = fn.substring(fn.length - suffix.length).toLowerCase();
suffix = suffix.toLowerCase();
return str === suffix;
};
let isFile = function (path : string)
{
return fs.statSync(path).isFile();
};
let isDir = function (path : string)
{
return fs.statSync(path).isDirectory();
};
let getFileName = function (fp : string, suffixLength : number)
{
let fn = path.basename(fp);
if (fn.length > suffixLength)
{
return fn.substring(0, fn.length - suffixLength);
}
return fn;
};
let requireUncached = function (module : string)
{
delete require.cache[require.resolve(module)]
return require(module)
}