1. Gulp简介gulp是一个自动化构建工具,能够强化我们的前端工作流。
gulp is an open-source JavaScript toolkit created by Eric Schoffstall used as a streaming build system (similar to a more package-focussed Make) in front-end web development.
It is a task runner built on Node.js and npm, used for automation of time-consuming and repetitive tasks involved in web development like minification, concatenation, cache busting, unit testing, linting, optimization, etc.
gulp uses a code-over-configuration approach to define its tasks and relies on its small, single-purpose plugins to carry them out. The gulp ecosystem includes more than 3500 such plugins.
更多内容,参考wikipedia-gulp.js 、Gulp官网 和Gulp中文网 。 本文中,会使用gulp来压缩hexo生成的静态资源文件,加快站点的访问速度。
2. 安装配置gulp1、安装gulpnpm install --global gulp-cli
2、安装gulp模块
1 2 3 4 npm install gulp --save npm install gulp-htmlclean gulp-htmlmin gulp-clean-css gulp-uglify gulp-imagemin --save npm install gulp-babel babel-preset-env babel-preset-mobx --save npm install -D @babel/core @babel/preset-react @babel/preset-env --save
最终生成的package.json为:
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 { "name" : "hexo-site" , "version" : "0.0.0" , "private" : true, "scripts" : { "build" : "hexo generate" , "clean" : "hexo clean" , "deploy" : "hexo deploy" , "server" : "hexo server" }, "hexo" : { "version" : "4.2.0" }, "dependencies" : { "babel-preset-env" : "^1.7.0" , "babel-preset-mobx" : "^2.0.0" , "gulp" : "^4.0.2" , "gulp-babel" : "^8.0.0" , "gulp-clean-css" : "^4.2.0" , "gulp-htmlclean" : "^2.7.22" , "gulp-htmlmin" : "^5.0.1" , "gulp-imagemin" : "^7.1.0" , "gulp-uglify" : "^3.0.2" , "hexo" : "^4.0.0" , "hexo-generator-archive" : "^1.0.0" , "hexo-generator-baidu-sitemap" : "^0.1.6" , "hexo-generator-category" : "^1.0.0" , "hexo-generator-feed" : "^2.2.0" , "hexo-generator-index" : "^1.0.0" , "hexo-generator-searchdb" : "^1.2.0" , "hexo-generator-sitemap" : "^2.0.0" , "hexo-generator-tag" : "^1.0.0" , "hexo-neat" : "^1.0.4" , "hexo-renderer-ejs" : "^1.0.0" , "hexo-renderer-marked" : "^2.0.0" , "hexo-renderer-stylus" : "^1.1.0" , "hexo-server" : "^1.0.0" }, "devDependencies" : { "@babel /core" : "^7.8.4" , "@babel /preset-env" : "^7.8.4" , "@babel /preset-react" : "^7.8.3" } }
4、在hexo目录创建gulpfile.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 let gulp = require ('gulp' )let cleanCSS = require ('gulp-clean-css' )let htmlmin = require ('gulp-htmlmin' )let htmlclean = require ('gulp-htmlclean' )let babel = require ('gulp-babel' ) let uglify = require ('gulp-uglify' )let imagemin = require ('gulp-imagemin' )const root = './public' const pattern = '**/*' gulp.task ('minify-html' , function ( ) { return gulp .src (`${root} /${pattern} .html` ) .pipe (htmlclean ()) .pipe ( htmlmin ({ removeComments : true , minifyJS : true , minifyCSS : true , minifyURLs : true }) ) .pipe (gulp.dest ('./public' )) }) gulp.task ('minify-css' , function ( ) { return gulp .src (`${root} /${pattern} .css` ) .pipe ( cleanCSS ({ compatibility : 'ie8' }) ) .pipe (gulp.dest ('./public' )) }) gulp.task ('minify-js' , function ( ) { return gulp .src (`${root} /${pattern} .js` ) .pipe ( babel ({ presets : ['env' ] }) ) .pipe (uglify ()) .pipe (gulp.dest ('./public' )) }) gulp.task ('minify-images' , function ( ) { return gulp .src (`${root} /images/${pattern} ` ) .pipe ( imagemin ( [ imagemin.gifsicle ({ optimizationLevel : 3 }), imagemin.jpegtran ({ progressive : true }), imagemin.optipng ({ optimizationLevel : 7 }), imagemin.svgo () ], { verbose : true } ) ) .pipe (gulp.dest ('./public/images' )) }) gulp.task ('default' , gulp.series ('minify-html' , 'minify-css' , 'minify-js' ))
4、执行压缩gulp
3. 命令精简使用了gulp时候,构建发布需要四个命令:
1 2 3 4 hexo clean hexo g gulp hexo d
这四个命令,可以都写在package.json。
1 2 3 4 "scripts" : { "build" : "hexo clean && hexo g && gulp" , "deploy" : "hexo clean && hexo g && gulp && hexo d" }
构建只需要执行npm run build
,构建发布只需要执行npm run deploy
。
4. travis配置对应的,修改.travis.yml配置为:
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 sudo : false language: node_js node_js: - 10.16.3 cache: npm branches: only: - master env : global: - GIT_USER: voidking - HEXO_BACKUP_REPO: github.com/voidking/hexo-backup.git - HEXO_THEME_REPO: github.com/voidking/hexo-theme-next.git - GITHUB_PAGES_REPO: github.com/voidking/voidking.github.io.git - VOIDKING_REPO: github.com/voidking/voidking.git before_install: - export TZ='Asia/Shanghai' - npm install hexo -g - npm install gulp-cli -g install: - npm install script: - git clone https://${HEXO_THEME_REPO} themes/next - git clone https://${GIT_USER} :${GITHUB_TOKEN} @${HEXO_BACKUP_REPO} hexo-backup - mv hexo-backup/source . - rm -rf source /private - npm run build after_success: - git config --global user.name "voidking" - git config --global user.email "voidking@qq.com" - git clone https://${GIT_USER} :${GITHUB_TOKEN} @${GITHUB_PAGES_REPO} voidking - unalias cp - cp -rf public/. voidking - cd voidking - git add . - git commit -m "Travis CI Auto Builder" - git push --force --quiet "https://${GIT_USER} :${GITHUB_TOKEN} @${GITHUB_PAGES_REPO} " master:master
5. 精简search.xmlhtml、css和js都压缩了,很开心。但是,还有一个大文件没有压缩,就是本地搜索的DB文件search.xml。我的博客有接近600篇文章,这个search.xml文件的大小为7.5M,很大。 打开search.xml文件,发现里面不止包含文章内容,还包含html标签。参考hexo-generator-searchdb ,发现可以设置不生成标签。
5.1. 修改localsearch配置1、修改hexo/_config.yml
的localsearch配置为:
1 2 3 4 5 6 # local search search: path: search.xml field: post format: striptags limit: 10000
2、重新生成search.xml文件,新的文件只有3.5M。
3、修改local-search.js 为了正常使用搜索功能,需要修改hexo主题的local-search.js。如果不修改的话,搜索时只搜索标题,不会搜索内容。编辑next/source/js/local-search.js
,如下修改:
1 2 3 // line 120 // let content = data .content ? data .content.trim().replace(/<[^>]+>/g , '') : ''; let content = data .content;
以上,实现了search.xml的精简,nice。
5.2. 自定义精简但是,3.5M依然很大,能不能再精简一下?可以。 1、localsearch的format改回html。
2、修改xml_generator.js 编辑hexo/node_modules/hexo-generator-searchdb/lib/xml_generator.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 'use strict' ;const path = require ('path' );const fs = require ('fs' );const nunjucks = require ('nunjucks' );var env = new nunjucks.Environment ();var searchTmplSrc = path.join (__dirname, '../templates/search.xml' );var searchTmpl = nunjucks.compile (fs.readFileSync (searchTmplSrc, 'utf8' ), env);var stripe_code_line_num = function (str ) { return str.replace (/<figure class="highlight.*?<\/figure>/ig , '' ); } var stripe = function (str ) { return str.replace (/(<([^>]+)>)/ig , '' ); } var minify = function (str ) { return str.trim ().replace (/\n/g , ' ' ).replace (/\s+/g , ' ' ); } module .exports = function (locals ) { var config = this .config ; var database = require ('./database' )(locals, config); database.forEach ( function (element, index ) { element.content = minify (stripe (stripe_code_line_num (element.content ))); }); var xml = searchTmpl.render ({ articles : database, config : config.search }); return { path : config.search .path , data : xml }; };
3、重新生成search.xml,这次只有2.5M,nice。
以上两种精简search.xml的方法都很好,这里我选择使用修改localsearch format的方法。因为如果在xml_generator.js不删除文章中的代码,两种方法的压缩结果基本相同,而方法一通用性更好。