前端小白徒手搭博客之路

Posted homehtml

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端小白徒手搭博客之路相关的知识,希望对你有一定的参考价值。

前言

本博客为最最最基本的html静态页面打造而成。

github地址
线上地址

技术图片

Github Pages

github上搭建博客,免费又方便,具体可以参考这两篇文章:
怎样在github上创建一个github pages的博客
手把手教你在Github Pages搭建自己写的页面

如果想打造博客专属域名,如下:

1. 域名购买与解析

这里我们可以通过万网申请,查找你想申请域名,购买就可以了。

技术图片

购买域名完成,进入管理控制台:

技术图片

找到你已经购买的域名,点击解析,进入如下页面:

技术图片

添加两条记录:

  • 主机记录www对应 www.域名
  • 主机记录@对应 域名

技术图片

记录类型-CNAME
记录值-你的仓库名

2. CNAME

在你的仓库创建一个CNAME文件,内容为你的域名,例如:

技术图片

技术图片

3. Settings

在仓库设置你的域名:

技术图片

技术图片

现在通过购买的域名访问你的个人站点了。

接下来你可以开始为你博客大展手脚添加各种炫酷样式。

开始

博客目录结构:

技术图片

1. BootCDN

稳定、快速、免费的前端开源项目 CDN 加速服务。

我们可以从BootCDN引用需要用到的JS库

// index.html
<body>
    <div id="particles-js"></div>
</body>

<script src="https://cdn.bootcss.com/particles.js/2.0.0/particles.min.js"></script>

<script src="js/particles.js"></script>
2. Iconfont

阿里巴巴矢量图标库,阿里妈妈MUX倾力打造的矢量图标管理、交流平台。

注册一个用户后,新建项目,把需要用到的图标加入到项目中,生成代码,直接引入就可以用了。

技术图片

// index.html
<link rel="stylesheet" href="你的iconfont地址"></link>
3. 极简图床

免费图床,markdown链接好利器。

技术图片

4. 评论

Gitment:使用 GitHub Issues 搭建评论系统

技术图片

5. 文章

博客所有文章都放在md目录下,用来直接访问,只支持Markdown。

技术图片

由于没有服务器,所以用catalogue.js来放静态数据。

function JsonDate() {}

JsonDate.prototype.catalogues = [{"id":"fb6d78f11adcee47d22c2d618694e152","title":"异步编程","year":2018,"createTime":1528103681796,"abstract":"如何维护本体希望看到如下输出结果:但事实上,你会看到:怎么回事?大多数情况下,当一个函数嵌套在另一个函数中时,它就会自动继承父宿主函数的作用域,因而就能访问所有的变量了。那么,为什么嵌套的回调函数却没有返回正确的属性的值呢?这个问题归根于关键字和异步回调函数本身。别忘了,当你调用这样的函数的时候,它会首先初始化自己,然后调用底层的操作系统函数,并把回调函数插到事件队列中去。执行完会立即返回给函数,然后退出。当函数完成...","next":"前端小白徒手搭博客之路"},{"id":"642ac0b4cacd8745d644aaf45d1cca7e","title":"前端小白徒手搭博客之路","year":2018,"createTime":1528103681794,"abstract":"前言作为一个前端小白,一直以来,样式、布局、设计、灵感都是自己的痛点。看到前端人士随手一来就是一个高大上的网页,真是羡慕不已。所以决定从开始,打好基础,写一个传统的静态页面博客。项目地址线上地址我选择在上搭建博客,具体可以参考这两篇文章:怎样在上创建一个的博客手把手教你在搭建自己写的页面如果想打造博客专属域名,如下:域名购买与解析这里我们可以通过万网申请,查找你想申请域名,购买就可以了。购买域名完成,进入管理控制台:...","next":"What is Node","prev":"异步编程"},{"id":"08ad6d06e8a9c0c8aa4f4c45381e955d","title":"What is Node","year":2018,"createTime":1528103681789,"abstract":"出现之前应用往往基于客户端服务器模式,当客服端向服务器请求资源时,服务器会响应这个请求并且返回响应的资源。服务器只会在接收到客服端请求时才会做出响应,同时会在响应结束后关闭与客户端的连接。这种设计模式需要考虑到效率问题,因为每一个请求都需要处理时间和资源。因此,服务器在每一次处理请求的资源后应该关闭这个连接,以便于响应其他请求。如果同时有成千上万个请求同时发往服务器,服务器会变成什么样子呢?线程是系统能够并行处理多任...","next":"Promise对象","prev":"前端小白徒手搭博客之路"},{"id":"00dada12c7e31b9f7bb37a3b2af7f7d4","title":"Promise对象","year":2018,"createTime":1528103681787,"abstract":"的含义所谓,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,是一个对象,从它可以获取异步操作的消息。对象有一下两个特点:对象的状态不受外界影响。对象代表一个异步操作,有三种状态:(进行中)、(已成功)和(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。一旦状态改变,就不会再变,任何时候都可以得到这个结果。对象的状态改变,只有两种可能...","prev":"What is Node"}];

