完善构建过程

This commit is contained in:
结发受长生 2019-05-11 17:13:36 +08:00
parent ed816bb30a
commit 1618668b14
4 changed files with 128 additions and 44 deletions

76
deploy_utils/deploy.js Normal file
View File

@ -0,0 +1,76 @@
const fs = require('fs')
const path = require('path')
module.exports = {
/**
* 发布静态化的站点
* @param {String} source 源位置
* @param {String} target 目标位置
* @param {Boolean} copyRoot 是否拷贝根目录
*/
async exec(source, target, copyRoot) {
await new Promise((resolve, reject) => {
console.log(`删除${target}目录中的文件`)
this._deleteFolderRecursive(target, true)
resolve()
})
console.log(`拷贝${source}所有文件 -> ${target}`)
this._copyFolderRecursive(source, target, copyRoot)
},
/**
* 递归删除目录以及子目录中的所有文件
* @param {String} curPath 要递归删除的目录
* @param {Boolean} retainRoot 是否保留根目录不删除
*/
_deleteFolderRecursive(curPath, retainRoot) {
fs.readdirSync(curPath).forEach(file => {
var nextPath = path.resolve(curPath, file)
if(fs.statSync(nextPath).isDirectory()) { // recurse
this._deleteFolderRecursive(nextPath)
} else {
fs.unlinkSync(nextPath)
}
})
if(!retainRoot) { // 根目录保留
fs.rmdirSync(curPath)
}
},
/**
* 递归拷贝目录
* @param {String} source 源位置
* @param {String} target 目标位置
*/
_copyFolderRecursive(source, target) {
let files = fs.readdirSync(source); //同步读取当前目录
files.forEach(file => {
var _src = path.resolve(source, file)
var _target = path.resolve(target, file)
fs.stat(_src,(err,stats) => { //stats 该对象 包含文件属性
if (err) throw err
if (stats.isFile()) { //如果是个文件则拷贝
let readable = fs.createReadStream(_src) //创建读取流
let writable = fs.createWriteStream(_target) //创建写入流
readable.pipe(writable);
} else if (stats.isDirectory()) { //是目录则 递归
this._checkDirectory(_src, _target, this._copyFolderRecursive)
}
})
})
},
/**
* 校验目标目录是否存在
* @param {String} src 源目录
* @param {String} target 目标目录
* @param {Function} callback 回调函数
*/
_checkDirectory (src,target,callback) {
fs.access(target, fs.constants.F_OK, err => {
if (err) {
fs.mkdirSync(target)
}
callback.call(this, src, target)
})
}
}

View File

@ -32,43 +32,44 @@ class ImageSynchronizer {
* @param {Function} uploadCallback 处理待上传文件的回调函数
* @param {Function} deleteCallback 处理待删除文件的回调函数
*/
_queryObjects(params, uploadCallback, deleteCallback) {
async _queryObjects(params, uploadCallback, deleteCallback) {
// 列出所有已存储的对象
return this.client.listObject(params).then(ret => {
// ret 包括 items(元素)limit(请求的数量)nextMarker(下一个标记)
let storageItems = ret.items.filter((item) => {
return /^images.+?\.(png|jpe?g|gif)$/.test(item.key)
}).sort((item1, item2) => {
if(item1.key > item2.key) {
return 1
} else if(item1.key < item2.key) {
return -1
}
return 0
})
// 待上传的文件列表
let pendingUploadFiles = this.imagesList.filter(item => {
let index = this._binarySearch(storageItems, item.name, 'key', 0, storageItems.length-1)
if(index === -1) {
// 文件名不存在, 代表是新文件
item.type = 'new'
return true
} else if(storageItems[index].eTag !== item.md5) {
// 文件名存在, 但是hash值不同, 代表有变化
item.type = 'change'
return true
}
return false
})
// 处理待上传的文件
uploadCallback.call(this, pendingUploadFiles)
// 待删除的文件列表( 仓库中存在, 本地不存在 )
let pendingDeleteFiles = storageItems.filter(item => {
return this._binarySearch(this.imagesList, item.key, 'name', 0, this.imagesList.length-1) === -1
})
// 处理待删除的文件
deleteCallback.call(this, pendingDeleteFiles.map(item => item.key))
const ret = await this.client.listObject(params)
// ret 包括 items(元素)limit(请求的数量)nextMarker(下一个标记)
let storageItems = ret.items.filter(item => {
return /^images.+?\.(png|jpe?g|gif)$/.test(item.key)
}).sort((item1, item2) => {
if (item1.key > item2.key) {
return 1
}
else if (item1.key < item2.key) {
return -1
}
return 0
});
// 待上传的文件列表
let pendingUploadFiles = this.imagesList.filter(item => {
let index = this._binarySearch(storageItems, item.name, 'key', 0, storageItems.length - 1)
if (index === -1) {
// 文件名不存在, 代表是新文件
item.type = 'new'
return true
}
else if (storageItems[index].eTag !== item.md5) {
// 文件名存在, 但是hash值不同, 代表有变化
item.type = 'change'
return true
}
return false
});
// 处理待上传的文件
uploadCallback.call(this, pendingUploadFiles);
// 待删除的文件列表( 仓库中存在, 本地不存在 )
let pendingDeleteFiles = storageItems.filter(item => {
return this._binarySearch(this.imagesList, item.key, 'name', 0, this.imagesList.length - 1) === -1;
})
// 处理待删除的文件
deleteCallback.call(this, pendingDeleteFiles.map(item => item.key))
}
/**
* 上传文件对象

View File

@ -4,6 +4,14 @@ const gulp = require('gulp'),
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
@ -45,16 +53,10 @@ gulp.task('compressHtml', () => {
// 同步图片到对象存储仓库
gulp.task('syncImages', () => {
// 程序执行的传参
var argv = require('optimist')
.usage('$0 --accessKey [string] --accessSecret [string]')
.demand(['accessKey', 'accessSecret'])
.argv
const listImages = require('./image_sync/list_images')
const listImages = require('./deploy_utils/list_images')
// 当前本地存在的所有图片
const imagesList = listImages(`${process.cwd()}/source/`, 'images/')
const ImageSynchronizer = require('./image_sync/image_synchronize')
const ImageSynchronizer = require('./deploy_utils/image_synchronize')
const nosSetting = {
defaultBucket: 'blog-cdn',
endpoint: 'http://nos-eastchina1.126.net',
@ -65,7 +67,12 @@ gulp.task('syncImages', () => {
return imageSynchronizer.synchronize('images/')
})
gulp.task('deploy', () => {
const deploy = require('./deploy_utils/deploy')
return deploy.exec('./public', argv.deployPath, false)
})
// 默认任务
gulp.task('default',
gulp.series('generate', 'compressHtml', 'syncImages') // 串行执行任务
gulp.series('generate', 'compressHtml', 'syncImages', 'deploy') // 串行执行任务
)