-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpack.js
114 lines (89 loc) · 2.76 KB
/
pack.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
const fs = require('fs');
const path = require('path');
// 匹配 require
const REQ_RULE = /(=|^|\s)require\(\s*(['"])([^'"]+)['"]\s*\)/;
// 需要优化的 enum 变量
const OPTI_ENUM = {
ExprType: require('../src/parser/expr-type'),
NodeType: require('../src/view/node-type'),
DataChangeType: require('../src/runtime/data-change-type')
};
const OPTI_ENUM_REPLACE_REG = new RegExp(
'(' + Object.keys(OPTI_ENUM).join('|') + ')\\.([A-Z_]+)',
'g'
);
function optiEnumReplaceFn(match, type, prop) {
if (!(prop in OPTI_ENUM[type])) {
throw new Error(`[ENUM OPTI ERROR] ${type} has not property ${prop}`);
}
return OPTI_ENUM[type][prop];
}
function pack(rootDir, mainFile) {
let srcDir = path.resolve(rootDir, 'src');
mainFile = mainFile || path.resolve(srcDir, 'main.js');
let deps = depAnalyse(mainFile);
return {
content: fileContent(mainFile, 1, []).replace(
'// #[main-dependencies]',
deps.map(dep => fileContent(dep)).join('\n\n')),
deps: deps,
base: mainFile
};
}
function depAnalyse(targetFile) {
let deps = [];
let depsIndex = {};
function analyse(file) {
if (depsIndex[file]) {
if (depsIndex[file] === 1) {
if (file !== targetFile) {
deps.push(file);
}
depsIndex[file] = 2;
}
return;
}
depsIndex[file] = 1;
let lines = fs.readFileSync(file, 'UTF-8').split(/\r?\n/);
lines.forEach(line => {
let requireMatch = REQ_RULE.exec(line);
if (requireMatch) {
let dep = resolveDep(requireMatch[3], file);
analyse(dep);
}
});
if (file !== targetFile && depsIndex[file] !== 2) {
deps.push(file);
}
depsIndex[file] = 2;
}
analyse(targetFile, 1);
return deps;
}
function resolveDep(dep, inFile) {
dep = path.resolve(path.dirname(inFile), dep);
if (path.extname(dep) !== '.js') {
dep += '.js';
}
return dep;
}
/**
* 读取源码文件内容并执行一系列处理
*
* @param {string} file 文件路径
* @param {boolean} dontIgnoreExports 产出是否不忽略 exports 语句
* @return {string} 处理后的源码
*/
function fileContent(file, dontIgnoreExports) {
return fs.readFileSync(file, 'UTF-8').split(/\r?\n/)
.map(line => {
if (/(=|^|\s)require\(['"]/.test(line)
|| (!dontIgnoreExports && /^\s*(module\.)?exports\s+=/.test(line))
) {
return '// ' + line;
}
return line.replace(OPTI_ENUM_REPLACE_REG, optiEnumReplaceFn);
})
.join('\n');
}
exports = module.exports = pack;