Next.js中的静态站点生成器
nextein是next.js周围的包装器,它允许您使用markdown和react编写静态站点。
nodejs v10.x +运行nextein命令。
如果您想跳入一个入门项目,请检查NextEin-Starter
您必须遵循几个步骤,以使您的网站启动并运行nextein
创建一个项目:
mkdir my-sitecd my-sitenpm init -y安装依赖项
npm i nextein next react react-dom添加next.config.js配置文件
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
} )创建pages/index.js
import React from 'react'
import { getPosts } from 'nextein/fetcher'
import Content from 'nextein/content'
export async function getStaticProps ( ) {
return {
props : {
posts : await getPosts ( )
}
}
}
export default function Index ( { posts } ) {
return (
< section >
{
posts . map ( post => < Content { ... post } /> )
}
</ section >
)
} )在posts Folder( posts/my-first-post.md )下创建一个markdown帖子条目
---
title : First Post
category : post
---
This is the first paragraph and it will be used as an excerpt when loaded in a ` <Content excerpt /> ` tag.
This paragraph should * not * appear in that list.
添加NPM脚本以将开发模式运行到您的package.json
"scripts" : {
"dev" : " next "
}运行开发服务器
npm run dev将另一个NPM脚本添加到您的package.json 。
"scripts" : {
"dev" : " next " ,
"export" : " next build && next export "
}fetcher使用Fetcher从Markdown文件中检索帖子和数据。
Fetcher中的getPostsFilterBy和getDataFilterBy方法允许传递过滤功能。例如,我们可以使用inCategory过滤器在给定类别中检索帖子:
import { getPostsFilterBy } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const blog = await getPostsFilterBy ( InCategory ( 'blog' ) ) getData和getDataFilterBy将仅检索为条目而不是整个帖子生成的元数据。
fetcher方法是定义过滤器,然后在应用过滤器中使用getPosts和getData的便捷方法。
import fetcher from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const { getPosts } = fetcher ( InCategory ( 'blog' ) )
//...
const blog = await getPosts ( )您可以使用Fetcher方法使用动态路由和静态生成器功能(GetStaticProps和Getstatic Pathers)。
[name].js动态路线的示例
import fetcher from 'nextein/fetcher'
const { getData , getPost } = fetcher ( /* filter */ )
export async function getStaticPaths ( ) {
const data = await getData ( )
return {
paths : data . map ( ( { name } ) => ( { params : { name } } ) ) ,
fallback : false
}
}
export async function getStaticProps ( { params } ) {
const post = await getPost ( params )
return { props : { post } }
}
export default function Post ( { post } ) {
//...
} [[...name]].js动态路线:
import fetcher from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
const { getData , getPosts , getPost } = fetcher ( inCategory ( 'guides' ) )
export async function getStaticPaths ( ) {
const data = await getData ( )
return {
paths : [ { params : { name : [ ] } } ,
... data . map ( ( { name } ) => ( { params : { name : [ name ] } } ) )
] ,
fallback : false
}
}
export async function getStaticProps ( { params } ) {
const posts = await getPosts ( )
const post = await getPost ( params ) // This can be null if not matching `...name`
return { props : { posts , post } }
}
export default function Guides ( { posts , post } ) {
//...
}inCategory(category, options)过滤功能将应用于帖子以检索给定类别中的帖子。
category : {String}要过滤结果的类别。options : {Object}可选includeSubCategories: Boolean ture,将帖子包含在子类别中。默认值: false默认情况下,文件夹结构可以解决类别。这意味着,除非您在FrontMatter中指定类别名称,否则位于posts/categoryA/subOne的帖子将具有categoryA/subOne
import { getPosts } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const posts = await getPosts ( )
const homePosts = posts . filter ( inCategory ( 'home' ) )
如果您想检索某个类别下的所有帖子,则假设将包括所有subOne下的所有帖子,请使用categoryA选项” includeSubCategories: true 。
import { inCategory } from 'nextein/filters'
const categoryAPosts = posts
. filter ( inCategory ( 'categoryA' , { includeSubCategories : true } ) )Content渲染post对象的组件。该组件作为属性从帖子中接收content 。使用excerpt属性仅渲染第一段(在呈现帖子列表时,这很有用)。
content : {Object}以HAST格式呈现的标记内容。这是由post.content提供的excerpt : {Boolean}真正仅渲染第一段。选修的。默认值: falserenderers : {Object}一组用于标记元素的自定义渲染器,其形式为[tagName]: renderer 。component : {String|React.Component}用于根节点的组件。 import Content from 'nextein/content'
//...
export default function PostPage ( { post } ) {
return < Content { ... post } />
} 使用renderers更改/样式<p>标签
const Paragraph = ( { children } ) => ( < p style = { { padding : 10 , background : 'silver' } } > { children } </ p > )
// Then in your render method ...
< Content
{ ... post }
renderers = { {
p : Paragraph
} }
/ >post__id是NextEin生成的唯一标识符。data是前材料对象包含邮政元信息(标题,页面,类别等)data.category是帖子的类别。如果未指定,如果帖子在文件夹内,则将使用posts下的目录结构。data.date的日期来自FrontMatter的文件名或文件创建日期的日期或日期content是由构建插件为给定的模拟类型创建的POST内容(通常为HAST格式)的表示。 { data , content } = postnextein使用的前元元数据中只有几个定义的属性
---
category : categoryOne
date : 2017-06-23
---
Post Content...
category :类别名称(可选)date :YYYY-MM-DD格式的日期字符串。用于排序帖子列表。 (选修的)published :设置为false以从条目中删除此帖子。name :仅阅读帖子名称。如果存在,将从名称中删除日期。withNextein包装器配置函数要应用于next.config.js 。它提供了一种添加您自己的next.js配置以及nextein Internal next.js配置的方法。
next.config.js
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
// Your own next.js config here
} ) 您还可以使用withNextein配置来定义NextEin插件:
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
nextein : {
plugins : [
//your nextein plugins here
]
}
// Your own next.js config here
} ) nextein.plugins配置接受以下格式的插件数组:
[name] :只是一个字符串来定义插件。[name, options] :一个字符串来定义插件和插件选项对象。{ name, id, options } :插件对象。需要name字段。所有先前的定义蛋白都转化为这种格式。 id是可选的,当提供时允许多个实例相同的插件。插件name应为预安装的插件( nextein-plugin-markdown )或本地文件( ./myplugins/my-awesome-plugin myplugins/my-waweshy-plugin)
默认配置包括:
plugins: [
[ 'nextein-plugin-source-fs' , { path : 'posts' , data : { page : 'post' } } ] ,
'nextein-plugin-markdown' ,
'nextein-plugin-filter-unpublished'
] 从文件系统读取文件。
选项:
path :从读取文件的路径。data :默认数据将作为每个条目额外传递。默认为{}includes :默认为**/*.* 。ignore :一组忽略的文件。默认列表包括: '**/.DS_Store' ,
'**/.gitignore' ,
'**/.npmignore' ,
'**/.babelrc' ,
'**/node_modules' ,
'**/yarn.lock' ,
'**/package-lock.json' 渲染标记文件。
选项:
raw :默认为true 。使此false以不在邮政对象中添加raw内容。position :默认为false 。使此true添加位置信息以发布内容HAST。rehype :默认为[] 。添加一组插件以进行rehyperemark :默认为[] 。添加一组插件进行remark 通过使用属性来防止显示草稿 /未发表条目的过滤柱。
选项:
field :默认为'published' 。将检查邮data中是否存在field ,并在设置为false中过滤。您可以编写自己的插件。基本上有2种不同类型(源和转换)。源插件将被调用以生成帖子条目,然后转换插件将接收这些条目,并可以在帖子列表中修改,过滤,附加或变换。
请参阅插件和生命系列设计文档。