共计 2766 个字符,预计需要花费 7 分钟才能阅读完成。
发现自己良久没有写博客了。之前在 github 开了一个仓库,在仓库的 issue 区写一些内容。issue 区体验挺好的,能够 refer 上我的项目代码,也能够追加评论。但我想本人写一个博客,不须要很多花里胡哨的性能,只对内容专一,极大的益处是,能够得心应手的编写本人喜爱的页面款式。刚好最近有接触了下 svelte,就顺带的用 sapper 写一个动态页面。
实现须要用到的知识点 / 技术:
- svelte
- sapper
- tailwindcss
- typescript
前面两点非必须,能够依据本人须要进行增减。
思路
整体的思路比较简单。
sapper 反对 export 出动态文件,我只须要将动态文件部署到一个动态站点,首选的就是 github pages。sapper 导出 export 有一个益处:
Static doesn’t mean non-interactive — your Svelte components work exactly as they do normally, and you still get all the benefits of client-side routing and prefetching.
sapper 默认的 template 就是一个 blog,这不是刚好能够拿来起手嘛!但默认的 template 的 blog 内容是固定的数据,大抵内容是一个 js 文件,export 一个 blog 的 array。
export const [
{
title: '2020-06/build-blog.md',
slug: '2020-06_build-blog', // 生成的路由门路
html: '<h1 id=\" 用 sapper 构建一个博客 \"> 用 sapper 构建一个博客 </h1>'
}
]
在 sapper export 之后,能够在 __sapper__/export/blog
看到生成 html 动态文件。也就意味着最初须要部署到 github pages 的目录,就是 __sapper__
目录啦。
可如果要写博客,那必定也优先选择 Markdown。
所以须要解决的也就是将 Markdown 文件转为下面提到的 js 文件。
将 Markdown 转为 js 文件
须要用到 Markedjs。
应用也是简略粗犷:
const marked = require('marked')
marked.setOptions({renderer: new marked.Renderer(),
highlight: function(code, language) {const hljs = require('highlight.js')
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext'
return hljs.highlight(validLanguage, code).value
},
// ...(more options)
});
marked(markdownString)
例如 markdownString 为:
*hello world*
将会被转为:
<p><em>hello world</em></p>
晓得用法之后,只须要通过 fs 文件操作,将指标的 Markdown 文件全副 push 进一个数组,最初将数组写入一个 js 文件。
读取 Markdown 并写入文件
node 对操作文件提供了 readir
、readFile
、writeFile
等函数。
其中外围的解决逻辑如下:
// 获取所有文件
const getAllFiles = function (dirPath, arrayOfFiles) {files = fs.readdirSync(dirPath)
arrayOfFiles = arrayOfFiles || []
files.forEach(function (file) {if (fs.statSync(dirPath + "/" + file).isDirectory()) {arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles)
} else {arrayOfFiles.push(path.join(dirPath, "/", file))
}
})
return arrayOfFiles
}
// 将 markdown 转为 js 文件
const compile = () => {
try {const dirs = getAllFiles('./') // 读取所有文件
const inPosts = [] // 文章数组
for (let fileName of dirs) {if (/.md/.test(fileName)) {const fileData = fs.readFileSync(`./${fileName}`, 'utf-8') // markdown 内容
const fmData = fm(fileData) // 此处能够疏忽 fm(fm 是解决 markdown front matter 的,可有可无)const rmSuffix = fileName.split('.')[0] // 移除文件名后缀
inPosts.push({
title: fileName,
path: rmSuffix,
slug: rmSuffix.replace('/', '_'),
html: marked(fmData.body),
fmData
})
}
}
inPosts.forEach(post => {post.html = post.html.replace(/^\t{3}/gm, '');
});
const outPutContent = `export default ${JSON.stringify(inPosts)}`
fs.writeFile('../routes/blog/_posts.js', outPutContent, err => {if (err) return console.log('生成 post 失败', err)
console.log('已生成_posts.js')
})
} catch (error) {console.error('error', error)
}
}
const watcher = chokidar.watch('./')
watcher
.on('all', () => {compile()
})
部署到 github pages
对于 sapper,执行 export 命令生成动态文件。
npm run export
将 __sapper__/export
推送到仓库的 gh-pages 分支。
git subtree push --prefix __sapper__/export origin gh-pages
最初在仓库设置出将 gh-pages 分支设置为部署分支就好了。
以上实现了从写 Markdown 到能够看到文章,后续页面的编写就能够得心应手啦!
后果
源码 https://github.com/GzhiYi/sap…
部署 Demo https://gzhiyi.top