设计思路
静态博客的最终产物为一个个HTML页面文件,为了实现该功能,可以利用Node来对文件进行读取和写入,根据自己的文件管理习惯,按照最后的产物设计相关的代码逻辑
如何接收终端命令
Node自带的process.argv
参数提供了对命令的解析,因此可根据这个特点自定义服务的命令
本地预览
使用的是Node的http
模块,启动端口对文件下的文件进行静态文件服务传输,这里需要注意的是,虽然实现了静态文件的浏览,但是无法实时更新,所以需要同时对重要的文件进行监听,代码示例:
function runServer() {
// 先生成静态文件,防止没有文件进行访问
startGenerate()
// 需要访问的文件的存放目录(项目所在位置的文件夹路径)
var documentRoot = './target'
// 启动服务
http.createServer(function (req, res) {
var url = req.url
if (url == '/') {
url = '/index.html'
}
var file = documentRoot + url
fs.readFile(file, function (err, data) {
if (err) {
// 配置404
res.writeHeader(404, {
'content-type': 'text/html;charset="utf-8"'
})
res.write(readFile('target/404.html'))
} else {
// 请求头设置
// html的请求头 Content-Type : text/html ; charset=utf-8
// CSS的请求头 content-type: text/css; charset=utf-8
// JavaScript的请求头 content-type: text/javascrpt; charset=utf-8
let contentType = 'text/html;charset="utf-8"'
if (url.indexOf('.css') > -1) {
contentType = 'text/css;charset=utf-8'
} else if (url.indexOf('.js') > -1) {
contentType = 'text/javascrpt;charset=utf-8'
}
res.writeHeader(200, {
'content-type': contentType
})
res.write(data)
}
res.end()
})
}).listen(7981)
// 监听文件变化(recursive开启深度监听)
fs.watch('./docs', { recursive: true }, () => {
startGenerate()
})
fs.watch('./source', { recursive: true }, () => {
startGenerate()
})
console.log('服务器开启成功,访问http://localhost:7981/')
}
静态资源复制
对于静态资源文件,如文章的图片、logo等文件,可以将其复制到服务启动文件夹下,复制代码逻辑
/**
* 文件夹复制(递归支持下级目录)
*/
function cpSync(source, destination) {
let major = process.version.match(/v([0-9]*).([0-9]*)/)[1]
let minor = process.version.match(/v([0-9]*).([0-9]*)/)[2]
// 判断node版本不是16.7.0以上的版本
// 则进入兼容处理
// 这样处理是因为16.7.0的版本支持了直接复制文件夹的操作
if (Number(major) < 16 || Number(major) == 16 && Number(minor) < 7) {
// 如果存在文件夹 先递归删除该文件夹
if (fs.existsSync(destination)) fs.rmSync(destination, { recursive: true })
// 新建文件夹 递归新建
fs.mkdirSync(destination, { recursive: true })
// 读取源文件夹
let rd = fs.readdirSync(source)
for (const fd of rd) {
// 循环拼接源文件夹/文件全名称
let sourceFullName = source + "/" + fd
// 循环拼接目标文件夹/文件全名称
let destFullName = destination + "/" + fd
// 读取文件信息
let lstatRes = fs.lstatSync(sourceFullName)
// 是否是文件
if (lstatRes.isFile()) fs.copyFileSync(sourceFullName, destFullName)
// 是否是文件夹
if (lstatRes.isDirectory()) cpSync(sourceFullName, destFullName)
}
} else {
fs.cpSync(source, destination, { force: true, recursive: true })
}
}
如何与模板拼合
使用的方案是js的替换replace
,在模板中自定义语法,例如${postName}
,在文件写入前对字符内容处理即可
部署问题
为了更加便捷的部署到Github,增加了一个脚本功能,需要将其复制到target
中
// 复制部署文件
fs.copyFileSync('./source/deploy.js', './target/deploy.js')
其中的内容为终端命令,根据实际情况做调整
const { execSync } = require("child_process")
var fs = require('fs')
/**
* 部署
*/
if (fs.existsSync('.git')) {
fs.rmSync('.git', { recursive: true })
}
console.log('执行命令 git init');
execSync('git init')
console.log('执行命令 git add article category images source index.html CNAME 404.html');
execSync('git add article images static index.html')
console.log('执行命令 git commit');
execSync('git commit -m commit')
console.log('执行命令 git branch -M main');
execSync('git branch -M main')
console.log('执行命令 git remote add origin');
execSync('git remote add origin https://github.com/fanmore/fanmore.github.io.git')
console.log('执行命令 git push -u -f origin main');
execSync('git push -u -f origin main')
执行方式为先进入target
文件夹下,执行该脚本
Github访问慢问题
由于Github的服务器在国外,访问起来总有慢的时候,可以使用CDN解决,使用的前提条件是
- 拥有自己的域名
- 已经备案
这里推荐的是又拍云,操作上最为简单,大致步骤为
- 登录注册又拍云
- 创建CDN服务,并配置域名、源站、证书
- 在Github的博客仓库上填写自定义域名(否则访问出现404),同时记得将
CNAME
文件保留
一开始尝试了阿里云的CDN,在域名那个步骤需要到github.com下放置文件,放弃了
问题
部署可能因为网络原因,无法成功部署,与Github有关