代码优化

This commit is contained in:
xugaoyi 2019-12-26 16:48:28 +08:00
parent e4c5a6ffa9
commit bf577d2905
26 changed files with 246 additions and 416 deletions

View File

@ -1,8 +1,15 @@
# Evan Blog —— web前端技术博客
## 介
##
使用 [VuePress](https://v1.vuepress.vuejs.org/zh/guide/) 构建 SEO 友好的静态博客站。内置 `deploy.sh` 和 [GitHub Action](https://github.com/features/actions) 两种自动部署脚本,一键发布到 GitHub Pages。
使用 [VuePress](https://v1.vuepress.vuejs.org/zh/guide/) 构建静态博客站。内置 `deploy.sh` 和 [GitHub Actions](https://github.com/features/actions) 两种自动部署脚本,一键发布到 GitHub Pages 或 国内访问速度更快的Coding Pages。还内置了自动百度链接推送以及结合GitHub Actions[每天定时推送](https://github.com/xugaoyi/blog/blob/master/.github/workflows/baiduPush.yml)
* **简洁至上**
* 继承了[VuePress](https://v1.vuepress.vuejs.org/zh/guide/) 简洁至上的特性,以 Markdown 为中心的项目结构,让你专注于写作
* **高自动化**
* 项目结合了各种自动化技术,[自动生成侧边栏](https://github.com/xugaoyi/blog/issues/113),自动部署,自动百度链接推送,每天定时百度链接推送
* **SEO友好**
* 让你的博客给更多人看到
@ -236,11 +243,7 @@ echo 'evanblogweb.com' > CNAME # // 域名替换成你的
## 提示
#### md文件的yaml代码
必须放在 md 文件在最上方才能生效
## 其他
#### 百度自动推送和统计

View File

@ -4,9 +4,9 @@ module.exports = {
"/01.前端/": [{"title":"JavaScript","collapsable":false,"children":[["01.JavaScript/01.JavaScript中的名词概念.md","JavaScript中的名词概念"],["01.JavaScript/02.数据类型转换.md","数据类型转换"],["01.JavaScript/03.ES5面向对象.md","ES5面向对象"],["01.JavaScript/04.ES6面向对象.md","ES6面向对象"],["01.JavaScript/05.new命令原理.md","new命令原理"],["01.JavaScript/06.多种数组去重性能对比.md","多种数组去重性能对比"]]}],
"/02.页面/": [{"title":"html-css","collapsable":false,"children":[["01.html-css/00.flex布局语法.md","flex布局语法"],["01.html-css/01.flex布局案例-基础.md","flex布局案例-基础"],["01.html-css/02.flex布局案例-骰子.md","flex布局案例-骰子"],["01.html-css/03.flex布局案例-网格布局.md","flex布局案例-网格布局"],["01.html-css/04.flex布局案例-圣杯布局.md","flex布局案例-圣杯布局"],["01.html-css/05.flex布局案例-输入框布局.md","flex布局案例-输入框布局"],["01.html-css/06.CSS3之transform过渡.md","CSS3之transform过渡"],["01.html-css/07.CSS3之animation动画.md","CSS3之animation动画"]]}],
"/02.页面/": [{"title":"html-css","collapsable":false,"children":[["01.html-css/01.flex布局语法.md","flex布局语法"],["01.html-css/02.flex布局案例-基础.md","flex布局案例-基础"],["01.html-css/03.flex布局案例-骰子.md","flex布局案例-骰子"],["01.html-css/04.flex布局案例-圣杯布局.md","flex布局案例-圣杯布局"],["01.html-css/05.flex布局案例-网格布局.md","flex布局案例-网格布局"],["01.html-css/06.flex布局案例-输入框布局.md","flex布局案例-输入框布局"],["01.html-css/07.CSS3之transform过渡.md","CSS3之transform过渡"],["01.html-css/08.CSS3之animation动画.md","CSS3之animation动画"]]}],
"/03.技术杂谈/": [{"title":"技术杂谈","collapsable":false,"children":[["01.技术杂谈/01.Git使用手册.md","Git使用手册"],["01.技术杂谈/02.GitHub高级搜索技巧.md","GitHub高级搜索技巧"],["01.技术杂谈/03.Markdown使用教程.md","Markdown使用教程"],["01.技术杂谈/04.npm常用命令.md","npm常用命令"],["01.技术杂谈/05.yaml语言教程.md","yaml语言教程"],["01.技术杂谈/06.解决百度无法收录搭建在GitHub上的个人博客的问题.md","解决百度无法收录搭建在GitHub上的个人博客的问题"],["01.技术杂谈/07.使用Gitalk实现静态博客无后台评论系统.md","使用Gitalk实现静态博客无后台评论系统"]]}],
"/03.技术杂谈/": [{"title":"技术","collapsable":false,"children":[["01.技术/01.Git使用手册.md","Git使用手册"],["01.技术/02.Markdown使用教程.md","Markdown使用教程"],["01.技术/03.npm常用命令.md","npm常用命令"],["01.技术/04.yaml语言教程.md","yaml语言教程"]]},{"title":"GitHub","collapsable":false,"children":[["02.GitHub/01.GitHub高级搜索技巧.md","GitHub高级搜索技巧"]]},{"title":"Nodejs","collapsable":false,"children":[["03.Nodejs/01.nodejs递归读取所有文件.md","nodejs递归读取所有文件"]]},{"title":"博客搭建","collapsable":false,"children":[["04.博客搭建/01.解决百度无法收录搭建在GitHub上的个人博客的问题.md","解决百度无法收录搭建在GitHub上的个人博客的问题"],["04.博客搭建/02.使用Gitalk实现静态博客无后台评论系统.md","使用Gitalk实现静态博客无后台评论系统"]]}],
"/04.其他/": [{"title":"学习","collapsable":false,"children":[["01.学习/01.学习网站.md","学习网站"],["01.学习/02.学习效率低,忘性很大怎么办?.md","学习效率低,忘性很大怎么办?"]]},{"title":"学习笔记","collapsable":false,"children":[["02.学习笔记/01.小程序笔记.md","小程序笔记"]]},{"title":"面试","collapsable":false,"children":[["03.面试/01.面试问题集锦.md","面试问题集锦"]]},["04.在线工具.md","在线工具"],["05.友情链接.md","友情链接"]],

View File

@ -0,0 +1,30 @@
---
title: nodejs递归读取所有文件
date: 2019-12-26
permalink: /pages/117708e0af7f0bd9
---
# nodejs递归读取所有文件
```js
var fs = require('fs');
var path = require('path');
function readFileList(dir, filesList = []) {
const files = fs.readdirSync(dir);
console.log(files);
files.forEach((item, index) => {
var fullPath = path.join(dir, item);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
readFileList(path.join(dir, item), filesList); //递归读取文件
} else {
filesList.push(fullPath);
}
});
return filesList;
}
var filesList = [];
readFileList(__dirname,filesList);
```

View File

@ -7,15 +7,15 @@ tagline: web前端技术博客积跬步以至千里致敬每个爱学习
features:
- title: 前端
details: JavaScript、ES6、vue框架等相关技术
url: /web/JavaScript/01.JavaScript中的名词概念
url: /pages/70d1485bb4e5754b/
imgname: /img/web.png
- title: 页面
details: html(5)/css(3),前端页面相关技术
url: /ui/00.flex布局语法
url: /pages/0a83b083bdf257cb/
imgname: /img/ui.png
- title: 技术杂谈
details: 技术文档、教程、技巧、学习笔记等
url: /other/git
url: /pages/9a7ee40fc232253e/
imgname: /img/other.png
footer: Copyright © 2019-present evanblog
---
@ -23,36 +23,37 @@ footer: Copyright © 2019-present evanblog
## :earth_americas:前端
* JavaScript
* [ES6面向对象](web/JavaScript/04.ES6面向对象)
* [new命令原理](web/JavaScript/05.new命令原理)
* [多种数组去重性能对比](web/JavaScript/06.多种数组去重性能对比)
* [更多... 👉](web/JavaScript/01.JavaScript中的名词概念)
* [ES6面向对象](/pages/1f4123be6f45abcd/)
* [new命令原理](/pages/8143cc480faf9a11/)
* [多种数组去重性能对比](/pages/e808fba1fa8fbab2/)
* [更多... 👉](/pages/70d1485bb4e5754b/)
## 🎨 页面
* HTML/CSS
* [flex布局语法](ui/00.flex布局语法)
* [flex布局案例-圣杯布局](ui/04.flex布局案例-圣杯布局)
* [CSS3之animation动画](ui/07.CSS3之animation动画)
* [更多... 👉](ui/00.flex布局语法)
* [flex布局语法](/pages/0a83b083bdf257cb/)
* [flex布局案例-圣杯布局](/pages/df9e7c7214fa5046/)
* [CSS3之animation动画](/pages/c2c0432138f6e042/)
* [更多... 👉](/pages/0a83b083bdf257cb/)
## :bulb:技术杂谈
* 技术
* [Git使用文档](other/git)
* [GitHub高级搜索技巧](other/github)
* [Markdown使用教程](other/markdown)
* [更多... 👉](other/git)
* [Git使用手册](/pages/9a7ee40fc232253e/)
* [GitHub高级搜索技巧](/pages/4c778760be26d8b3/)
* [Markdown使用教程](/pages/ad247c4332211551/)
* [解决百度无法收录搭建在GitHub上的静态博客的问题](/pages/41f87d890d0a02af/)
* [使用Gitalk实现静态博客无后台评论系统](/pages/1da0bf9a988eafe5/)
* [更多... 👉](/pages/9a7ee40fc232253e/)
* 学习
* [学习效果低,忘性很大怎么办?](other/LearningAndMemory)
* [学习网站分享](other/study)
* [学习网站分享](/pages/2e9ba3fa6e1ed0e9/)
* [学习效果低,忘性很大怎么办?](/pages/839158575e5c4866/)
* 面试
* [面试问题集锦](other/interview)
* [面试问题集锦](/pages/aea6571b7a8bae86/)
* 其他
* [在线工具](other/utils)
* [在线工具](/pages/9c2232288caaa8ec/)
* [关于本博客搭建](https://github.com/xugaoyi/evanblog)
* [解决百度无法收录搭建在GitHub上的个人博客的问题](other/baidushoulu)
## :email: 联系

View File

@ -2,8 +2,8 @@
"name": "evanblog",
"version": "1.0.0",
"scripts": {
"dev": "node utils/frontmatter.js && node utils/sidebarAndNav.js && vuepress dev docs",
"build": "node utils/frontmatter.js && node utils/sidebarAndNav.js && vuepress build docs",
"dev": "node utils/frontmatter.js && node utils/sidebar.js && vuepress dev docs",
"build": "node utils/frontmatter.js && node utils/sidebar.js && vuepress build docs",
"deploy": "bash deploy.sh",
"updateFM": "node utils/frontmatter.js -update"
},

View File

@ -1,11 +1,10 @@
/**
* 百度链接推送文件生成
* 生成百度链接推送文件
*/
const fs = require('fs');
const path = require('path');
const MD5 = require('md5.js');
const { readFileList, docsRoot, PREFIX } = require('./frontmatter');
const readFileList = require('./modules/readFileList');
const urlsRoot = path.join(__dirname, '..', 'urls.txt'); // 百度链接推送文件
const DOMAIN = 'https://evanblogweb.com'
@ -17,9 +16,9 @@ main();
*/
function main() {
fs.writeFileSync(urlsRoot, DOMAIN)
const files = readFileList(docsRoot); // 读取所有md文件
const files = readFileList(); // 读取所有md文件数据
files.forEach( file => {
const link = `\r\n${DOMAIN}${PREFIX}${new MD5().update(file.name).digest('hex').substring(0,16)}/`;
const link = `\r\n${DOMAIN}${file.permalink}/`;
console.log(link);
fs.appendFileSync(urlsRoot, link);
})

View File

@ -1,14 +1,10 @@
/**
* nodejs自动生成永久链接
* 生成frontmatter (标题日期永久链接)
*/
const fs = require('fs'); // 文件模块
const path = require('path'); // 路径模块
const logger = require('tracer').colorConsole(); // 控制台工具(用于控制台打印信息包含时间、打印类型、文件及代码行号、对象、颜色)
const MD5 = require('md5.js');
const arg = process.argv.splice(2)[0]; // 获取命令行 传入参数
const docsRoot = path.join(__dirname, '..', 'docs'); // docs文件路径
const PREFIX = '/pages/'; // 链接前缀
const readFileList = require('./modules/readFileList');
main();
@ -16,7 +12,7 @@ main();
* 主体函数
*/
function main() {
const files = readFileList(docsRoot); // 读取所有md文件
const files = readFileList(); // 读取所有md文件数据
files.forEach(file => {
let dataStr = fs.readFileSync(file.filePath, 'utf8');// 读取每个md文件内容
@ -48,8 +44,7 @@ function writeFrontMatter(file, dataStr) {
const stat = fs.statSync(file.filePath);
const date = stat.birthtime; // 创建时间
const dateStr = `${date.getFullYear()}-${zero(date.getMonth()+1)}-${zero(date.getDate())}`;
const permalink = `${PREFIX}${new MD5().update(file.name).digest('hex').substring(0,16)}`;
const newData = `---\r\ntitle: ${file.name}\r\ndate: ${dateStr}\r\npermalink: ${permalink}\r\n---\r\n` + dataStr;
const newData = `---\r\ntitle: ${file.name}\r\ndate: ${dateStr}\r\npermalink: ${file.permalink}\r\n---\r\n` + dataStr;
fs.writeFileSync(file.filePath, newData); // 写入
}
@ -57,53 +52,3 @@ function writeFrontMatter(file, dataStr) {
function zero(d){
return d.toString().padStart(2,'0')
}
// 读取所有md文件
function readFileList(dir, filesList = []) {
const files = fs.readdirSync(dir);
files.forEach((item, index) => {
let filePath = path.join(dir, item);
const stat = fs.statSync(filePath);
if (stat.isDirectory() && item !== '.vuepress') {
readFileList(path.join(dir, item), filesList); //递归读取文件
} else {
if(path.basename(dir) !== 'docs'){ // 过滤docs目录级下的文件
// 过滤非md文件
let [, name, type] = path.basename(filePath).split('.');
if(type === 'md'){
filesList.push({
name,
filePath
});
}
}
}
});
return filesList;
}
// 抛出给baiduPush.js调用
module.exports = {
readFileList,
docsRoot,
PREFIX
};
/**
* 读取指定目录下的文件绝对路径
* @param {String} root 指定的目录
*/
// function readTocs(root){
// const result = [];
// const files = fs.readdirSync(root); // 方法:读取目录,返回数组成员是root底下所有的目录名 (包含文件文件夹和文件)
// files.forEach(name => {
// const file = path.resolve(root, name); // 方法:将路径或路径片段的序列解析为绝对路径
// if (fs.statSync(file).isDirectory() && name !== '.vuepress') { // 是否为文件夹目录,并排除.vuepress文件
// result.push(file);
// }
// })
// return result;
// }

View File

@ -1,70 +0,0 @@
const {readdir, readFile, writeFile} = require('fs')
// const {resolve} = require('path')
// const FOLDERPATH = './docs/article'
const PathsIn = [
'./docs/web/',
'./docs/python/',
'./docs/other/'
]
function pReadFile(filepath) {
return new Promise((resolve, reject) => {
readdir(filepath, (err, files) => {
let filenames = []
files.forEach(file => {
if (file.toLowerCase() === 'readme.md') {
file = ``
} else {
file = file.replace('.md', '')
file = `${file}`
}
filenames.push(file)
})
filenames.sort() // 排序
resolve(filenames)
})
})
}
Promise.all([
pReadFile(PathsIn[0]),
pReadFile(PathsIn[1]),
pReadFile(PathsIn[2])
]).then(
arr => {
console.log(arr)
var params = {
'/web/': arr[0],
'/python/': arr[1],
'/other/': arr[2]
}
writeJson(params)
},
err => console.log(err)
)
function writeJson(params) {
//现将json文件读出来
readFile('./docs/.vuepress/config/sidebar.json', function(err, data) {
if (err) {
return console.error(err)
}
var person = data.toString() //将二进制的数据转换为字符串
person = JSON.parse(person) //将字符串转换为json对象
// person['/article_child/'] = params['/article_child/']
for (let key in params) {
person[key] = params[key]
}
console.log(person)
var str = JSON.stringify(person) //因为nodejs的写入文件只认识字符串或者二进制数所以把json对象转换成字符串重新写入json文件中
writeFile('./docs/.vuepress/config/sidebar.json', str, function(err) {
if (err) {
console.error(err)
}
console.log('----------新增成功-------------')
})
})
}

View File

@ -0,0 +1,36 @@
/**
* 读取所有md文件数据
*/
const fs = require('fs'); // 文件模块
const path = require('path'); // 路径模块
const MD5 = require('md5.js');
const docsRoot = path.join(__dirname, '..', '..', 'docs'); // docs文件路径
const PREFIX = '/pages/'; // 链接前缀
function readFileList(dir = docsRoot, filesList = []) {
const files = fs.readdirSync(dir);
files.forEach( (item, index) => {
let filePath = path.join(dir, item);
const stat = fs.statSync(filePath);
if (stat.isDirectory() && item !== '.vuepress') {
readFileList(path.join(dir, item), filesList); //递归读取文件
} else {
if(path.basename(dir) !== 'docs'){ // 过滤docs目录级下的文件
let [order, name, type] = path.basename(filePath).split('.');
order = parseInt(order, 10);
if(type === 'md'){ // 过滤非md文件
filesList.push({
order,
name,
filePath,
permalink: PREFIX + new MD5().update(name).digest('hex').substring(0,16) // 永久链接
});
}
}
}
});
return filesList;
}
module.exports = readFileList;

30
utils/nav.js Normal file
View File

@ -0,0 +1,30 @@
/**
* 生成导航栏数据
*/
// 思路从sidebar.js中抽离一套获取目录文件结构树的代码然后共用这块代码对返回的数据做二次处理分别产出侧边栏、导航栏、百度链接推送、首页内部链接数据。
// 考虑:需要对导航和首页内链接做个性化处理,暂时不做自动化生成。
// const fs = require('fs');
// const path = require('path');
// const readFileList = require('./modules/readFileList');
// const navPath = path.join(__dirname, '..', 'docs', '.vuepress', 'config', 'nav-auto.js'); // 导航栏js文件要保存的路径
// main();
// /**
// * 主体函数
// */
// function main() {
// let navArr = [{text: '首页', link: '/'}];
// const files = readFileList(); // 读取所有md文件数据
// files.forEach( file => {
// //if (file.order === 1) {
// //console.log(file.filePath.split('\\'))
// //}
// })
// }

107
utils/sidebar.js Normal file
View File

@ -0,0 +1,107 @@
/**
* 生成侧边栏数据
*/
const fs = require('fs'); // 文件模块
const path = require('path'); // 路径模块
const ejs = require('ejs'); // ejs模板引擎
const logger = require('tracer').colorConsole(); // 控制台工具(用于控制台打印信息包含时间、打印类型、文件及代码行号、对象、颜色)
const docsRoot = path.join(__dirname, '..', 'docs'); // docs文件路径
const sidebarPath = path.join(__dirname, '..', 'docs', '.vuepress', 'config', 'sidebar-auto.js'); // 侧边栏js文件要保存的路径
// sidebar-auto.js代码模板
const sidebarTemplate = `
// 侧边栏自动生成
module.exports = {
<% for (let item of sidebarData) { %>
"<%- item.path %>": <%- JSON.stringify(item.sidebarArr) %>,
<% } %>
}`;
main();
/**
* 主体函数
*/
function main() {
const sidebarData = [];
const tocs = readTocs(docsRoot); // 得到一个对路路径目录数组
tocs.forEach(toc => { // toc为每个目录的绝对路径
const sidebarArr = mapTocToSidebar(toc);
if (!sidebarArr.length) {
logger.warn(`该目录 "${toc}" 内部没有任何文件,将忽略生成对应侧边栏`);
return;
}
sidebarData.push({
path: `/${path.basename(toc)}/`, // basename返回绝对路径的文件名
// name: path.basename(toc).replace(/ /g, '_'), // 替换空格
sidebarArr
})
})
const sidebarDataTem = ejs.render(sidebarTemplate, { sidebarData });
fs.writeFileSync(sidebarPath, sidebarDataTem); // 同步写入文件, 参数一:写入到的文件, 参数二:写入的数据
logger.info('侧边栏生成成功!')
}
/**
* 读取指定目录下的文件绝对路径
* @param {String} root 指定的目录
*/
function readTocs(root){
const result = [];
const files = fs.readdirSync(root); // 方法:读取目录,返回数组成员是root底下所有的目录名 (包含文件文件夹和文件)
files.forEach(name => {
const file = path.resolve(root, name); // 方法:将路径或路径片段的序列解析为绝对路径
if (fs.statSync(file).isDirectory() && name !== '.vuepress') { // 是否为文件夹目录,并排除.vuepress文件
result.push(file);
}
})
return result;
}
/**
* 将对应目录映射为对应的侧边栏配置
* @param {String} root
* @param {String} prefix
*/
function mapTocToSidebar(root, prefix){
prefix = prefix || '';
let sidebar = [];
const files = fs.readdirSync(root); // 读取目录(文件和文件夹),返回数组
files.forEach(filename => {
const file = path.resolve(root, filename); // 方法:将路径或路径片段的序列解析为绝对路径
const stat = fs.statSync(file); // 文件信息
let [order, title, type] = filename.split('.');
order = parseInt(order, 10);
if (isNaN(order) || order < 0) {
logger.error(`该文件 "${file}" 序号出错请填写正确的序号序号约定请查看https://github.com/xugaoyi/blog/issues/113`);
return;
}
if (sidebar[order]) { // sidebar数组的order位置的数据的布尔值
logger.warn(`该文件 "${file}" 的序号在同一级别中有重复出现,将会被覆盖`);
}
if(stat.isDirectory()){ // 是否为文件夹目录
sidebar[order] = {
title,
collapsable: false,
children: mapTocToSidebar(file, prefix + filename + '/') // 子栏路径添加前缀
}
} else { // 是文件
if (type !== 'md') {
// 控制台错误信息
logger.error(`该文件 "${file}" 非md文件不支持非md文件类型`);
return;
}
sidebar[order] = [prefix + filename, title]; // [<前缀加完整文件名>, <文件标题>]
}
})
sidebar = sidebar.filter(item => item !== null && item !== undefined);
return sidebar;
}

View File

@ -1,251 +0,0 @@
/**
* nodejs自动生成侧边栏与导航栏
*/
const fs = require('fs'); // 文件模块
const path = require('path'); // 路径模块
const ejs = require('ejs'); // ejs模板引擎
const logger = require('tracer').colorConsole(); // 控制台工具(用于控制台打印信息包含时间、打印类型、文件及代码行号、对象、颜色)
const docsRoot = path.join(__dirname, '..', 'docs'); // docs文件路径
const sidebarPath = path.join(__dirname, '..', 'docs', '.vuepress', 'config', 'sidebar-auto.js'); // 侧边栏js文件要保存的路径
const navPath = path.join(__dirname, '..', 'docs', '.vuepress', 'config', 'nav-auto.js'); // 导航栏js文件要保存的路径
// sidebar-auto.js代码模板
const sidebarTemplate = `
// 侧边栏自动生成
module.exports = {
<% for (let item of sidebarData) { %>
"<%- item.path %>": <%- JSON.stringify(item.sidebarArr) %>,
<% } %>
}`;
// nav-auto.js代码模板
const navTemplate = `
// 导航栏自动生成
module.exports = {
{text: '首页', link: '/'},
<% for (let item of navData) { %>
{
text: '<%- item.name %>',
<% if (item.navArr) {%>
items: [
<% for (let i of item.xx) { %>
{text: '<%- i.name %>', link: <%- i.link %>},
<% } %>
]
<% } else { %>
link: <%- item.link %>
<% } %>
},
<% } %>
}`;
main();
/**
* 主体函数
*/
function main() {
const sidebarData = [];
const navData = [];
const tocs = readTocs(docsRoot); // 得到一个对路路径目录数组
tocs.forEach(toc => { // toc为每个目录的绝对路径
const sidebarArr = mapTocToSidebar(toc);
//const navArr = mapTocToNav(toc);
//console.log(navArr)
if (!sidebarArr.length) {
logger.warn(`该目录 "${toc}" 内部没有任何文件,将忽略生成对应侧边栏`);
return;
}
sidebarData.push({
path: `/${path.basename(toc)}/`, // basename返回绝对路径的文件名
// name: path.basename(toc).replace(/ /g, '_'), // 替换空格
sidebarArr
})
})
const sidebarDataTem = ejs.render(sidebarTemplate, { sidebarData });
fs.writeFileSync(sidebarPath, sidebarDataTem); // 同步写入文件, 参数一:写入到的文件, 参数二:写入的数据
logger.info('侧边栏生成成功!')
}
/**
* 读取指定目录下的文件绝对路径
* @param {String} root 指定的目录
*/
function readTocs(root){
const result = [];
const files = fs.readdirSync(root); // 方法:读取目录,返回数组成员是root底下所有的目录名 (包含文件文件夹和文件)
files.forEach(name => {
const file = path.resolve(root, name); // 方法:将路径或路径片段的序列解析为绝对路径
if (fs.statSync(file).isDirectory() && name !== '.vuepress') { // 是否为文件夹目录,并排除.vuepress文件
result.push(file);
}
})
return result;
}
/**
* 将对应目录映射为对应的侧边栏配置
* @param {String} root
* @param {String} prefix
*/
function mapTocToSidebar(root, prefix){
prefix = prefix || '';
let sidebar = [];
const files = fs.readdirSync(root); // 读取目录(文件和文件夹),返回数组
files.forEach(filename => {
const file = path.resolve(root, filename); // 方法:将路径或路径片段的序列解析为绝对路径
const stat = fs.statSync(file); // 文件信息
let [order, title, type] = filename.split('.');
order = parseInt(order, 10);
if (isNaN(order) || order < 0) {
logger.error(`该文件 "${file}" 序号出错请填写正确的序号序号约定请查看https://github.com/xugaoyi/blog`);
return;
}
if (sidebar[order]) { // sidebar数组的order位置的数据的布尔值
logger.warn(`该文件 "${file}" 的序号在同一级别中有重复出现,将会被覆盖`);
}
if(stat.isDirectory()){ // 是否为文件夹目录
sidebar[order] = {
title,
collapsable: false,
children: mapTocToSidebar(file, prefix + filename + '/') // 子栏路径添加前缀
}
} else { // 是文件
if (type !== 'md') {
// 控制台错误信息
logger.error(`该文件 "${file}" 非md文件不支持非md文件类型`);
return;
}
sidebar[order] = [prefix + filename, title]; // [<前缀加完整文件名>, <文件标题>]
}
})
sidebar = sidebar.filter(item => item !== null && item !== undefined);
return sidebar;
}
/**
* 将对应目录映射导航
* @param {String} root
*/
function mapTocToNav(root){
let nav = [];
const prefix = path.basename(root); // basename返回绝对路径的文件名
let [order , text] = prefix.split('.');
order = parseInt(order, 10);
if (nav[order]) {
logger.warn(
`该序号 "${order}" 在同一级别中有重复出现,将会被覆盖`
);
}
const files = fs.readdirSync(root); // 方法:读取目录,返回数组
if (files.length === 1) { // 只有一级导航
let link = ''
const file = path.resolve(root, files[0]); // 方法:将路径或路径片段的序列解析为绝对路径
const stat = fs.statSync(file); // 文件信息
if (stat.isDirectory()) { // 文件夹
const files2 = fs.readdirSync(file);
if (!files2.length) {
logger.warn(`该目录 "${file}" 内部没有任何文件,将忽略生成对应导航`);
return;
}
link = `/${prefix}/${files}/${files2[0]}`
} else { // 文件
const type = files[0].split('.')[2];
if( type === 'md'){
link = `/${prefix}/${files}`
} else if (type === 'txt') { // 外部链接
} else { // 非md、txt文件
logger.error(`该文件 "${file}" 非md或txt文件不支持该文件类型`);
}
}
nav[order] = {
text,
link
}
} else if (files.length > 1) { // 二级导航
nav[order] = {
text,
items: twoNav(files,)
}
} else {
logger.warn(`该目录 "${root}" 内部没有任何文件,将忽略生成对应导航`);
}
return nav;
}
// 获取二级导航数据
function twoNav(files){
var items = [];
files.forEach(file => {
console.log(file)
let [order, text, type] = file.split('.');
order = parseInt(order, 10);
if (items[order]) {
logger.warn(
`该序号 "${order}" 在同一级别中有重复出现,将会被覆盖`
);
}
if (type === 'md') {
items[order] = {
text,
link: '/04.其他/01.学习/01.学习网站'
}
} else if (type === 'txt') { // 外部链接文件
} else if (type === undefined) { // 文件夹
items[order] = {
text,
link: '/04.其他/01.学习/01.学习网站'
}
} else { // 其他文件
logger.error(`该文件 "${file}" 非md或txt文件不支持该文件类型`);
}
})
// files.forEach(file => {
// const file2 = path.resolve(root, file); // 方法:将路径或路径片段的序列解析为绝对路径
// const stat = fs.statSync(file2); // 文件信息
// if (stat.isDirectory()) { // 文件夹
// console.log(mapTocToNav(path.resolve(root, file)))
// } else {
// }
// })
// items: [
// {text: '学习', link: '/04.其他/01.学习/01.学习网站'},
// {text: '学习笔记', link: '/04.其他/02.学习笔记/01.小程序笔记'},
// {text: '面试', link: '/04.其他/03.面试/01.面试问题集锦'},
// {text: '在线工具', link: '/04.其他/04.在线工具'},
// {text: '友情链接', link: '/04.其他/05.友情链接'},
// ]
return items;
}