diff --git a/README.MD b/README.MD index 36df3d7..b3d7f22 100644 --- a/README.MD +++ b/README.MD @@ -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 文件在最上方才能生效 +## 其他 #### 百度自动推送和统计 diff --git a/docs/.vuepress/config/sidebar-auto.js b/docs/.vuepress/config/sidebar-auto.js index fae931e..c35b0c7 100644 --- a/docs/.vuepress/config/sidebar-auto.js +++ b/docs/.vuepress/config/sidebar-auto.js @@ -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","友情链接"]], diff --git a/docs/02.页面/01.html-css/00.flex布局语法.md b/docs/02.页面/01.html-css/01.flex布局语法.md similarity index 100% rename from docs/02.页面/01.html-css/00.flex布局语法.md rename to docs/02.页面/01.html-css/01.flex布局语法.md diff --git a/docs/02.页面/01.html-css/01.flex布局案例-基础.md b/docs/02.页面/01.html-css/02.flex布局案例-基础.md similarity index 100% rename from docs/02.页面/01.html-css/01.flex布局案例-基础.md rename to docs/02.页面/01.html-css/02.flex布局案例-基础.md diff --git a/docs/02.页面/01.html-css/02.flex布局案例-骰子.md b/docs/02.页面/01.html-css/03.flex布局案例-骰子.md similarity index 100% rename from docs/02.页面/01.html-css/02.flex布局案例-骰子.md rename to docs/02.页面/01.html-css/03.flex布局案例-骰子.md diff --git a/docs/02.页面/01.html-css/03.flex布局案例-网格布局.md b/docs/02.页面/01.html-css/05.flex布局案例-网格布局.md similarity index 100% rename from docs/02.页面/01.html-css/03.flex布局案例-网格布局.md rename to docs/02.页面/01.html-css/05.flex布局案例-网格布局.md diff --git a/docs/02.页面/01.html-css/05.flex布局案例-输入框布局.md b/docs/02.页面/01.html-css/06.flex布局案例-输入框布局.md similarity index 100% rename from docs/02.页面/01.html-css/05.flex布局案例-输入框布局.md rename to docs/02.页面/01.html-css/06.flex布局案例-输入框布局.md diff --git a/docs/02.页面/01.html-css/06.CSS3之transform过渡.md b/docs/02.页面/01.html-css/07.CSS3之transform过渡.md similarity index 100% rename from docs/02.页面/01.html-css/06.CSS3之transform过渡.md rename to docs/02.页面/01.html-css/07.CSS3之transform过渡.md diff --git a/docs/02.页面/01.html-css/07.CSS3之animation动画.md b/docs/02.页面/01.html-css/08.CSS3之animation动画.md similarity index 100% rename from docs/02.页面/01.html-css/07.CSS3之animation动画.md rename to docs/02.页面/01.html-css/08.CSS3之animation动画.md diff --git a/docs/03.技术杂谈/01.技术杂谈/01.Git使用手册.md b/docs/03.技术杂谈/01.技术/01.Git使用手册.md similarity index 100% rename from docs/03.技术杂谈/01.技术杂谈/01.Git使用手册.md rename to docs/03.技术杂谈/01.技术/01.Git使用手册.md diff --git a/docs/03.技术杂谈/01.技术杂谈/03.Markdown使用教程.md b/docs/03.技术杂谈/01.技术/02.Markdown使用教程.md similarity index 100% rename from docs/03.技术杂谈/01.技术杂谈/03.Markdown使用教程.md rename to docs/03.技术杂谈/01.技术/02.Markdown使用教程.md diff --git a/docs/03.技术杂谈/01.技术杂谈/04.npm常用命令.md b/docs/03.技术杂谈/01.技术/03.npm常用命令.md similarity index 100% rename from docs/03.技术杂谈/01.技术杂谈/04.npm常用命令.md rename to docs/03.技术杂谈/01.技术/03.npm常用命令.md diff --git a/docs/03.技术杂谈/01.技术杂谈/05.yaml语言教程.md b/docs/03.技术杂谈/01.技术/04.yaml语言教程.md similarity index 100% rename from docs/03.技术杂谈/01.技术杂谈/05.yaml语言教程.md rename to docs/03.技术杂谈/01.技术/04.yaml语言教程.md diff --git a/docs/03.技术杂谈/01.技术杂谈/02.GitHub高级搜索技巧.md b/docs/03.技术杂谈/02.GitHub/01.GitHub高级搜索技巧.md similarity index 100% rename from docs/03.技术杂谈/01.技术杂谈/02.GitHub高级搜索技巧.md rename to docs/03.技术杂谈/02.GitHub/01.GitHub高级搜索技巧.md diff --git a/docs/03.技术杂谈/03.Nodejs/01.nodejs递归读取所有文件.md b/docs/03.技术杂谈/03.Nodejs/01.nodejs递归读取所有文件.md new file mode 100644 index 0000000..a0c2f50 --- /dev/null +++ b/docs/03.技术杂谈/03.Nodejs/01.nodejs递归读取所有文件.md @@ -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); +``` + diff --git a/docs/03.技术杂谈/01.技术杂谈/06.解决百度无法收录搭建在GitHub上的个人博客的问题.md b/docs/03.技术杂谈/04.博客搭建/01.解决百度无法收录搭建在GitHub上的个人博客的问题.md similarity index 100% rename from docs/03.技术杂谈/01.技术杂谈/06.解决百度无法收录搭建在GitHub上的个人博客的问题.md rename to docs/03.技术杂谈/04.博客搭建/01.解决百度无法收录搭建在GitHub上的个人博客的问题.md diff --git a/docs/03.技术杂谈/01.技术杂谈/07.使用Gitalk实现静态博客无后台评论系统.md b/docs/03.技术杂谈/04.博客搭建/02.使用Gitalk实现静态博客无后台评论系统.md similarity index 100% rename from docs/03.技术杂谈/01.技术杂谈/07.使用Gitalk实现静态博客无后台评论系统.md rename to docs/03.技术杂谈/04.博客搭建/02.使用Gitalk实现静态博客无后台评论系统.md diff --git a/docs/index.md b/docs/index.md index e46f688..c5719d0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -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: 联系 diff --git a/package.json b/package.json index 77a3def..8bb5d97 100644 --- a/package.json +++ b/package.json @@ -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" }, diff --git a/utils/baiduPush.js b/utils/baiduPush.js index a3d74cb..2871ef1 100644 --- a/utils/baiduPush.js +++ b/utils/baiduPush.js @@ -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); }) diff --git a/utils/frontmatter.js b/utils/frontmatter.js index e6d43d1..659051b 100644 --- a/utils/frontmatter.js +++ b/utils/frontmatter.js @@ -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; -// } - - diff --git a/utils/getFilenames.js b/utils/getFilenames.js deleted file mode 100644 index 9345d26..0000000 --- a/utils/getFilenames.js +++ /dev/null @@ -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('----------新增成功-------------') - }) - }) -} diff --git a/utils/modules/readFileList.js b/utils/modules/readFileList.js new file mode 100644 index 0000000..f04a091 --- /dev/null +++ b/utils/modules/readFileList.js @@ -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; \ No newline at end of file diff --git a/utils/nav.js b/utils/nav.js new file mode 100644 index 0000000..a3984e3 --- /dev/null +++ b/utils/nav.js @@ -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('\\')) +// //} +// }) + +// } diff --git a/utils/sidebar.js b/utils/sidebar.js new file mode 100644 index 0000000..ce031e7 --- /dev/null +++ b/utils/sidebar.js @@ -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; +} \ No newline at end of file diff --git a/utils/sidebarAndNav.js b/utils/sidebarAndNav.js deleted file mode 100644 index d1dab53..0000000 --- a/utils/sidebarAndNav.js +++ /dev/null @@ -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; -} \ No newline at end of file