关于前端:VuePress-博客优化之-last-updated-最后更新时间如何设置

42次阅读

共计 5343 个字符,预计需要花费 14 分钟才能阅读完成。

前言

在《一篇带你用 VuePress + Github Pages 搭建博客》中,咱们应用 VuePress 搭建了一个博客,然而浏览最终搭建的站点:TypeScript4 中文文档,咱们会发现,在每篇文章的底部,并没有像 VuePress 官网文档那样,呈现最初更新的工夫:

这篇咱们来探索下如何实现最初更新工夫。

官网自带

查阅 VuePress 的官网文档,咱们能够晓得,VuePress 自带显示最初更新工夫的插件,在默认主题下,无需装置本插件,因为 VuePress 的 core 中曾经蕴含此插件。

你能够在 config.js 文件中间接应用:

// .vuepress/config.js
module.exports = {
  themeConfig: {lastUpdated: '上次更新', // string | boolean}
}

留神,themeConfig.lastUpdated 默认是敞开的,在给定一个字符串后,它会作为前缀显示(默认值是:Last Updated)。

在这个示例代码中,咱们设置 lastUpdated 的值为 “ 上次更新 ”,最终的成果应该跟下面的 VuePress 官网的截图是统一的。

在这里,也给了一个应用须知:

因为 lastUpdated 是基于 git 的, 所以你只能在一个基于 git 的我的项目中启用它。此外,因为应用的工夫戳来自 git commit,因而它将仅在给定页的第一次提交之后显示,并且仅在该页面后续提交更改时更新。

那咱们依照文档配置一下试试,后果发现并没有呈现所谓的最初更新工夫,因为没有内容显示,显得这里的空白也很大:

查看插件源码

那这是为什么呢?回顾下咱们代码编译和提交的过程,其实咱们是在本地写好源码,而后执行构建命令,将构建后的后果 git init,而后强制提交到近程仓库。这从咱们的 deploy.sh 脚本文件能够看出:

npm run docs:build

cd docs/.vuepress/dist

git init
git add -A
git commit -m 'deploy'

git push -f git@github.com:mqyqingfeng/learn-typescript.git master:gh-pages

那应该没有什么问题呀,咱们就是作为 git 仓库提交的,也提交了一个 commit,为什么会显示不进去呢?

而且说起来,last updated 最初更新工夫是怎么生成的呢?他怎么就依据 git 的提交记录主动生成工夫了呢?

为了解决这个问题,也为了满足咱们的好奇心,咱们无妨去看下这个 npm 包 @vuepress/plugin-last-updated 的源码,后果发现它的源码意外的简略:

const path = require('path')
const spawn = require('cross-spawn')

/**
 * @type {import('@vuepress/types').Plugin}
 */
module.exports = (options = {}, context) => ({extendPageData ($page) {const { transformer, dateOptions} = options
    const timestamp = getGitLastUpdatedTimeStamp($page._filePath)
    const $lang = $page._computed.$lang
    if (timestamp) {
      const lastUpdated = typeof transformer === 'function'
        ? transformer(timestamp, $lang)
        : defaultTransformer(timestamp, $lang, dateOptions)
      $page.lastUpdated = lastUpdated
      $page.lastUpdatedTimestamp = timestamp
    }
  }
})

function defaultTransformer (timestamp, lang, dateOptions) {return new Date(timestamp).toLocaleString(lang, dateOptions)
}

function getGitLastUpdatedTimeStamp (filePath) {
  let lastUpdated
  try {
    lastUpdated = parseInt(spawn.sync(
      'git',
      ['log', '-1', '--format=%at', path.basename(filePath)],
      {cwd: path.dirname(filePath) }
    ).stdout.toString('utf-8')) * 1000
  } catch (e) {/* do not handle for now */}
  return lastUpdated
}

通过源码,咱们能够发现,之所以能生成工夫,其实是通过利用 git log 命令获取工夫,而后写入 $page 全局属性中。

$page

那 $page 是什么呢,咱们查看官网文档 – 全局计算属性章节:

在 VuePress 中,内置了一些外围的计算属性,以供默认主题或自定义主题应用。

对于每个页面,都会有一个 $page 计算属性,官网还给了一个 $page 的示例:

{
  "title": "Global Computed",
  "frontmatter": {"sidebar": "auto"},
  "regularPath": "/zh/miscellaneous/global-computed.html",
  "key": "v-bc9a3e3f9692d",
  "path": "/zh/miscellaneous/global-computed.html",
  "headers": [
    {
      "level": 2,
      "title": "$site",
      "slug": "site"
    },
    {
      "level": 2,
      "title": "$page",
      "slug": "page"
    },
    ...
  ]
}

咱们由此能够想到,VuePress 其实针对每个页面都生成了一个 $page 计算属性,而后在多个中央展现计算属性的值,那突破口就来了,如果咱们像源码那样,间接向 $page 写入一个 lastUpdated 属性呢?

Markdown 中应用 Vue

咱们每个页面都是依据 markdown 文件生成的,咱们怎么在一个 markdown 文件中向 $page 写入一个 lastUpdated 属性呢,还好在 VuePress 中,markdown 是能够间接应用 Vue 语法的,这里应用 vuepress-theme-reco 主题的示例代码作为解说:

// 在 markdown 文案中间接写

<p class="demo" :class="$style.example"></p>

<style module>
.example {color: #41b883;}
</style>

<script>
export default {props: ['slot-key'],
  mounted () {document.querySelector(`.${this.$style.example}`)
      .textContent = '这个块是被内联的脚本渲染的,款式也采纳了内联款式。'
  }
}
</script>

在页面的展现成果如下:

那么咱们间接在 Markdown 中间接写入如下的 Vue 代码:

<script>
export default {mounted () {this.$page.lastUpdated = "2022/1/6 下午 6:09:09";}
  }
</script>

咱们本地运行代码,而后查看页面,就会发现真的胜利写入了最初更新工夫:

Vue 组件

然而这样每篇都插入一段 Vue 代码,很麻烦呀,我能够勉强承受手动更新一下工夫,但我不能承受每次那么多篇都要手动改一下呀,即使用批量替换也有点麻烦,就没有更优化的形式吗?

那咱们能够将这段 Vue 代码抽离成一个 Vue 组件,将具体的工夫封装在组件中,而后每个 md 文件引入这个组件即可,而 VuePress 也是能够反对引入组件的。查看下官网文档:

所有在 .vuepress/components 中找到的 *.vue 文件将会主动地被注册为全局的异步组件,如:

.
└─ .vuepress
   └─ components
      ├─ demo-1.vue
      ├─ OtherComponent.vue
      └─ Foo
         └─ Bar.vue

你能够间接应用这些组件在任意的 Markdown 文件中(组件名是通过文件名取到的):

<demo-1/>
<OtherComponent/>
<Foo-Bar/>

那咱们就在 .vuepress 文件夹下新建一个 components 文件夹,而后创立一个 LastUpdated.vue 文件,代码为:

<template>
</template>

<script>
export default {props: ['slot-key'],
  mounted () {this.$page.lastUpdated = "2022/1/6 下午 2:00:00";}
};
</script>

而后咱们在具体要应用这个工夫的 md 文件里写入:

<LastUpdated />

天然也是胜利的写入了工夫:

这样咱们每次批改 LastUpdated 组件里的工夫,所有引入该组件的中央工夫都会扭转。

Markdown

这个问题看似是通过曲线救国的形式解决了,就是每次都须要手动更新一次,而且所有援用的中央都会更新,如果要实现某个中央部分更新,还要本人写入工夫,其实还是有点麻烦的。

让咱们再回顾下官网文档里的介绍:

因为 lastUpdated 是基于 git 的, 所以你只能在一个基于 git 的我的项目中启用它。此外,因为应用的工夫戳来自 git commit,因而它将仅在给定页的第一次提交之后显示,并且仅在该页面后续提交更改时更新。

还有官网文档里的这句:

lastUpdated 是这个文件最初一次 git 提交的 UNIX 工夫戳

那这句里的「这个文件」到底是指哪个文件呢?回忆下咱们的提交形式,咱们每次只提交了编译后的文件,编译的文件为 HTML 文件,尽管它是以 git 仓库的模式提交的,但在它编译完后就应该曾经是动态的了,不可能是在运行 HTML 文件的时候再通过 git 仓库获取最初提交工夫的吧,所以这个文件不应该是指编译后的文件,那排除掉编译后的文件,其实咱们就能够想到,这里的文件指的其实应该是你编写的 markdown 文件。在你执行编译命令的时候,从 git log 中获取工夫,写入编译后的代码中。

这也能够解释为什么咱们依照官网文档配置后,没有显示工夫,因为咱们的源码的确不是 git 仓库,咱们只是把编译后的代码生成了一个代码仓库提交下来,那天然是获取不到工夫。

所以咱们进入源码的根目录,而后执行 git init,要留神,如果要生成最初更新工夫,须要:

  1. 仓库 git init
  2. 文件至多 commit 一次

但当咱们 git add 的时候,可能会报错,会提醒你曾经增加了另外一个 git 仓库在你以后的仓库:

You’ve added another git repository inside your current repository.

这是因为咱们编译生成的 dist 目录也是一个 git 仓库,但其实解决形式很简略,咱们间接用一个 .gitignore 文件 将 dist 目录疏忽掉不就好了,这是 .gitignore 文件写入的内容:

node_modules
dist

咱们 commit 后再运行代码,就会看到每篇文章都会呈现最初更新工夫:

Last updated

如果你想更改工夫后面的 Last Updated: 这段字符,你能够在 config.js 写入:

module.exports = {
    themeConfig: {lastUpdated: '上次更新'}
}

展现的成果就会变为:

更改格局

如果你想要更改工夫展现的格局,参照 @vuepress/plugin-last-updated 的官网文档,你能够这样写:

const moment = require('moment');

module.exports = {
  plugins: [
    [
      '@vuepress/last-updated',
      {transformer: (timestamp, lang) => {
          // 不要忘了装置 moment
          const moment = require('moment')
          moment.locale(lang)
          return moment(timestamp).fromNow()}
      }
    ]
  ]
}

展现的成果为:

至此,尽管绕了一圈,但还是简略的解决了这个问题。

系列文章

博客搭建系列是我至今写的惟一一个偏实战的系列教程,解说如何应用 VuePress 搭建博客,并部署到 GitHub、Gitee、集体服务器等平台。

  1. 一篇带你用 VuePress + GitHub Pages 搭建博客
  2. 一篇教你代码同步 GitHub 和 Gitee
  3. 还不会用 GitHub Actions?看看这篇
  4. Gitee 如何主动部署 Pages?还是用 GitHub Actions!
  5. 一份前端够用的 Linux 命令
  6. 一份简略够用的 Nginx Location 配置解说
  7. 一篇教你博客如何部署到本人的服务器

微信:「mqyqingfeng」,加我进冴羽惟一的读者群。

如果有谬误或者不谨严的中央,请务必给予斧正,非常感激。如果喜爱或者 有所启发,欢送 star,对作者也是一种激励。

正文完
 0