1.使用 Webpack-chain 链式生成 webpack 配置(读 vuepress 二)
2.关于 VuePress 的源码主题
3.markdown-it 原理解析
4.VuePress 博客优化之 last updated 最后更新时间如何设置
5.《了不起的Markdown》第六章
使用 Webpack-chain 链式生成 webpack 配置(读 vuepress 二)
在使用 VuePress 构建项目时,你可能会发现它的分析配置文件中引入了一个叫做 webpack-chain 的库。VuePress 使用 webpack-chain 来生成它的源码三个配置:基础配置、dev 配置、分析build 配置。源码这个库与传统方式生成配置文件的分析仓库领用系统源码模式有所不同。本文将深入探讨 webpack-chain 如何帮助简化配置过程。源码
首先,分析webpack-chain 提供了两种数据结构:ChainMap 和 ChainedSet。源码ChainMap 类似于 ES6 的分析 Map,而 ChainedSet 类似于 Set。源码这两种数据结构都允许通过链式方法进行操作,分析大大提高了配置的源码灵活性和可读性。
ChainedSet 和 ChainedMap 都继承于 Chainable 类,分析它们分别提供了对配置文件中特定部分的源码管理功能。例如,你可以通过 ChainedSet 的方法来添加、删除或查询配置中的任意部分,这种操作方式使得配置修改变得更加直观和高效。
webpack-chain 的核心原理在于实现链式调用,通过 Chainable 类来支持这一特性。链式调用通过 end 方法返回调用链中最前端的对象,使得配置构建过程更为简洁和直观。在 VuePress 中,这种链式调用方式被充分利用,使得开发者能够以更少的代码量完成复杂的配置任务。
在 VuePress 的源代码中,你可以看到如 createBaseConfig.js 这样的文件,其中包含了使用 webpack-chain 功能的示例。例如,生成配置时可能会包含对特定样式语言的处理,通过链式调用进行顺序加载和处理,这极大减少了配置文件的编写工作量,同时提供了高度的定制性和灵活性。
使用 webpack-chain 的关键在于理解其核心功能和如何在实际项目中灵活应用。它可以帮助简化配置过程,提高开发效率。然而,引入新的库或工具总是需要权衡其带来的好处与项目成本。在考虑使用 webpack-chain 时,确保它能够为你的wms 源码分析项目带来显著的收益,从而抵消引入新库所增加的成本。
总结起来,webpack-chain 为 VuePress 和其他项目提供了更高效、更灵活的配置管理方式。通过学习其原理和应用示例,你可以更好地利用这一工具,提高项目的开发效率和可维护性。
关于 VuePress 的主题
主题的概念在VuePress中同样重要,它不仅关乎外观,更涉及功能的扩展与增强用户体验。
在不使用主题时,VuePress仅提供基本功能,如侧边栏配置等,需要手动设置,耗时且繁琐。通过主题,可以轻松实现如加载动画、返回顶部、评论等高级功能。
本文以vdoing主题为例,展示如何集成并利用主题的强大功能。首先,需确保博客内容丰富,以便全面展示主题效果。
修改Markdown文件和目录格式以符合vdoing主题要求,如使用特定编号前缀。增加标题内容,增强博客实用性。
主题通过npm安装,配置于config.js文件中。通过删除原侧边栏配置并应用新主题的侧边栏设置,博客界面显著提升。
网站右侧添加了切换皮肤等额外功能,未在默认VuePress主题中提供。点击特定文章链接,可见主题自动生成的侧边栏和目录页。
vdoing主题自动为Markdown文件添加front matter,简化文档管理。提供丰富功能,如自动目录生成、自动缩进 源码导航栏、文章分类等。
VuePress支持多种主题,如vdoing、laihua-coder/awesome-vuepress等。选择主题时,应考虑其功能、易用性和个人喜好。
通过新建项目演示不同功能,提供源码,方便读者体验和选择。如需获取演示源码,可切换项目分支。
查阅官方文档获取深入指导:使用主题 | VuePress,Front Matter | VuePress,vdoing官网文档:vuepress-theme-vdoing。
VuePress主题生态丰富,可极大地增强博客功能和用户体验,适合广大开发者和博主。
markdown-it 原理解析
在《一篇带你用 VuePress + Github Pages 搭建博客》中,我们使用 VuePress 搭建了一个博客,最终的效果查看: TypeScript 中文文档。
在搭建博客的过程中,我们出于实际的需求,在《VuePress 博客优化之拓展 Markdown 语法》中讲解了如何写一个 markdown-it插件,本篇我们将深入markdown-it的源码,讲解 markdown-it的执行原理,旨在让大家对 markdown-it有更加深入的理解。
引用 markdown-it Github 仓库的介绍:
Markdown parser done right. Fast and easy to extend.
可以看出markdown-it是一个 markdown 解析器,并且易于拓展。
其演示地址为: markdown-it.github.io/
markdown-it具有以下几个优势:
使用源码解析
我们查看markdown-it 的 入口代码,可以发现其代码逻辑清晰明了:
从render方法中也可以看出,其渲染分为两个过程:
跟 Babel 很像,不过 Babel 是转换为抽象语法树(AST),而markdown-it 没有选择使用 AST,主要是为了遵循 KISS(Keep It Simple, Stupid) 原则。
Tokens
那 Tokens 长什么样呢?我们不妨在 演示页面中尝试一下:
可以看出# header生成的 Token 格式为(注:这里为了展示方便,简化了):
具体 Token 里的字段含义可以查看 Token Class。
通过这个简单的 Tokens 示例也可以看出 Tokens 和 AST 的区别:
Parse
查看 parse 方法相关的代码:
可以看到其具体执行的代码,应该是ai看相 源码写在了./parse_core 里,查看下 parse_core.js 的代码:
可以看出,Parse 过程默认有 6 条规则,其主要作用分别是:
1. normalize
在 CSS 中,我们使用normalize.css 抹平各端差异,这里也是一样的逻辑,我们查看 normalize 的代码,其实很简单:
我们知道\n是匹配一个换行符,\r是匹配一个回车符,那这里为什么要将 \r\n替换成 \n 呢?
我们可以在阮一峰老师的这篇 《回车与换行》中找到\r\n出现的历史:
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model )的玩意,每秒钟可以打个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。 于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做"回车",告诉打字机把打印头定位在左边界;另一个叫做"换行",告诉打字机把纸向下移一行。 这就是"换行"和"回车"的来历,从它们的英语名字上也可以看出一二。 后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。 Unix系统里,每行结尾只有"",即"\n";Windows系统里面,每行结尾是"",即"\r\n";Mac系统里,lua源码教程每行结尾是""。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。
之所以将\r\n替换成 \n其实是 遵循规范:
A line ending is a newline (U+A), a carriage return (U+D) not followed by a newline, or a carriage return and a following newline.
其中 U+A 表示换行(LF) ,U+D 表示回车(CR) 。
除了替换回车符外,源码里还替换了空字符,在 正则中,\0表示匹配 NULL(U+)字符,根据 WIKI 的解释:
空字符(Null character)又称结束符,缩写 NUL,是一个数值为 0 的控制字符。 在许多字符编码中都包括空字符,包括ISO/IEC (ASCII)、C0控制码、通用字符集、Unicode和EBCDIC等,几乎所有主流的编程语言都包括有空字符 这个字符原来的意思类似NOP指令,当送到列表机或终端时,设备不需作任何的动作(不过有些设备会错误的打印或显示一个空白)。
而我们将空字符替换为\uFFFD,在 Unicode 中,\uFFFD表示替换字符:
之所以进行这个替换,其实也是遵循规范,我们查阅 CommonMark spec 2.3 章节:
For security reasons, the Unicode character U+ must be replaced with the REPLACEMENT CHARACTER (U+FFFD).
我们测试下这个效果:
效果如下,你会发现原本不可见的空字符被替换成替换字符后,展示了出来:
2. block
block 这个规则的作用就是找出 block,生成 tokens,那什么是 block?什么是 inline 呢?我们也可以在 CommonMark spec 中的 Blocks and inlines 章节 找到答案:
We can think of a document as a sequence of blocks—structural elements like paragraphs, block quotations, lists, headings, rules, and code blocks. Some blocks (like block quotes and list items) contain other blocks; others (like headings and paragraphs) contain inline content—text, links, emphasized text, images, code spans, and so on.
翻译一下就是:
我们认为文档是由一组 blocks 组成,结构化的元素类似于段落、引用、列表、标题、代码区块等。一些 blocks (像引用和列表)可以包含其他 blocks,其他的一些 blocks(像标题和段落)则可以包含 inline 内容,比如文字、链接、 强调文字、、代码片段等等。
当然在markdown-it中,哪些会识别成 blocks,可以查看 parser_block.js,这里同样定义了一些识别和 parse 的规则:
关于这些规则我挑几个不常见的说明一下:
code 规则用于识别 Indented code blocks (4 spaces padded),在 markdown 中:
fence 规则用于识别 Fenced code blocks,在markdown 中:
hr 规则用于识别换行,在 markdown 中:
reference 规则用于识别 reference links,在 markdown 中:
html_block 用于识别 markdown 中的 HTML block 元素标签,就比如div。
lheading 用于识别 Setext headings,在 markdown 中:
3. inline
inline 规则的作用则是解析 markdown 中的 inline,然后生成 tokens,之所以 block 先执行,是因为 block 可以包含 inline ,解析的规则可以查看 parser_inline.js:
关于这些规则我挑几个不常见的说明一下:
newline规则用于识别 \n,将 \n 替换为一个 hardbreak 类型的 token
backticks 规则用于识别反引号:
entity 规则用于处理 HTML entity,比如 { ``¯``"等:
4. linkify
自动识别链接
5. replacements
将(c)`` (C) 替换成 ©,将 替换成 ,将 !!!!! 替换成 !!!,诸如此类:
6. smartquotes
为了方便印刷,对直引号做了处理:
Render
Render 过程其实就比较简单了,查看 renderer.js 文件,可以看到内置了一些默认的渲染 rules:
其实这些名字也是 token 的 type,在遍历 token 的时候根据 token 的 type 对应这里的 rules 进行执行,我们看下 code_inline 规则的内容,其实非常简单:
自定义 Rules
至此,我们对 markdown-it 的渲染原理进行了简单的了解,无论是 Parse 还是 Render 过程中的 Rules,markdown-it 都提供了方法可以自定义这些 Rules,这些也是写 markdown-it 插件的关键,这些后续我们会讲到。
系列文章
博客搭建系列是我至今写的唯一一个偏实战的系列教程,讲解如何使用 VuePress 搭建博客,并部署到 GitHub、Gitee、个人服务器等平台。
微信:「mqyqingfeng」,加我进冴羽唯一的读者群。
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。
VuePress 博客优化之 last updated 最后更新时间如何设置
探究 VuePress 博客中最后更新时间的设置与实现
在使用 VuePress 搭建博客的过程中,发现未自动显示最后更新时间。查阅官方文档得知,VuePress 自带显示最后更新时间的插件,通过在 config.js 文件中配置即可启用。
官方示例中将 lastUpdated 设置为 "上次更新",但实际操作并未显示最后更新时间,原因在于使用本地编写源码并使用构建命令,将结果 git init 后强制提交,此时并未在 git log 中获取到更新记录。
深入查看插件源码发现,lastUpdated 是基于 git 提交记录生成的,因此需要在 git 仓库中操作。分析代码实现后,发现直接修改 $page 计算属性即可实现最后更新时间的展示。
在 Markdown 文件中直接使用 Vue 语法编写更新时间的代码,但此法较为繁琐。为提高效率,可将此代码封装为 Vue 组件,实现全局引入并自动更新时间的功能。
在 .vuepress/components 文件夹下创建 LastUpdated.vue 组件,引用后即可在 Markdown 文件中自动显示最后更新时间。此方法简化了更新流程,并确保了时间的全局同步。
回顾官方文档,lastUpdated 是基于 git 提交记录生成的时间戳,且仅在页面首次提交后生效。在执行编译命令时,通过 git log 获取时间并写入编译后的代码中。
解决未显示时间问题的关键在于初始化 git 仓库,并确保编译后文件的 git 状态。可通过在根目录执行 git init 进行初始化,但在添加文件时需注意避免重复的 git 仓库。
解决重复 git 仓库问题,使用 .gitignore 文件忽略编译后的 dist 目录,确保只在一个 git 仓库内操作。执行 git add 后,即可在编译后的代码中显示最后更新时间。
最后,若需自定义 lastUpdated 前缀或调整时间格式,参照官方文档进行配置。实现后,整个博客页面将展示最新的更新时间,简化了手动更新操作。
搭建博客系列教程旨在分享 VuePress 搭建、部署的实战经验,欢迎关注微信「mqyqingfeng」加入读者群。如有错误或不严谨之处,请指正,感谢支持。
《了不起的Markdown》第六章
笔记软件是现代人记录重要信息、事件与想法的重要工具。Markdown作为一种简洁的文本格式标记语言,因其专注且高效的写作特点,在笔记软件中大放异彩。以下介绍几款流行的笔记软件及其与Markdown的结合: 印象笔记 印象笔记支持基础Markdown语法与GFM语法,用户可以快速绘制数学公式、流程图、时序图、甘特图,并提供多种图表绘制功能。在印象笔记中新建Markdown笔记,可通过左上角的新建Markdown笔记按钮或快捷键实现。默认编辑模式下,左侧为源码,右侧为预览。工具栏提供常用标记的快速插入功能,包括图表模板。使用添加流程图功能后,可快速插入流程图模板。印象笔记支持四种图表:饼图、折线图、柱状图、条形图,预览界面支持交互操作。上传、直接拖拽添加或从剪切板粘贴均支持,大小可通过右键菜单调整。导出Markdown格式或转换为PDF文件亦可实现。 有道云笔记 有道云笔记支持Markdown功能,包括基础Markdown语法、代码高亮、任务列表、表格、数学公式等。在电脑端与Web端,新建Markdown文件可通过右键菜单中的新文档选项完成。手机端则在+按钮中选择Markdown。在Markdown编辑环境中,常用语法可通过工具栏的快速插入图标直接使用。有道云笔记还提供快速插入公式与图表模板的功能,简化了创建图表的过程。 OneNote OneNote本身不直接支持Markdown,但通过插件可以实现Markdown功能。插件可在网站上下载,适用于Windows版本。 在线多人协作工具 在线文档协作工具如腾讯文档和石墨文档,支持简单的Markdown语法,如标题、分隔线、列表等,且在编辑时直接通过“标记符号+空格”使用Markdown,效果实时显示。 写博客 知乎支持基础Markdown语法,通过“标记符号+空格”对文字进行排版。简书与CSDN也分别支持Markdown编辑器,其中CSDN的Markdown编辑器功能齐全,可以导入/导出Markdown文件,解析GFM语法。 写微信公众号文章 对于写微信公众号文章,Markdown虽然方便,但某些格式在微信编辑器中不支持。推荐使用Online-Markdown或Md2All等在线格式化工具,将Markdown文档渲染为适合微信公众号的格式。 写邮件 Markdown Here插件允许用户在邮件编辑器中使用Markdown语法,通过该插件,Markdown编辑器直接集成在邮件编辑器中,实现Markdown写作,简化了邮件写作流程。 其他常见工具 锤子便签支持Markdown语法,适用于文字排版;DayOne日记软件支持Markdown对日记进行排版,使用简单;交互式文档工具如Jupyter Notebook与R Markdown,分别在数据分析与技术写作领域提供强大的功能支持,支持代码的实时执行与显示结果。Markdown页编写工具md-page允许直接使用Markdown编写网页,无需转换格式。项目文档写作工具如MkDocs与VuePress,提供快速创建项目文档的解决方案,支持Markdown编写。 付费软件方面,如Ulysses、MWeb、MarkdownPad与CMD Markdown等提供更专业的服务与更好的用户体验,适合不同需求的用户群体。 小结 本文详细介绍了多个专业Markdown工具,旨在帮助用户根据不同的写作场景选择合适的工具。从记笔记、写博客、写邮件、编写技术文档到创建交互式文档,Markdown工具提供了丰富的功能与便捷的体验,满足了现代写作的多样化需求。