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 | "use strict";
|
32 |
|
33 | var path =require('path');
|
34 | var fs = require('fs');
|
35 | var util = require('util');
|
36 | var crypto = require('crypto');
|
37 | var vfs = require('vinyl-fs');
|
38 | var through = require('through-gulp');
|
39 | var gutil = require('gulp-util');
|
40 |
|
41 |
|
42 | var startReg = /<!--\s+build:\w+\s+\/?[^\s]+\s+-->/gim;
|
43 | var startMirrorReg = /<!--\s+build:\w+\s+\/?[^\s]+\s+-->/i;
|
44 | var endReg = /<!--\s*endbuild\s*-->/gim;
|
45 | var endMirrorReg = /<!--\s*endbuild\s*-->/i;
|
46 | var splitReg = /<!--\s+split\s+-->/gim;
|
47 | var jsReg = /<\s*script\s+.*?src\s*=\s*("|')([^"']+?)\1.*?><\s*\/\s*script\s*>/i;
|
48 | var cssReg = /<\s*link\s+.*?href\s*=\s*("|')([^"']+)\1.*?>/i;
|
49 | var spaceReg = /^\s*$/;
|
50 | var typeReg = /<!--\s+build:(\w+)\s+\/?[^\s]+\s+-->/i;
|
51 | var pathReg = /<!--\s+build:\w+\s+(\/?[^\s]+)\s+-->/i;
|
52 | var utils = {};
|
53 |
|
54 |
|
55 | utils._stylesheet = ['css', 'less', 'stylus', 'sass'];
|
56 | utils._script = ['js', 'coffee', 'typescript', 'jsx'];
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | utils.getSplitBlock = function(string) {
|
64 | return string.split(splitReg);
|
65 | };
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 | utils.getBlockType = function(block) {
|
73 | return typeReg.exec(block)[1];
|
74 | };
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 | utils.getBlockPath = function(block) {
|
82 | return pathReg.exec(block)[1];
|
83 | };
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | utils.getScriptPath = function(script) {
|
94 | if (jsReg.test(script)) return jsReg.exec(script.replace(/^\s*/, ''))[2];
|
95 | gutil.log(gutil.colors.green('failed resolve source path from'), gutil.colors.green(script), 'the block type refers script', '\n');
|
96 | return null;
|
97 | };
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | utils.getLinkPath = function(link) {
|
108 | if (cssReg.test(link)) return cssReg.exec(link.replace(/^\s*/, ''))[2];
|
109 | gutil.log(gutil.colors.green('failed resolve source path from'), gutil.colors.green(link), 'the block type refers link', '\n');
|
110 | return null;
|
111 | };
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | utils.getReplacePath = function(line, mode) {
|
121 | if (utils._script.indexOf(mode) !== -1) return utils.getScriptPath(line);
|
122 | if (utils._stylesheet.indexOf(mode) !== -1) return utils.getLinkPath(line);
|
123 | return null;
|
124 | };
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 | utils.getBlockFilePath = function(block) {
|
140 | return block
|
141 | .replace(startReg, '')
|
142 | .replace(endReg, '')
|
143 | .split('\n')
|
144 | .filter(function(value) {
|
145 | return !spaceReg.test(value);
|
146 | })
|
147 | .map(function(value) {
|
148 | switch (true) {
|
149 | case utils._script.indexOf(utils.getBlockType(block)) !== -1 :
|
150 | return utils.getScriptPath(value);
|
151 | case utils._stylesheet.indexOf(utils.getBlockType(block)) !== -1 :
|
152 | return utils.getLinkPath(value);
|
153 | case utils.getBlockType(block) === 'replace' :
|
154 | return utils.getReplacePath(value, path.extname(utils.getBlockPath(block)).slice(1));
|
155 | case utils.getBlockType(block) === 'remove' :
|
156 | return null;
|
157 | default :
|
158 | return null;
|
159 | }
|
160 | })
|
161 | .filter(function(value) {
|
162 | return value !== null;
|
163 | });
|
164 | };
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 | utils.getBlockStructure = function(block) {
|
172 | return {
|
173 | type: utils.getBlockType(block),
|
174 | destiny: utils.getBlockPath(block),
|
175 | files: utils.getBlockFilePath(block)
|
176 | }
|
177 | };
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 | utils.isBlock = function(block) {
|
185 | return startMirrorReg.test(block) && endMirrorReg.test(block);
|
186 | };
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 | utils.getBlockFileSource = function(blocks) {
|
194 | return blocks
|
195 | .filter(function(block) {
|
196 | return utils.isBlock(block);
|
197 | })
|
198 | .map(function(block) {
|
199 | return utils.getBlockStructure(block);
|
200 | });
|
201 | };
|
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 | utils.resolvePostfix = function(postfix, block, debug) {
|
211 | if (postfix === null || typeof postfix === 'undefined') return '';
|
212 | if (util.isString(postfix) && postfix !== 'md5') return '?' + postfix;
|
213 |
|
214 | var content;
|
215 | var source = utils.prerenderOriginPath(utils.getBlockFilePath(block), debug);
|
216 |
|
217 | content = source.reduce(function(prev, current) {
|
218 | try {
|
219 | return Buffer.concat([prev, fs.readFileSync(current)]) ;
|
220 | } catch (err) {
|
221 | gutil.log(gutil.colors.red('The file ' + current + ' not exist, maybe cause postfix deviation'));
|
222 | return prev;
|
223 | }
|
224 | }, new Buffer(''));
|
225 |
|
226 | if (util.isFunction(postfix)) {
|
227 | return '?' + utils.escape(postfix.call(null, content));
|
228 | }
|
229 |
|
230 | if (postfix === 'md5') {
|
231 | var hash = crypto.createHash('md5');
|
232 | hash.update(content);
|
233 | return '?' + hash.digest('hex');
|
234 | }
|
235 |
|
236 | return '';
|
237 | };
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 | utils.generateTags = function(block, options) {
|
246 | switch (true) {
|
247 | case !utils.isBlock(block):
|
248 | return block;
|
249 | case utils._script.indexOf(utils.getBlockType(block)) !== -1 :
|
250 | return '<script src="' + utils.getBlockPath(block) + utils.resolvePostfix(options.postfix, block, options.debug) + '"></script>';
|
251 | case utils._stylesheet.indexOf(utils.getBlockType(block)) !== -1 :
|
252 | return '<link rel="stylesheet" href="' + utils.getBlockPath(block) + utils.resolvePostfix(options.postfix, block, options.debug) + '"/>';
|
253 | case utils.getBlockType(block) === 'replace' && path.extname(utils.getBlockPath(block)) === '.js' :
|
254 | return '<script src="' + utils.getBlockPath(block) + utils.resolvePostfix(options.postfix, block, options.debug) + '"></script>';
|
255 | case utils.getBlockType(block) === 'replace' && path.extname(utils.getBlockPath(block)) === '.css' :
|
256 | return '<link rel="stylesheet" href="' + utils.getBlockPath(block) + utils.resolvePostfix(options.postfix, block, options.debug) + '"/>';
|
257 | case utils.getBlockType(block) === 'remove' :
|
258 | return null;
|
259 | default :
|
260 | return null;
|
261 | }
|
262 | };
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 | utils.resolveFileSource = function(sources, options) {
|
271 | if (!sources || !options) return false;
|
272 |
|
273 | sources = sources.filter(function(value) {
|
274 | return (utils._script.indexOf(value.type) !== -1 || utils._stylesheet.indexOf(value.type) !== -1) && value.files.length !== 0 && value.destiny;
|
275 | });
|
276 |
|
277 | if (sources.length === 0) return false;
|
278 |
|
279 | for (var i = 0; i < sources.length; i++) {
|
280 | var parser = options[sources[i].type];
|
281 | var files = sources[i].files;
|
282 | var destiny = path.join('./', sources[i].destiny);
|
283 | var stream;
|
284 | if (!parser || parser.length === 0) {
|
285 | stream = utils.pathTraverse(files, null, options.debug).pipe(utils.concat(destiny)).pipe(vfs.dest(path.join('./', options.directory)));
|
286 | } else {
|
287 | stream = utils.pathTraverse(files, parser, options.debug).pipe(utils.concat(destiny)).pipe(vfs.dest(path.join('./', options.directory)));
|
288 | }
|
289 | stream.on('end', function() {
|
290 | var notify = options.notify;
|
291 | notify ? notify.Trigger.emit(notify.Event) : utils.noop();
|
292 | });
|
293 | }
|
294 | };
|
295 |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 |
|
301 |
|
302 | utils.resolveSourceToDestiny = function(blocks, options) {
|
303 | var result = blocks.map(function(block) {
|
304 | return utils.generateTags(block, options);
|
305 | });
|
306 |
|
307 | return result.join('\n');
|
308 | };
|
309 |
|
310 | utils.prerenderOriginPath = function(originPath, debug) {
|
311 | if (util.isString(originPath)) return !debug ? [path.join('./', originPath)] : [path.join('./', 'test/fixture/', originPath)];
|
312 | if (util.isArray(originPath)) {
|
313 | return originPath.map(function(value) {
|
314 | return !debug ? path.join('./', value) : path.join('./', 'test/fixture/', value);
|
315 | });
|
316 | }
|
317 | };
|
318 |
|
319 |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 | utils.pathTraverse = function(originPath, flow, debug) {
|
327 | var destinyPath = utils.prerenderOriginPath(originPath, debug);
|
328 | var stream = vfs.src(destinyPath);
|
329 | if (util.isArray(flow)) {
|
330 | for (var i = 0; i < flow.length; i++) {
|
331 | let generator, options;
|
332 | if (util.isArray(flow[i])) {
|
333 | generator = flow[i][0];
|
334 | options = flow[i][1];
|
335 | }
|
336 | if (util.isFunction(flow[i])) {
|
337 | generator = flow[i];
|
338 | options = {};
|
339 | }
|
340 | stream = stream.pipe(generator(options));
|
341 | }
|
342 | }
|
343 |
|
344 | return stream;
|
345 | };
|
346 |
|
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 |
|
353 |
|
354 |
|
355 |
|
356 |
|
357 |
|
358 |
|
359 |
|
360 |
|
361 | utils.shallowMerge = function(source, destiny) {
|
362 | for (var key in source) {
|
363 | if (source.hasOwnProperty(key)) {
|
364 | destiny[key] = source[key];
|
365 | }
|
366 | }
|
367 |
|
368 | return destiny;
|
369 | };
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
376 | utils.escape = function(string) {
|
377 | return string.toString().replace(/[\n\s]*/gi, '');
|
378 | };
|
379 |
|
380 |
|
381 |
|
382 |
|
383 |
|
384 |
|
385 | utils.streamToPromise = function(stream) {
|
386 | if (util.isUndefined(stream.pipe)) return Promise.reject('argument is not stream');
|
387 |
|
388 | return new Promise(function(resolve, reject) {
|
389 | var destiny = new Buffer('');
|
390 |
|
391 | stream.pipe(through(function(file, encoding, callback) {
|
392 | destiny = Buffer.concat([destiny, file.contents || file]);
|
393 | callback();
|
394 | }, function(callback) {
|
395 | resolve(destiny);
|
396 | callback();
|
397 | }));
|
398 | });
|
399 | };
|
400 |
|
401 |
|
402 |
|
403 |
|
404 |
|
405 |
|
406 | utils.concat = function(fileName) {
|
407 | var assetStorage = new Buffer(0);
|
408 | var separator = new Buffer('\n');
|
409 | return through(function(file, enc, callback) {
|
410 | assetStorage = Buffer.concat([assetStorage, file.contents, separator]);
|
411 | callback();
|
412 | }, function(callback) {
|
413 | this.push(new gutil.File({
|
414 | path: fileName,
|
415 | contents: assetStorage
|
416 | }));
|
417 | callback();
|
418 | })
|
419 | };
|
420 |
|
421 |
|
422 |
|
423 |
|
424 | utils.noop = function() {};
|
425 |
|
426 |
|
427 | module.exports = utils; |
\ | No newline at end of file |