- 前端
- 静态站点
【免费下载链接】minimal-mistakes
:triangular_ruler: Jekyll theme for building a personal site, blog, project documentation, or portfolio.
导读
Minimal Mistakes 的assets/js/main.min.js并不是一份手写的巨型脚本,而是由一组 vendor 库、jQuery 插件和主题自带脚本通过 Rake 任务拼接压缩而成。本文以官方文档 docs/_docs/17-javascript.md 为主体,结合仓库内 Rakefile、package.json、_includes/scripts.html 等源码,系统讲解主题 JavaScript 的文件结构、自定义扩展方式、_config.yml注入配置,以及构建与调试流程,帮助你按需增删脚本并保持构建链路一致。
一、assets/js 目录结构与脚本职责
主题的 JavaScript 源码全部集中在 assets/js/ 目录,构建产物为assets/js/main.min.js。官方文档给出了如下结构树,与仓库实际内容一致:
minimal mistakes ├── assets │ ├── js │ │ ├── plugins │ │ │ ├── gumshoe.js # 简单的滚动监听(scrollspy) │ │ │ ├── jquery.ba-throttle-debounce.js # 函数限流(rate-limit) │ │ │ ├── jquery.fitvids.js # 视频嵌入自适应宽度 │ │ │ ├── jquery.greedy-navigation.js # priority plus 导航 │ │ │ ├── jquery.magnific-popup.js # 响应式 lightbox │ │ │ └── smooth-scroll.js # 站内锚点平滑滚动 │ │ ├── vendor │ │ │ └── jquery │ │ │ └── jquery-3.6.0.js # 主题内置的 jQuery 库 │ │ ├── _main.js # jQuery 插件设置与其他脚本 │ │ └── main.min.js # 拼接并压缩后的主题脚本各组成部分的职责与源码佐证如下:
- vendor/jquery/jquery-3.6.0.js:主题内置的 jQuery 3.6.0 运行时,是
_main.js和所有 jQuery 插件依赖的基座。 - plugins/ 下的五个插件:分别承担滚动监听(Gumshoe)、事件限流(jQuery ba-throttle-debounce)、视频宽度自适应(FitVids)、导航栏折叠(Greedy Navigation)与图片灯箱(Magnific Popup)等功能,另有非 jQuery 的 smooth-scroll.js 负责锚点平滑滚动。
- _main.js:主题自定义脚本入口,集中了插件初始化参数与页面交互逻辑(详见下文第四节)。
- main.min.js / main.min.js.map:Rake 构建产出的压缩脚本及其 source map,供浏览器调试映射回原始源码。
值得注意:官方文档中该目录树标注的 vendor jQuery 为jquery-3.5.1.js,而当前仓库实际为jquery-3.6.0.js(见 Rakefile 中的JS_FILES定义),阅读历史版本文档时需以仓库当前内容为准。
二、自定义脚本:三种注入路径
2.1 修改 assets/js/_main.js(推荐)
官方推荐的自定义方式是编辑 _main.js:在其中追加你自己的初始化代码,然后执行bundle exec rake js重新构建。该文件在构建时位于拼接队列的末尾,因此可以直接使用前面已加载的 jQuery 与插件。
_main.js的全部逻辑都被包裹在$(document).ready(function () { ... })中,是主题各种页面行为的汇总,包括:
- 对
#main调用fitVids(),让嵌入的 iframe 视频自适应容器宽度; - 作者关注按钮下拉菜单的显隐切换;
- 全屏搜索层的开关,以及按
Esc键关闭搜索层(_main.js中监听keyCode === 27); - 初始化
SmoothScroll(偏移量offset: 20、速度speed: 400)与Gumshoe滚动监听(为nav.toc目录高亮当前章节); - 为所有指向图片文件的链接自动添加
image-popup类,并初始化 Magnific Popup 灯箱(含画廊模式、缩放动画mfp-zoom-in等); - 为正文各级标题自动注入
header-link锚点图标; - 当
window.enable_copy_code_button为真时,为代码块注入“复制到剪贴板”按钮(对应_config.yml的enable_copy_code_button配置)。
这些实现细节可在 _main.js 中逐行查阅,新增脚本时可仿照其$(document).ready包裹方式,避免在 DOM 尚未就绪时操作元素。
2.2 向构建队列追加插件
如果你把第三方脚本放入assets/js/plugins/并希望它与其他脚本一起被拼接压缩,必须同步更新 package.json 中uglify脚本的参与文件清单——更准确地说,是更新 Rakefile 中JS_FILES的 glob 集合。当前定义如下:
JS_FILES = ["assets/js/vendor/jquery/jquery-3.6.0.js"] + Dir.glob("assets/js/plugins/*.js") + ["assets/js/_main.js"] JS_TARGET = "assets/js/main.min.js"由于Dir.glob("assets/js/plugins/*.js")会自动收集plugins/目录下所有.js文件,新增插件无需改动JS_FILES;但如果你删除了某个插件文件,或在其他目录新增了脚本,就需要调整这里的清单。package.json中的devDependencies仅声明了uglify-js(当前为^3.17.4),它正是压缩阶段所使用的工具。
2.3 通过 _config.yml 注入外部脚本
不想进入构建链路的话,可以在_config.yml中通过三个数组把脚本注入页面不同位置:
head_scripts: - https://code.jquery.com/jquery-3.3.1.min.js - /assets/js/your-custom-head-script.js footer_scripts: - /assets/js/your-custom-footer-script.js after_footer_scripts: - /assets/js/custom-script-loads-after-footer.jshead_scripts:渲染到<head>中,由 _includes/head.html 在样式表加载之后循环输出<script src>标签;footer_scripts与after_footer_scripts:渲染到</body>收尾处,由 _includes/scripts.html 处理。footer_scripts优先于搜索、统计与评论脚本,after_footer_scripts则排在其后。
警告(官方原文提示):一旦你为
footer_scripts赋值,主题自带的/assets/js/main.min.js就会被停用(见 _includes/scripts.html 的if site.footer_scripts ... else逻辑)。由于该文件内置了 jQuery 及上述各类插件,你需要自行寻找替代品并单独引入,否则页面依赖的 jQuery 功能将全部失效。
这一机制在 _includes/scripts.html 中有完整实现:footer_scripts存在时按列表逐条输出,否则才输出main.min.js;随后按site.search与search_provider决定是否引入 lunr / google / algolia 搜索脚本,再引入统计与分析脚本,最后输出after_footer_scripts。
三、构建流程:bundle exec rake js
主题刻意避免引入 Gulp、Grunt 等任务运行器,而是用一组 Rake 规则完成脚本的压缩拼接,以降低依赖数量。构建前需要:
- 安装 Node.js(
package.json中声明engines.node >= 0.10.0); - 在项目根目录执行
npm install,安装uglify-js等依赖; - 运行
bundle exec rake js。
注意:如果你是从旧版本主题升级而来,务必先把 package.json 一并拷贝到项目根目录,再执行
npm install,否则缺少uglify-js会导致构建失败。
bundle exec rake js的底层链路在 Rakefile 中定义如下:
task :js => JS_TARGET file JS_TARGET => ["_includes/copyright.js"] + JS_FILES do |t| sh Shellwords.join(%w[npx uglifyjs -c --comments /@mmistakes/ --source-map -m -o] + [t.name] + t.prerequisites) end- 目标文件
assets/js/main.min.js的依赖是_includes/copyright.js加JS_FILES(jQuery vendor +plugins/*.js+_main.js),任何依赖更新都会触发重新构建; - 压缩命令使用
npx uglifyjs,参数-c(压缩)、-m(变量名混淆)、--source-map(生成 source map)、--comments /@mmistakes/(保留版权注释)。构建产物头部保留了 _includes/copyright.js 中的版权横幅,即Minimal Mistakes Jekyll Theme 4.28.0 by Michael Rose ...,该文件由task :copyright依据 package.json 版本自动生成。
此外,仓库还提供了bundle exec rake watch_js任务(Rakefile):通过listen监听assets/js目录(忽略main.min.js本身),文件变动时自动重新执行:js任务,适合开发期持续构建。
四、调试:关闭压缩、按原样打包
压缩与混淆后的脚本在浏览器 DevTools 中难以阅读。官方给出了临时关闭压缩的方法——打开根目录 Rakefile,把file JS_TARGET的构建块改成如下形式:
file JS_TARGET => ["_includes/copyright.js"] + JS_FILES do |t| - sh Shellwords.join(%w[npx uglifyjs -c --comments /@mmistakes/ --source-map -m -o] + + sh Shellwords.join(%w[cat >] + [t.name] + t.prerequisites) end将npx uglifyjs ... -o替换为cat >后,bundle exec rake js会把_includes/copyright.js与所有JS_FILES按顺序原样拼接到main.min.js,不经过任何压缩与混淆,便于在浏览器中断点调试。调试验证完毕后,记得将 Rakefile 恢复原状并重新构建发布版本。
除关闭压缩外,还有两个辅助手段:
- 构建时
--source-map已生成assets/js/main.min.js.map,正常生产构建下浏览器可借助 source map 将压缩代码映射回原始源码; enable_copy_code_button(_config.yml中true, false (default))控制 _main.js 中复制代码按钮的注入逻辑,调试_main.js时可通过该开关快速验证相关代码分支。
五、与其他配置项的联动
主题 JavaScript 与_config.yml的多个开关协同工作,以下为与本文档最相关的组合(各配置项均可在根目录 _config.yml 中查阅默认值与注释):
| 配置项 | 默认值 | 相关脚本/位置 | 说明 |
|---|---|---|---|
head_scripts | 空 | _includes/head.html | 注入<head>的脚本数组 |
footer_scripts | 空 | _includes/scripts.html | 覆盖main.min.js的脚本数组 |
after_footer_scripts | 空 | _includes/scripts.html | 页面收尾处追加的脚本数组 |
search/search_provider | false /lunr | _includes/scripts.html | 决定是否加载搜索脚本及其提供方(lunr、google、algolia) |
enable_copy_code_button | false | _main.js | 是否在代码块上渲染复制按钮 |
此外,search_provider为 lunr 时,页面尾部还会通过_includes/search/lunr-search-scripts.html加载 assets/js/lunr/ 下的 lunr 及其语言/索引脚本(如 lunr-en.js、lunr-store.js),这部分独立于main.min.js的构建链路,自定义搜索时需另行关注。
六、FAQ:常见问题速查
- Q:改了
_main.js但页面没有变化?A:_main.js的改动需要执行bundle exec rake js重新生成main.min.js才会生效;开发期可使用bundle exec rake watch_js自动监听重建。 - Q:新增了
plugins/下的脚本,需要改package.json吗?A:当前仓库 Rakefile 使用Dir.glob("assets/js/plugins/*.js")自动收集,新增文件无需改动;官方文档提示的package.json更新仅在脚本清单不再被 glob 覆盖时才需要。 - Q:页面引入了
footer_scripts后 jQuery 方法报错?A:这是预期行为——footer_scripts会停用内置的main.min.js,你需要自行引入 jQuery 与所有依赖插件(参见官方文档警告与 _includes/scripts.html 的else分支)。 - Q:如何验证构建产物与源码一致?A:临时将 Rakefile 中的
npx uglifyjs换成cat >后重新构建,得到未压缩脚本对比即可;排查后务必还原。
结语
Minimal Mistakes 的脚本体系是一条清晰的流水线:源码(vendor + plugins +_main.js)→ Rake 拼接压缩 →main.min.js→ 页面注入(head_scripts/footer_scripts/after_footer_scripts)。理解 Rakefile 与 _includes/scripts.html 两个关键文件,即可在不动构建框架的前提下自由扩展脚本、注入第三方库,并在需要时临时关闭压缩进行源码级调试。相关主题文档还包括 05-configuration.md(配置项总览)与 17-javascript.md(本文所依据的原始文档)。
- 前端
- 静态站点
【免费下载链接】minimal-mistakes
:triangular_ruler: Jekyll theme for building a personal site, blog, project documentation, or portfolio.
相关推荐
Minimal Mistakes 样式系统定制完全指南:SCSS 架构、变量覆写与主题皮肤
Minimal Mistakes 样式系统定制完全指南:SCSS 架构、变量覆写与主题皮肤 本篇技术指南完整讲解 Minimal Mistakes Jekyll
前端静态站点Minimal Mistakes 主题目录结构全解析:从 _data 到 assets 的 Jekyll 文件组织指南
Minimal Mistakes 主题目录结构全解析:从 _data 到 assets 的 Jekyll 文件组织指南 本文以 Minimal Mistakes
前端静态站点Minimal Mistakes 主题 teaser 图片与 OpenGraph 覆盖(og_image)配置实战指南
Minimal Mistakes 主题 teaser 图片与 OpenGraph 覆盖(og_image)配置实战指南 本文围绕 Minimal Mistake
前端静态站点
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考