-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathdeploy.js
More file actions
355 lines (325 loc) · 10.9 KB
/
deploy.js
File metadata and controls
355 lines (325 loc) · 10.9 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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
/**
* Builder.js
* @type {{}}
*/
const Fs = require('fs');
const Path = require('path');
const uglify = require('uglify-js');
const babel = require('babel-core');
const cheerio = require('cheerio');
// 发布文件夹
let distDir = 'dist';
// 排除文件夹或文件
// excludes.copy 不复制文件夹或文件列表
// excludes.mini 不压缩文件列表。需要目录文件相对根目录的全路径,如:./script/xx/xx.js
let excludes = {
'copy': [
'.gitignore',
'.DS_Store',
'deploy.js',
'package.json',
'package-lock.json',
'README.md',
'.git',
'.idea',
'node_modules',
'dist'
],
'mini': [
]
};
//
let App = {
view: {
/**
* 继承
* @param name
* @param func
*/
extend: function(name, func) {
func.prototype = App;
this[name] = new func();
},
/**
* 创建View方法
* @param model
* @param name
*/
buildViewContent: function(model, name) {
let key = model + "." + name;
if (!this.hasOwnProperty(key)) {
let content = this[model][name](),
_html = [];
let txt = ["App.view.extend('"+ model +"."+name+"', function() {"];
txt.push("this.init = function(data) {");
txt.push("var html = '';");
content = content.split('\n');
for (let i in content) {
_html.push(this.parse(content[i]));
}
txt.push(_html.join(""));
txt.push("return html;");
txt.push("}");
txt.push("});");
return txt.join('');
}
},
/**
* 解析模板
* @param line 行代码
*/
parse: function(line) {
if (!line || line === '') {
return null;
}
let result = line.trim().replace(new RegExp(/'/g), "\\'"),
parseStatus = false;
/**
* 解析变量
*/
let parseData = function() {
let item,
patt = /\{\{ (.+?) \}\}/i;
while (item = patt.exec(result)) {
result = result.replace(item[0], "'+" + item[1].replace(new RegExp(/\\/g), "") + "+'");
}
};
/**
* 解析定义
*/
let parseVer = function() {
let item,
patt = /\{\{ var (.+?) \}\}/i;
while (item = patt.exec(result)) {
parseStatus = true;
result = result.replace(item[0], "var " + item[1].replace(new RegExp(/\\/g), "") + ";");
}
};
/**
* 解析条件
*/
let parseCondition = function() {
let item,
patt = /\{\{ if (.+?) \}\}/i;
while (item = patt.exec(result)) {
parseStatus = true;
result = result.replace(item[0], "if("+ item[1].replace(new RegExp(/\\/g), "") +"){");
}
patt = /\{\{ else if (.+?) \}\}/i;
while (item = patt.exec(result)) {
parseStatus = true;
result = result.replace(item[0], "} else if("+ item[1].replace(new RegExp(/\\/g), "") +"){");
}
patt = /\{\{ else \}\}/i;
while (item = patt.exec(result)) {
parseStatus = true;
result = result.replace(item[0], "} else {");
}
};
/**
* 解析循环
*/
let parseLoop = function() {
let item,
patt = /\{\{ for (.+?) \}\}/i;
while (item = patt.exec(result)) {
parseStatus = true;
result = result.replace(item[0], "for("+ item[1].replace(new RegExp(/\\/g), "") +"){");
}
};
/**
* 解析结束
*/
let parseEnd = function() {
let item,
patt = /\{\{ end \}\}/i;
while (item = patt.exec(result)) {
parseStatus = true;
result = result.replace(item[0], "}");
}
};
parseLoop();
parseCondition();
parseEnd();
parseVer();
parseData();
if (!parseStatus) {
result = "html += '" + result + "';";
}
return result;
}
}
};
(function() {
/**
* 清空目录
* @param targetDir
*/
let delDir = function (targetDir) {
let paths = Fs.readdirSync(targetDir);
if (paths) {
paths.forEach(function (path) {
let targetPath = targetDir + '/' + path,
stat = Fs.lstatSync(targetPath);
if (stat.isFile()) {
// 如果是文件,直接删除
console.log('删除文件: ' + targetPath);
Fs.unlinkSync(targetPath);
} else if (stat.isDirectory()) {
delDir(targetPath);
}
});
Fs.rmdirSync(targetDir);
}
};
/**
* 压缩JS
* @params sourceList 来源JS文件
* @params target 输出目标JS
*/
let jsMini = function (sourceList, target) {
try {
let r = babel.transformFileSync(sourceList, {presets: ['es2015']});
let result = uglify.minify(r.code);
Fs.writeFileSync(target, result['code'], 'utf8');
} catch (e) {
console.error(e);
}
};
/**
* 拷贝目录
* @param sourceDir 源目录
* @param targetDir 目标目录
*/
let deploy = function (sourceDir, targetDir) {
let paths = Fs.readdirSync(sourceDir);
if (paths) {
paths.forEach(function (path) {
if (excludes.copy.indexOf(path) !== -1) {
return false;
}
let sourcePath = sourceDir + '/' + path,
targetPath = targetDir + '/' + path,
stat = Fs.lstatSync(sourcePath);
if (stat.isFile()) {
let extName = Path.extname(sourcePath).slice(1);
let readable, writeable;
if (Fs.existsSync(targetDir)) {
if (!sourcePath.endsWith('view.js') && !sourcePath.endsWith('index.html') && !sourcePath.endsWith('manifest.json')) {
console.log('Copy file: ' + sourcePath + ' => ' + targetPath);
if (extName === 'js' && excludes.mini.indexOf(sourcePath) === -1) {
jsMini(sourcePath, targetPath);
} else {
readable = Fs.createReadStream(sourcePath);
writeable = Fs.createWriteStream(targetPath);
readable.pipe(writeable);
}
}
} else {
console.log('Mkdir: ' + targetDir);
Fs.mkdirSync(targetDir);
readable = Fs.createReadStream(sourcePath);
writeable = Fs.createWriteStream(targetPath);
readable.pipe(writeable);
}
} else if (stat.isDirectory()) {
if (!Fs.existsSync(targetPath)) {
console.log('Mkdir: ' + targetPath);
Fs.mkdirSync(targetPath);
}
deploy(sourcePath, targetPath);
}
});
}
};
let getStructure = function() {
let indexText = Fs.readFileSync('index.html', 'utf-8'),
$ = cheerio.load(indexText),
views = [],
viewContents = [];
//
if (!$) {
console.log('build index dom failed');
return false;
}
$('head').find('script').each(function() {
let modulePath = $(this).attr('src');
if (modulePath.endsWith('view.js')) {
views.push(modulePath);
}
});
//
for (var i = 0; i < views.length; i++) {
let content = Fs.readFileSync(views[i], 'utf-8');
eval(content);
}
//
for (var module in App.view) {
if (App.view.hasOwnProperty(module) && ['exend', 'buildViewContent', 'parse'].indexOf(module) === -1) {
let ms = App.view[module];
for (var name in ms) {
if (ms.hasOwnProperty(name)) {
let c = App.view.buildViewContent(module, name);
viewContents.push(c);
}
}
}
}
//
return viewContents;
};
let buildView = function() {
console.log('build view start...');
let viewContents = getStructure();
Fs.writeFileSync(distDir + '/scripts/view.js', viewContents.join(''), 'utf-8');
console.log('build view sucess.');
};
let buildManifest = function() {
console.log('build manifest.json start...');
let f = Fs.readFileSync('manifest.json', 'utf-8');
f = JSON.parse(f);
//
delete f.content_security_policy;
//
Fs.writeFileSync(distDir + '/manifest.json', JSON.stringify(f), 'utf-8');
console.log('build manifest.json success.');
};
this.buildIndex = function() {
console.log('build index.html start...');
let indexText = Fs.readFileSync('index.html', 'utf-8'),
$ = cheerio.load(indexText);
//
if (!$) {
console.log('build index dom failed');
return false;
}
//
$('head').find('script').each(function() {
let modulePath = $(this).attr('src');
if (modulePath.endsWith('view.js')) {
$(this).remove();
}
});
$('head').append('<script src="scripts/view.js" type="text/javascript"></script>');
Fs.writeFileSync(distDir + '/index.html', $.html(), 'utf-8');
console.log('build index.html success.');
};
(function() {
console.log('Builder run.');
//
// check dir
if (Fs.existsSync(distDir)) {
//
delDir(distDir);
}
Fs.mkdirSync(distDir);
//
deploy('.', './' + distDir);
//
buildView();
//
buildIndex();
//
buildManifest();
})();
})();