JsonDate.prototype.getCatalogues = function() {
    return this.catalogues;
};

JsonDate.prototype.getCatalogueInfo = function(index) {
    return this.catalogues[index];
};

这样,就可以在页面上引用:

<script src="md/catalogue.js"></script>
<script>
    let data = new JsonDate();
    let index = GetRequest();
    let info = data.getCatalogueInfo(index);
    
    $.ajax({
        type: ‘get‘,
        // 线上文章地址,直接访问获取内容
        url: `http://dusuchao.xin/md/${info.title}.md`,
        success: data => {}
    })
    
    function GetRequest() {
        var url = location.search;
        if (url.indexOf("?") != -1) {
            var str = url.substr(1);
            strs = str.split("#");
            return parseInt(strs[0]);
        }
    }
</script>

So,发布新文章的时候,就很简单的了,只需把文件添加到md目录下,再修改一下下catalogue.js的catalogues数据就行。

技术图片

..因为太麻烦了,便写了一键发布的脚本shell.js。

shell.js是基于node环境,随便写写,应该可以用,贴上代码:

‘use strict‘;

const fs = require(‘fs‘);
const path = require(‘path‘);
const crypto = require(‘crypto‘);
const util = require(‘util‘);

const readline = require(‘readline‘);

const readdir = util.promisify(fs.readdir);
const stat = util.promisify(fs.stat);
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);
const loadMd = util.promisify(load_md);

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let _folder = process.argv[2];
let _file = process.argv[3];

if (!_folder && !_file) {
    process.stdout.write(‘请输入 -文章所在文件夹名 -要写入的文件名: 
‘);
    process.stdout.write(‘-d (当前文件夹,默认文件catalogue.js)
‘);
    process.stdout.write(‘      or
‘);
    process.stdout.write(‘./ catalogue.js
‘);
    process.stdout.write(‘> ‘);
} else {
    load(_folder, _file)
        .then(data => {
            console.log(data);
            rl.close();
        })
        .catch(err => {
            err.msg && process.stdout.write(‘error:‘ + err.msg + ‘
‘);
            process.stdout.write(‘文件夹:‘ + err.folder + ‘
‘);
            process.stdout.write(‘文件:‘ + err.file + ‘
‘);
            process.stdout.write(‘请输入正确的路径名: 
‘);
            process.stdout.write(‘> ‘);
        });
}

rl.on(‘line‘, line => {
    let parts = line.split(new RegExp(‘[ ]+‘));
    if (parts.length <= 1) {
        if (parts[0] === ‘-d‘) {
            load(parts[0], ‘‘)
                .then(data => {
                    console.log(data);
                    rl.close();
                })
                .catch(err => {
                    err.msg && process.stdout.write(‘error:‘ + err.msg + ‘
‘);
                    process.stdout.write(‘文件夹:‘ + err.folder + ‘
‘);
                    process.stdout.write(‘文件:‘ + err.file + ‘
‘);
                    process.stdout.write(‘请输入正确的路径名: 
‘);
                    process.stdout.write(‘> ‘);
                });
        } else {
            process.stdout.write(‘请输入正确的格式 (文章所在文件夹名 要写入的文件名): 
‘);
            process.stdout.write(‘> ‘);
        }
    } else {
        load(parts[0], parts[1])
            .then(data => {
                console.log(data);
                rl.close();
            })
            .catch(err => {
                err.msg && process.stdout.write(‘error:‘ + err.msg + ‘
‘);
                process.stdout.write(‘文件夹:‘ + err.folder + ‘
‘);
                process.stdout.write(‘文件:‘ + err.file + ‘
‘);
                process.stdout.write(‘请输入正确的路径名: 
‘);
                process.stdout.write(‘> ‘);
            });
    }
});

