gulpfile.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /**
  2. * FeHelper Chrome Extension Builder By Gulp
  3. * @author zhaoxianlie
  4. */
  5. let gulp = require('gulp');
  6. let clean = require('gulp-clean');
  7. let copy = require('gulp-copy');
  8. let zip = require('gulp-zip');
  9. let uglifyjs = require('gulp-uglify-es').default;
  10. let uglifycss = require('gulp-uglifycss');
  11. let htmlmin = require('gulp-htmlmin');
  12. let jsonmin = require('gulp-jsonminify');
  13. let fs = require('fs');
  14. let through = require('through2');
  15. let path = require('path');
  16. let pretty = require('pretty-bytes');
  17. let shell = require('shelljs');
  18. let runSequence = require('run-sequence');
  19. let watchPath = require('gulp-watch-path');
  20. let gcallback = require('gulp-callback');
  21. let crypto = require('crypto');
  22. // 顶部导航栏
  23. let navbar = require('./static/js/navbar.js');
  24. // 可以特定的编译某个工具,开发过程中用,可以提高编译速度
  25. let singleTool = '';
  26. gulp.task('clean', () => {
  27. if (require('os').hostname() === 'www-baidufe-com') {
  28. return console.log('当心,别乱来!不允许在服务器上直接编译!');
  29. }
  30. let args = process.argv.slice(2);
  31. if (args.length === 2 && args[0] === '--t') {
  32. return gulp.src('output', {read: false});
  33. } else {
  34. return gulp.src('output', {read: false}).pipe(clean({force: true}));
  35. }
  36. });
  37. gulp.task('copy', () => {
  38. return gulp.src(['fehelper/**/*.{gif,png,jpg,jpeg,cur,ico}']).pipe(copy('output'));
  39. });
  40. gulp.task('json', () => {
  41. return gulp.src('fehelper/**/*.json').pipe(jsonmin()).pipe(gulp.dest('output/fehelper'));
  42. });
  43. gulp.task('html', () => {
  44. // 头部公共的meta标签,SEO用
  45. let metas = `<meta name="Robots" content="INDEX,FOLLOW">
  46. <meta name="keywords" content="FeHelper,WEB前端助手,JSON格式化,JSON对比,信息编解码,代码美化,代码压缩,二维码生成,二维码解码,图片Base64转换,Markdown,随机密码生成器,正则表达式,时间戳转换,便签笔记,进制转换,贷款计算器">
  47. <meta name="description" content="WEB前端助手:FeHelper,浏览器插件,包含一些前端实用的工具,如JSON格式化,JSON对比,信息编解码,代码美化,代码压缩,二维码生成,二维码解码,图片Base64转换,Markdown,随机密码生成器,正则表达式,时间戳转换,便签笔记,进制转换,贷款计算器等">
  48. <link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/pkgccpejnmalmdinmhkkfafefagiiiad">
  49. <meta name="renderer" content="webkit">
  50. <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">`;
  51. // 百度统计代码
  52. let baiduTj = `<div id="pageFooter" class="hide" style="display: none">
  53. <script type="text/javascript">
  54. (function(){
  55. var _bdhmProtocol = (("https:" === document.location.protocol) ? " https://" : " http://");
  56. document.write(unescape("%3Cscript src='" + _bdhmProtocol +
  57. "hm.baidu.com/h.js%3F17b02fba4e62901b4289eef4c2243123' type='text/javascript'%3E%3C/script%3E"));
  58. })();
  59. </script>
  60. </div>`.replace(/\n+|\s{2,}/gm, ' ');
  61. let tplInsert = () => {
  62. return through.obj(function (file, enc, cb) {
  63. let contents = file.contents.toString('utf-8');
  64. let insert = (fp, fc) => {
  65. return fc.replace(/<\/title>/gm, `</title>${metas}`) // meta标签-seo
  66. .replace(/id="pageContainer"[^>]*>/gm, function (frag) { // 顶部导航栏
  67. return frag + navbar.htmlHeader;
  68. }).replace(/<\/body>/gm, `${baiduTj}</body>`) // 百度统计
  69. .replace(`<script src="../static/js/navbar.js"></script>`, ''); // 删掉navbar.js的引用
  70. };
  71. contents = insert(file.path, contents);
  72. file.contents = new Buffer.from(contents);
  73. this.push(file);
  74. return cb();
  75. });
  76. };
  77. return gulp.src(`fehelper${singleTool}/**/*.html`).pipe(tplInsert()).pipe(htmlmin({collapseWhitespace: true})).pipe(gulp.dest(`output/fehelper${singleTool}`));
  78. });
  79. // 合并 & 压缩 js
  80. gulp.task('js', () => {
  81. let jsMerge = () => {
  82. return through.obj(function (file, enc, cb) {
  83. let contents = file.contents.toString('utf-8');
  84. let tpl = 'let #VARNAME# = (function(module){ #CODES# ; return module.exports; })({exports:{}});\r\n';
  85. let merge = (fp, fc) => {
  86. let js = {};
  87. // 合并 __importScript
  88. fc = fc.replace(/__importScript\(\s*(['"])([^'"]*)\1\s*\)/gm, function (frag, $1, mod) {
  89. let mp = path.resolve(fp, '../' + mod + (/\.js$/.test(mod) ? '' : '.js'));
  90. let mc = fs.readFileSync(mp).toString('utf-8');
  91. return merge(mp, mc + ';');
  92. });
  93. let rfc = fc.replace(/Tarp\.require\(\s*(['"])([^'"]+)\1\s*\)/gm, function (frag, $1, mod, $2, code) {
  94. let mp = path.resolve(fp, '../' + mod + (/\.js$/.test(mod) ? '' : '.js'));
  95. let mc = fs.readFileSync(mp).toString('utf-8');
  96. frag = frag.replace(/[^\w]/g, '').replace('Tarprequire', 'TR');
  97. js[frag] = merge(mp, mc);
  98. return frag;
  99. });
  100. return Object.keys(js).map(k => {
  101. return tpl.replace('#VARNAME#', k).replace('#CODES#', () => js[k]);
  102. }).join('; ') + rfc;
  103. };
  104. contents = merge(file.path, contents);
  105. file.contents = new Buffer.from(contents);
  106. this.push(file);
  107. return cb();
  108. })
  109. };
  110. return gulp.src(`fehelper${singleTool}/**/*.js`).pipe(jsMerge()).pipe(uglifyjs()).pipe(gulp.dest(`output/fehelper${singleTool}`));
  111. });
  112. // 合并 & 压缩 css
  113. gulp.task('css', () => {
  114. let cssMerge = () => {
  115. return through.obj(function (file, enc, cb) {
  116. let contents = file.contents.toString('utf-8');
  117. let merge = (fp, fc) => {
  118. return fc.replace(/\@import\s+(url\()?\s*(['"])([^'"]*)\2\s*(\))?\s*;?/gm, function (frag, $1, $2, mod) {
  119. let mp = path.resolve(fp, '../' + mod + (/\.css$/.test(mod) ? '' : '.css'));
  120. let mc = fs.readFileSync(mp).toString('utf-8');
  121. return merge(mp, mc);
  122. });
  123. };
  124. contents = merge(file.path, contents);
  125. file.contents = new Buffer.from(contents);
  126. this.push(file);
  127. return cb();
  128. })
  129. };
  130. return gulp.src(`fehelper${singleTool}/**/*.css`).pipe(cssMerge()).pipe(uglifycss()).pipe(gulp.dest(`output/fehelper${singleTool}`));
  131. });
  132. // 给静态文件增加md5戳
  133. gulp.task('md5', () => {
  134. let md5Replace = () => {
  135. return through.obj(function (file, enc, cb) {
  136. let contents = file.contents.toString('utf-8');
  137. let replace = (fp, fc) => {
  138. [
  139. [
  140. /<script[^>]*>\s*?<\/[^>]*script>/gim,
  141. /src=['"]([^'"]+)['"]/igm,
  142. 'src'
  143. ],
  144. [
  145. /<link\s+[^>]*stylesheet[^>]*>/gim,
  146. /href=['"]([^'"]+)['"]/igm,
  147. 'href'
  148. ]
  149. ].forEach(item => {
  150. fc = fc.replace(item[0], frag => {
  151. return frag.replace(item[1], function ($1, $2) {
  152. if(/^http(s)?:\/\//.test($2)) {
  153. return $2;
  154. }
  155. if ($2.indexOf('?') !== -1) {
  156. let x = $2.split('?');
  157. x.pop();
  158. $2 = x.join('');
  159. }
  160. let mp = path.resolve(fp, '../' + $2);
  161. let mc = fs.readFileSync(mp).toString('utf-8');
  162. let md5 = crypto.createHash('md5').update(mc).digest('hex');
  163. return `${item[2]}="${$2}?v=${md5.slice(-8)}"`;
  164. });
  165. });
  166. });
  167. return fc;
  168. };
  169. contents = replace(file.path, contents);
  170. file.contents = new Buffer.from(contents);
  171. this.push(file);
  172. return cb();
  173. })
  174. };
  175. return gulp.src(`output/fehelper${singleTool}/**/*.html`).pipe(md5Replace()).pipe(gulp.dest(`output/fehelper${singleTool}`));
  176. });
  177. // 清理冗余文件,并且打包成zip
  178. gulp.task('zip', ['md5'], () => {
  179. // hello-world是一个demo,代码不能被压缩
  180. shell.exec('cp -r hello-world output/fehelper/');
  181. shell.exec('cd output/ && rm -rf fehelper.zip && zip -r fehelper.zip fehelper/* > /dev/null && cd ../ && rm -rf fehelper/');
  182. console.log('\n\tfehelper.zip 已打包完成!可以提交代码去更新网站了!\n');
  183. });
  184. // 创建fehelper目录
  185. gulp.task('fehelper', () => {
  186. let excludeFiles = ['fehelper', 'gulpfile.js', 'LICENSE', 'package.json', 'package-lock.json', 'README.md', 'output', 'node_modules'];
  187. let tools = shell.ls().filter(file => !/^\./.test(file) && !excludeFiles.includes(file));
  188. shell.exec('rm -rf fehelper && mkdir fehelper && cp -r ' + tools.join(' ') + ' fehelper/');
  189. });
  190. // builder
  191. gulp.task('default', ['clean'], () => {
  192. if (require('os').hostname() === 'www-baidufe-com') {
  193. return console.log('当心,别乱来!不允许在服务器上直接编译!');
  194. }
  195. let args = process.argv.slice(2);
  196. if (args.length === 2 && args[0] === '--t') {
  197. singleTool = `/${args[1]}`;
  198. }
  199. runSequence(['fehelper', 'copy', 'css', 'js', 'html', 'json'], 'zip');
  200. });
  201. // 在服务器上进行发布
  202. gulp.task('deploy', () => {
  203. shell.exec('cd output/ && rm -rf fehelper.bak && mv fehelper fehelper.bak && unzip fehelper.zip > /dev/null');
  204. console.log('已发布成功!');
  205. });
  206. gulp.task('sync', () => {
  207. gulp.src('fehelper/**/*').pipe(gulp.dest('output/fehelper'));
  208. });
  209. // 开发过程中用,watch while file changed
  210. gulp.task('watch', () => {
  211. gulp.watch('fehelper/**/*.*', (event) => {
  212. let wp = watchPath(event, './', './output');
  213. gulp.src(wp.srcPath).pipe(copy('output')).pipe(gcallback(() => {
  214. console.log(new Date().toLocaleString(), '> 文件发生变化,已编译:', wp.srcPath);
  215. }));
  216. });
  217. });
  218. // 用esbuild来进行js文件压缩,超级快。。。。。
  219. gulp.task('esbuild',() => {
  220. shell.cd('output');
  221. shell.exec(`find . -type f -name "*.js" -exec esbuild --minify {} --outfile=dist/{} \\;`);
  222. });