--- title: 博客部署调整记录 date: 2019-05-11 19:01:11 tags: - gulp - nodejs categories: - 前端杂烩 --- 让你永远都有事情可忙正是前端的魅力所在 按照目前的策略, 博客构建部署大概是以下几个步骤 1. 主题内容的webpack打包 2. hexo clean && hexo generate 3. 图片与对象存储仓库同步 4. 生成的html文件的压缩 5. public目录中所有文件的拷贝发布 因为不想把主题和内容过多整合, 这样会导致将来更换主题困难 所以计划是把2 3 4 5步骤在构建过程中一键完成 ( 虽然有jenkins可以写多步的执行脚本, 但是仍然感觉不够优雅 ) 最好是能有个js脚本, 用nodejs一次执行完成这些步骤 第2步之前用的是hexo的命令行工具, 现在可以换成hexo的api, 在js当中调用之 第3步之前已经完成了, 就是用js写的脚本, 简单封装一下拿过来就可以用 第4步目前还没有做到, 准备实现一下, 因为webpack完成了对css和js的压缩输出, 所以静态化后就无需再次处理了 但是html文件是由hexo生成, 所以对主题内容的webpack打包, 是无法完成这件事的 查了一些资料发现gulp可以很简单做到, 于是就计划用它了 第5步, 就在js里面写递归删除与递归拷贝吧 ### hexo的api 根据官网的介绍, 可以按照下面的方式使用hexo的api ```javascript const Hexo = require('hexo') const hexo = new Hexo(process.cwd(), {}) hexo.init().then(()=>{ // 链式的Promise调用, 每一步都要返回Promise对象 return hexo.call('clean') }).then(()=>{ return hexo.call('generate', {watch: false}) }).then(()=>{ return hexo.exit() }).catch(err => { return hexo.exit(err) }) /* 当然也可以采用更加简洁的await try { await hexo.init() await hexo.call('clean') await hexo.call('generate', { watch: false }) return hexo.exit() } catch (err) { return hexo.exit(err) } */ ``` 上面的写法就如同是在命令行执行`hexo clean && hexo generate` 正好gulp配置任务的时候也需要返回Promise对象( 下面会提到 ), 可以直接结合, 不需要二次封装了, 不错 ### gulp ![gulp](/images/前端杂烩/gulp-2x.png) 之前没用过这个前端构建工具, 因为跟webpack的作用有不少的重合, 前端实在学不完 这里使用一下它的任务自动管理的功能, 整体的体验挺好 #### 安装 除了gulp本身, 还有其他几个用的到的插件 ( 当然也可以用npm安装 ) ```bash # 这几个是gulp相关的 yarn add gulp gulp-htmlclean gulp-htmlmin gulp-plumber -D # 这是图片同步到对象仓库相关的 yarn add @xgheaven/nos-node-sdk optimist -D ``` gulp在**4.0**这个大版本做了很大的改变, 这里我使用的是4.0.2 #### gulpfile.js 在根目录下创建`gulpfile.js`文件, 这个文件是gulp的配置文件 先简单规划一下结构 ```javascript const gulp = require('gulp') // 创建静态页面 (等同 hexo generate) gulp.task('generate', () => { // TODO 执行hexo的api }) // 压缩public目录下的html文件 gulp.task('compressHtml', () => { // TODO 使用gulp-htmlmin插件压缩html }) // 同步图片到对象存储仓库 gulp.task('syncImages', () => { //TODO 直接调用之前写的同步文件的代码 }) gulp.task('deploy', () => { //TODO 递归拷贝public目录中的所有文件到站点根目录 }) // 默认任务 gulp.task('default', gulp.series('generate', 'compressHtml', 'syncImages', 'deploy') // 串行执行任务 ) ``` 1. **gulp.task** 用于定义一个任务, 第一个参数是任务的名称, 第二个参数是任务要执行的函数 从4.0版本开始, 这个函数必须返回Promise对象, 让gulp来监测该任务是否执行完毕 应该是有利于更优化串行任务的执行过程 2. `default`就是在直接执行`gulp`的时候会执行的任务 当然也可以执行`gulp 任务名称`用来指定执行某个任务 3. **gulp.series**用来定义串行的任务, 也就是把参数里面这几个任务作为子任务, 并按照串行的方式执行 如果不使用它, 而是直接写 ```javascript gulp.task('default', ['generate', 'compressHtml', 'syncImages', 'deploy']) ``` 任务这几个子任务就会以并行的方式执行, 但是在这里因为有执行的顺序要求 比如必须在generate完成之后再执行html的压缩, 所以选择串行方式 这个api也是gulp4.0新增的 以往只能定义任务的完成依赖, 比如在定义B任务必须在A任务完成后执行 ```javascript gulp.task('B', ['A'], ()=>{/* do something */}) ``` #### 添加一些细节 ```javascript // gulpfile.js const gulp = require('gulp'), htmlmin = require('gulp-htmlmin'), //html压缩组件 htmlclean = require('gulp-htmlclean'), //html清理组件 plumber = require('gulp-plumber'), //容错组件(发生错误不跳出任务,并报出错误内容) Hexo = require('hexo') // 程序执行的传参 const argv = require('optimist') .demand(['accessKey', 'accessSecret', 'deployPath']) .describe('accessKey', '网易云对象存储key') .describe('accessSecret', '网易云对象存储secret') .describe('deployPath', '静态化后发布的目录') .argv const hexo = new Hexo(process.cwd(), {}) // 创建静态页面 (等同 hexo generate) gulp.task('generate', async function() { try { await hexo.init() await hexo.call('clean') await hexo.call('generate', { watch: false }) return hexo.exit() } catch (err) { return hexo.exit(err) } }) // 压缩public目录下的html文件 gulp.task('compressHtml', () => { const cleanOptions = { protect: /<\!--%fooTemplate\b.*?%-->/g, //忽略处理 unprotect: /