使用 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
帖子数据
每个帖子都将保存在目录中,并在文件顶部posts
包含元数据(又称前言)。yaml
帖子看起来是这样posts/example.md
的:
---
title: Everything you wanted to know
summary: A short post about ...
date: 2020-04-01
---
- this
- is
- markdown
插件
我们可以在构建时加载这些.md
文件fs.readFile()
,但还有一种更简单的方法,使用import
语句。
rollup
为了配置.md
导入,我们将使用插件@jackfranklin/rollup-plugin-markdown
。
这使得以下操作成为可能:
import post1 from 'posts/example1.md'
import post2 from 'posts/example2.md'
// ...
当然,逐一导入每个帖子很快就会变得乏味。😅
如果能使用通配符搜索模式(例如 )一次性导入一堆文件会更方便posts/*.md
。这个插件rollup-plugin-glob
就是这么做的。🚀
添加 NPM 包:
yarn add -D @jackfranklin/rollup-plugin-markdown rollup-plugin-glob
然后,告诉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(),
...
],
...
}
}
阅读帖子
现在我们可以导入了.md
,让我们集中访问里面的帖子的逻辑src/posts.js
:
import all from '../posts/*.md'
export const posts = all
如果我们console.log(posts)
,帖子的数据目前如下所示:
[
{
metadata: {title: 'the title', summary: '...', date: '2020-01-02'},
html: '<h1>...</h1>',
filename: 'example.md'
}
]
让我们稍微重塑一下它,以便我们的 UI 更容易使用。
我们将做出以下改进:
- 将
metadata
(title
,,summary
)date
放在顶层。 - 添加一个
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})
}
索引页
现在我们有了帖子,我们可以继续讨论 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}
博客详细信息页面
索引页现在显示每个帖子的摘要,要查看整个帖子,请添加一个名为的页面/路线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}
部署
要部署我们的网站,我们可以使用 生成静态网站yarn export
。
您也可以使用zeit
以下命令:
yarn export
now
就这样,全部完成了!💃
概括
使用 Sapper 构建静态网站非常容易。
有很多实用的 Rollup 插件可以将静态数据转换为可导入的格式,这意味着在很多情况下我们甚至不需要为数据编写解析器。
这种方法的另一个优点是它的多功能性。同样的概念也适用于项目页面、wiki、新闻网站、书籍、落地页等等。任何你能放在git
repo 里的数据,都可以成为 Sapper 网站的驱动。
您可以在此处找到示例代码:
https://github.com/joshnuss/sample-blog
祝你编码愉快!✌
附言:这是我即将推出的 Svelte 课程的一部分:http://svelte.video