不到100行代碼,使用Node寫一個靜態博客生成器

不到100行代碼,使用Node寫一個靜態博客生成器

如今有不少流行的靜態博客生成工具,好比hexohugo等,其實手動實現一個靜態博客生成工具也是一個簡單的過程,本文就帶你們使用node實現一個簡單的靜態博客生成工具。咱們的目標是將markdown文件生成一個靜態的站點。只需5步,不到100行代碼量。javascript

1. 創建項目

先新建一個項目目錄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

2. 收集markdown文件

在項目根目錄下新建src目錄,該目錄用於存放咱們全部的markdown源文件,咱們首先將該目錄下的全部markdown文件的路徑收集起來,編寫一個walk函數,並使用walkdirsrc目錄進行遍歷。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;
}

3. 將markdown文件渲染成html

在根目錄下新建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;
}

4. 生成首頁

只將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 成功`);
    });
}

5. 編寫入口函數

接下來咱們在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的過程當中加一點樣式。

到此就實現了一個很是簡單的靜態博客生成器,其中不少過程都簡化處理了,主要是爲了闡述生成靜態博客的思路,若是要完成一個功能豐富的靜態博客生成工具,還有不少能夠完善的地方。

源代碼地址:https://github.com/JohnSnow93/node-site-generator

相關文章
相關標籤/搜索