如今有不少流行的静态博客生成工具,好比hexo
、hugo
等,其实手动实现一个静态博客生成工具也是一个简单的过程,本文就带你们使用node实现一个简单的静态博客生成工具。咱们的目标是将markdown文件生成一个静态的站点。只需5步,不到100行代码量。javascript
先新建一个项目目录css
mkdir node-site-generator && cd node-site-generator
初始化项目html
npm init -y
安装一些依赖包, 这些依赖包具体做用后面会解释到java
npm i del markdown-it parse-md walkdir --save
而后在项目目录下新建一个main.js
,由于代码比较少,咱们的全部代码就写到这里。node
在项目根目录下新建src
目录,该目录用于存放咱们全部的markdown源文件,咱们首先将该目录下的全部markdown文件的路径收集起来,编写一个walk
函数,并使用walkdir
对src
目录进行遍历。git
const walkdir = require('walkdir'); async function walk (srcPath){ let result = await walkdir.async(srcPath,{return_object:true}); const mdPaths = []; Object.entries(result).forEach(([path, fileStatus]) => { // walkdir会遍历全部目录和文件,我只将遍历结果中的md文件路径收集起来 if(!fileStatus.isDirectory() && path.match(/\.md$/ig)){ mdPaths.push(path); } }); return mdPaths; }
在根目录下新建public
文件夹,再在public
目录下新建articles
目录,用于存放生成好的静态HTML文件。github
按照上一步收集到文件路径读取markdown文件,并将其生成HTML静态文件。npm
这里咱们用到了parse-md
包和markdown-it
两个包,做用以下:数组
parse-md
用于读取makrdown的元信息,如标题、建立时间等,元信息相似下面的格式markdown
--- title: SQL学习笔记 date: 2018-06-11 ---
markdown-it
用于将markdown文件渲染成HTML继续在mian.js
编写以下内容
const fs = require('fs'); // node原生的文件模块 const { default: parseMD } = require('parse-md'); const MarkdownIt = require('markdown-it'); const md = new MarkdownIt(); // htmlTemplate函数将生内容字符串填充到HTML模板中,方便复用 function htmlTemplate(content, title = '站点标题', isArticle = false){ return `<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>站点标题</title> <link rel="stylesheet" href="${isArticle ? '../styles.css' : './styles.css'}"> </head> <body> <header>${title}</header> <ul> ${content} </ul> <footer> Simple Blog 2019-2020 </footer> </body> </html> `;} // 将markdown文件渲染为HTML静态文件 function parseMDtoHTML(paths = []){ // paths是一个数组,存放了咱们上一步中收集到全部的md文件路径 let indexData = []; for (let i = 0; i < paths.length; i++) { const str = fs.readFileSync(paths[i], 'utf8'); // 读取markdown文件的源信息和内容,获得标题、日期等,以后生成首页也要用到这些元信息 const { metadata, content } = parseMD(str); const { title, date } = metadata; // indexData以后用于生成首页 const mdHtml = md.render(content); const articleHtml = `<article> <h2>${title}</h2> <p>${date.toLocaleDateString()}</p> ${mdHtml} </article>`; const fileTitle = title.replace('/\s/g', '-'); const writePath = `./public/articles/${fileTitle}.html`; fs.writeFileSync(writePath, htmlTemplate(articleHtml, '文章页', true)); indexData.push({ ...metadata, fileTitle }); } return indexData; }
只将markdown生成HTML仍是不够的,咱们还须要一个首页,这一步咱们就给静态博客生成一个首页index.html
,并将其生成在public
目录下,首页要包含导航到全部文章区域的连接:
function generateIndex(indexData = []){ // indexData所用的是第三部中收集的文章元信息数组,用于生成文章的连接 const listHTML = indexData.map(i => { return ` <li> <a href="./articles/${i.fileTitle}.html">${i.title}</a> <time>${i.date.toLocaleDateString()}</time> </li> ` }).join(''); // htmlTemplate函数具体见第三步 const indexHTML = htmlTemplate(listHTML); fs.writeFile('./public/index.html', indexHTML, function () { console.log(`写入index.html 成功`); }); }
接下来咱们在main.js
的最底部编写一个start
函数,将上面的过程串联起来:
const del = require('del'); async function start() { // 1. del用于删除上一次生成的静态文件 del(['./public/articles/**.html', './public/index.html']); // 2. 收集src目录下的全部markdown文件的路径 const paths = await walk('./src'); // 3. 读取全部markdown文件并生成html const indexData = await parseMDtoHTML(paths); // 4. 生成首页index.html await generateIndex(indexData); } // 执行start函数 start();
最后在项目目录下执行node main.js
启动,就能够看到public
目录下生成的结果。额外地,为了不生成的html静态文件太过朴素,建议在生成静态HTML的过程当中加一点样式。
到此就实现了一个很是简单的静态博客生成器,其中不少过程都简化处理了,主要是为了阐述生成静态博客的思路,若是要完成一个功能丰富的静态博客生成工具,还有不少能够完善的地方。