function load(_folder, _file) {
    if (_folder === ‘-d‘ && !_file) {
        _folder = ‘md‘;
        _file = ‘md/catalogue.js‘;
    }
    _folder = path.resolve(__dirname, _folder);
    _file = path.resolve(__dirname, _file);
    return new Promise((resolve, reject) => {
        return (async () => {
            try {
                let catalogues = await loadMd(_folder);
                let file = await readFile(_file);
                let catalogues_reg = /[((
s*)*({([^]+?)})?(
s*)*)?]/;
                file = file.toString(‘utf8‘);
                if (!catalogues_reg.test(file)) throw {msg: ‘没找到可替换内容位置,请确保catalogues = []‘};
                let f = file.replace(catalogues_reg, JSON.stringify(catalogues));
                await writeFile(_file, f);
                resolve(‘文章添加完毕!‘);
            } catch (err) {
                err.folder = _folder;
                err.file = _file;
                reject(err);
            }
        })();
    });
}

async function load_md(dir, callback) {
    try {
        let files = await readdir(dir);

        files = files.filter(fileName => path.extname(fileName) === ‘.md‘ && path.basename(fileName, ‘.md‘) !== ‘关于我‘);
        if (files.length === 0) callback({msg: ‘当前文件夹下没有md文件‘});

        let catalogues = [];

        for (let i = 0; i < files.length; i++) {
            let status = await stat(dir + ‘/‘ + files[i]);
            let file = await readFile(dir + ‘/‘ + files[i]);

            file = file.toString(‘utf8‘);

            file = file.match(/[^x00-xff]/g).join(‘‘).substr(0, 210);

            let fileName = files[i].split(‘.‘)[0];

            let md5 = crypto.createHash(‘md5‘);
            md5.update(fileName, ‘uft8‘);
            let id = md5.digest(‘hex‘);

            let ctime = new Date(status.ctime);
            catalogues.push({
                id,
                title: fileName,
                year: ctime.getFullYear(),
                createTime: ctime.getTime(),
                abstract: file.length > 200 ? file + ‘...‘ : file
            });
        }

        if (catalogues.length) {
            catalogues.sort(compare(‘createTime‘));

            catalogues.forEach((catalogue, i) => {
                if (catalogues.length <= 1) return;

                if (i !== catalogues.length - 1) catalogue.next = catalogues[i + 1].title;
                if (i !== 0) catalogue.prev = catalogues[i - 1].title;
            });

            callback(null, catalogues);
        }
    } catch (err) {
        callback(err);
    }
}

function compare(property) {
    return function(a, b) {
        var value1 = a[property];
        var value2 = b[property];
        return value2 - value1;
    };
}

本想写成支持自定义目录、自定义文件,但是页面写死的东西太多,自定义名的文件好像也没什么用,不用在意..

现在,只需将文章添加到目录下,再

> node shell -d

一下下,就可以开心地提交代码了。

技术图片

后记

第一次写文章难免会紧张和哆嗦,欢迎大家指正和批评。

前段时间刚好看到某云优惠,入手一台云服务器,后续会有博客升级版。

技术图片

最后最后,走过路过千万别错过Star一下哦!





以上是关于前端小白徒手搭博客之路的主要内容,如果未能解决你的问题,请参考以下文章

小白的学习之路

前端小小白的学习之路JavaScript常用代码书写规范

前端进阶之路-二如何用gulp搭建一套web前端开发框架

前端进阶之路-一如何用gulp搭建一套web前端开发框架

前端小小白的学习之路JavaScript 开发的45个经典技巧

前端小小白的学习之路 JavaScript中的十个难点,你有必要知道。