使用 Sapper 和 Markdown 创建博客 概念设置 帖子数据 插件 阅读帖子 索引页 博客详情页 部署 摘要 截屏视频

2025-06-09

使用 Sapper 和 Markdown 创建博客

概念

设置

帖子数据

插件

阅读帖子

索引页

博客详细信息页面

部署

概括

截屏录像

Sapper是一个用于创建Svelte应用的工具包。它内置了一系列约定,可帮助您快速启动和运行项目。

它可以部署为静态站点,也可以部署为执行服务器端渲染和客户端渲染的 node.js 服务器+SPA。

注意:您可以在文章末尾找到此内容的截屏视频。

概念

我们将把博客文章以 Markdown.md文件的形式存储在仓库中。这样我们就可以将其用作git编辑文章的工作流程。这意味着我们可以创建 Pull 请求来审核文章、git log查看更改历史记录,以及在有多位作者的情况下创建分叉/分支。

由于我们的数据来自静态文件(没有数据库),我们不需要服务器端组件,我们可以使用 Sapper 的静态站点生成器来部署它。

设置

首先使用 搭建应用程序的脚手架degit

你可以使用官方的svelte/sapper-template,但它包含了很多演示代码。我打算用我的 fork joshnuss/sapper-template,它是空白的,没有演示代码。

npx degit joshnuss/sapper-template blog
cd blog
yarn install
Enter fullscreen mode Exit fullscreen mode

帖子数据

每个帖子都将保存在目录中,并在文件顶部posts包含元数据(又称前言)。yaml

帖子看起来是这样posts/example.md的:

---
title: Everything you wanted to know
summary: A short post about ...
date: 2020-04-01
---

- this
- is
- markdown
Enter fullscreen mode Exit fullscreen mode

插件

我们可以在构建时加载这些.md文件fs.readFile(),但还有一种更简单的方法,使用import语句。

rollup为了配置.md导入,我们将使用插件@jackfranklin/rollup-plugin-markdown

这使得以下操作成为可能:

import post1 from 'posts/example1.md'
import post2 from 'posts/example2.md'
// ...
Enter fullscreen mode Exit fullscreen mode

当然,逐一导入每个帖子很快就会变得乏味。😅

如果能使用通配符搜索模式(例如 )一次性导入一堆文件会更方便posts/*.md。这个插件rollup-plugin-glob就是这么做的。🚀

添加 NPM 包:

yarn add -D @jackfranklin/rollup-plugin-markdown rollup-plugin-glob
Enter fullscreen mode Exit fullscreen mode

然后,告诉rollup使用这些插件。更新rollup.config.js

// import plugins
import markdown from '@jackfranklin/rollup-plugin-markdown'
import glob from 'rollup-plugin-glob'

// ....

// remember rollup is creating multiple builds
// make sure to add the new plugins to both the server *and* client builds
export {
  client: {
    plugins: [
      markdown(),
      glob(),
      ...
    ],
    ...
  },

  server: {
    plugins: [
      markdown(),
      glob(),
      ...
    ],
    ...
  }
}
Enter fullscreen mode Exit fullscreen mode

阅读帖子

现在我们可以导入了.md,让我们集中访问里面的帖子的逻辑src/posts.js

import all from '../posts/*.md'

export const posts = all
Enter fullscreen mode Exit fullscreen mode

如果我们console.log(posts),帖子的数据目前如下所示:

[
  {
    metadata: {title: 'the title', summary: '...', date: '2020-01-02'},
    html: '<h1>...</h1>',
    filename: 'example.md'
  }
]
Enter fullscreen mode Exit fullscreen mode

让我们稍微重塑一下它,以便我们的 UI 更容易使用。

我们将做出以下改进:

  • metadatatitle,,summarydate放在顶层。
  • 添加一个permalink字段。它将基于filename
  • date按降序对帖子列表进行排序(最新帖子排在最前面)

进行以下更改src/posts.js

import _ from 'lodash'
import all from '../posts/*.md'

export const posts = _.chain(all) // begin a chain
                      .map(transform) // transform the shape of each post
                      .orderBy('date', 'desc') // sort by date descending
                      .value() // convert chain back to array

// function for reshaping each post
function transform({filename, html, metadata}) {
  // the permalink is the filename with the '.md' ending removed
  const permalink = filename.replace(/\.md$/, '')

  // convert date string into a proper `Date`
  const date = new Date(metadata.date)

  // return the new shape
  return {...metadata, filename, html, permalink, date}
}

// provide a way to find a post by permalink
export function findPost(permalink) {
  // use lodash to find by field name:
  return _.find(posts, {permalink})
}
Enter fullscreen mode Exit fullscreen mode

索引页

现在我们有了帖子,我们可以继续讨论 UI。

打开src/routes/index.svelte并显示<article>每个帖子的标签:

<script>
  // import the list of posts
  import {posts} from '../posts'
</script>

<h1>My Weblog</h1>

<!-- iterate through each post -->
{#each posts as post}
  <article>
    <!-- link article to /posts/$permalink -->   
    <a href={`/posts/${post.permalink}`}>
      <h2>{post.title}</h2>
      <p>{post.summary}</p>
    </a>
  </article>
{/each}
Enter fullscreen mode Exit fullscreen mode

博客详细信息页面

索引页现在显示每个帖子的摘要,要查看整个帖子,请添加一个名为的页面/路线src/routes/posts/[permalink].svelte

注意我们在[permalink]? 周围使用了方括号。这告诉 sapper 它permalink是一个动态参数。Sapper 会将所有参数提供给我们的preload()函数。

<script context="module">
  // import the logic for finding a post based on permalink
  import {findPost} from '../../posts'

  // sapper calls this to load our data
  export function preload(page) {
    // find the post based on the permalink param
    const post = findPost(page.params.permalink)

    // return a list of props
    return { post }
  }
</script>

<script>
  // this prop is filled from the result of the `preload()`
  export let post
</script>

<!-- display the post -->
<h1>{post.title}</h1>

{@html post.html}
Enter fullscreen mode Exit fullscreen mode

部署

要部署我们的网站,我们可以使用 生成静态网站yarn export
您也可以使用zeit以下命令:

yarn export
now
Enter fullscreen mode Exit fullscreen mode

就这样,全部完成了!💃

概括

使用 Sapper 构建静态网站非常容易。
有很多实用的 Rollup 插件可以将静态数据转换为可导入的格式,这意味着在很多情况下我们甚至不需要为数据编写解析器。

这种方法的另一个优点是它的多功能性。同样的概念也适用于项目页面、wiki、新闻网站、书籍、落地页等等。任何你能放在gitrepo 里的数据,都可以成为 Sapper 网站的驱动。

您可以在此处找到示例代码:
https://github.com/joshnuss/sample-blog

祝你编码愉快!✌

附言:这是我即将推出的 Svelte 课程的一部分:http://svelte.video

截屏录像

鏂囩珷鏉ユ簮锛�https://dev.to/joshnuss/create-a-blog-with-markdown-sapper-50ad
PREV
Svelte 编译器:工作原理 编译器的工作原理 解析标签 将所有内容整合在一起 想要更多吗?
NEXT
本网站是开源的