เครื่องกำเนิดไซต์คงที่อยู่ใน next.js
nextein เป็น wrapper รอบถัดไป 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 >
)
} ) สร้างรายการโพสต์ markdown ภายใต้โฟลเดอร์ posts ( posts/my-first-post.md )
---
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 เพื่อเรียกใช้โหมด dev ไปยัง package.json ของคุณ
"scripts" : {
"dev" : " next "
}เรียกใช้เซิร์ฟเวอร์การพัฒนา
npm run dev เพิ่มสคริปต์ NPM อื่นลงใน package.json ของคุณเพื่อส่งออกไซต์
"scripts" : {
"dev" : " next " ,
"export" : " next build && next export "
}fetcherใช้ Fetcher เพื่อดึงโพสต์และข้อมูลจากไฟล์ Markdown ของคุณ
วิธี getPostsFilterBy และ getDataFilterBy ใน fetcher ช่วยให้สามารถส่งฟังก์ชั่นตัวกรอง ตัวอย่างเช่นเราสามารถใช้ตัวกรอง 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 ( )คุณสามารถใช้เส้นทางไดนามิกและ ฟังก์ชั่นเครื่องกำเนิดไฟฟ้าแบบคงที่ (getstaticprops และ getstaticpaths) ด้วยวิธีการดึงข้อมูล
ตัวอย่างสำหรับ [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 Dynamic Route:
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 จริงเพื่อรวมโพสต์ในหมวดย่อย ค่าเริ่มต้น: false หมวดหมู่ได้รับการแก้ไขโดยโครงสร้างโฟลเดอร์โดยค่าเริ่มต้น ซึ่งหมายความว่าโพสต์ที่อยู่ที่ posts/categoryA/subOne จะมีหมวดหมู่ categoryA/subOne เว้นแต่คุณจะระบุชื่อหมวดหมู่ใน Frontmatter
import { getPosts } from 'nextein/fetcher'
import { inCategory } from 'nextein/filters'
//...
const posts = await getPosts ( )
const homePosts = posts . filter ( inCategory ( 'home' ) )
หากคุณต้องการดึงโพสต์ทั้งหมดภายใต้หมวดหมู่บางประเภทสมมติว่า categoryA ซึ่งจะรวมถึงทั้งหมดที่อยู่ภายใต้ subOne ให้ใช้ตัวเลือก includeSubCategories: true
import { inCategory } from 'nextein/filters'
const categoryAPosts = posts
. filter ( inCategory ( 'categoryA' , { includeSubCategories : true } ) )Content องค์ประกอบในการแสดงผล post ส่วนประกอบนี้ได้รับ content จากโพสต์เป็นคุณสมบัติ ใช้คุณสมบัติ excerpt เพื่อแสดงวรรคแรกเท่านั้น (สิ่งนี้มีประโยชน์เมื่อแสดงรายการโพสต์)
content : {Object} MARKDOWN เนื้อหาในรูปแบบ HAST ที่จะแสดงผล สิ่งนี้จัดทำโดย post.contentexcerpt : {Boolean} จริงที่จะแสดงวรรคแรกเท่านั้น ไม่จำเป็น. ค่าเริ่มต้น: falserenderers : {Object} ชุดของ renderers ที่กำหนดเองสำหรับองค์ประกอบ markdown ด้วยรูปแบบของ [tagName]: renderercomponent : {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 เป็นตัวระบุที่ไม่ซ้ำกันที่สร้างโดย Nexteindata คือวัตถุ frontmatter มีข้อมูลโพสต์เมตา (ชื่อเรื่องหน้าหมวดหมู่ ฯลฯ )data.category เป็นหมวดหมู่ของโพสต์ เมื่อไม่ได้ระบุไว้หากโพสต์อยู่ในโฟลเดอร์โครงสร้างไดเรกทอรีภายใต้ posts จะถูกใช้data.date : วันที่ JSON จากวันที่หรือวันที่ของ Frontmatter ในชื่อไฟล์หรือวันที่สร้างไฟล์content เป็นตัวแทนของเนื้อหาโพสต์ (โดยทั่วไปในรูปแบบ HAST) ที่สร้างขึ้นโดย Build Plugin สำหรับ mimetype ที่กำหนด { data , content } = post มีคุณสมบัติที่กำหนดไว้เพียงไม่กี่อย่างในเมตาดาต้า frontmatter ที่ใช้โดย nextein
---
category : categoryOne
date : 2017-06-23
---
Post Content...
category : ชื่อหมวดหมู่ (ไม่บังคับ)date : วันที่สตริงในรูปแบบ yyyy-mm-dd ใช้ในการเรียงลำดับรายการโพสต์ (ไม่จำเป็น)published : ตั้งค่าเป็น false เพื่อลบโพสต์นี้ออกจากรายการname : อ่านเฉพาะ ชื่อไฟล์โพสต์ วันที่จะถูกลบออกจากชื่อหากมีอยู่withNextein ฟังก์ชั่นการกำหนดค่า wrapper ที่จะนำไปใช้กับ next.config.js มันมีวิธีเพิ่มการกำหนดค่า next.js ของคุณเองพร้อมกับ nextein ภายใน next.js config
next.config.js
const { withNextein } = require ( 'nextein/config' )
module . exports = withNextein ( {
// Your own next.js config here
} ) นอกจากนี้คุณยังสามารถกำหนดปลั๊กอิน Nextein โดยใช้การกำหนดค่า withNextein :
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 definitoins ก่อนหน้าทั้งหมดทั้งหมดจะถูกเปลี่ยนเป็นรูปแบบนี้ id เป็นตัวเลือกเมื่อมีให้อนุญาตหลายอินสแตนซ์ของปลั๊กอินเดียวกัน name ปลั๊กอินควรเป็นปลั๊กอินที่ติดตั้งไว้ล่วงหน้า ( nextein-plugin-markdown ) หรือไฟล์ท้องถิ่น ( ./myplugins/my-awesome-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' แสดงไฟล์ Markdown
ตัวเลือก:
raw : ค่าเริ่มต้นเป็น true ทำให้ false นี้ไม่เพิ่มเนื้อหา raw ในวัตถุโพสต์position : ค่าเริ่มต้นเป็น false ทำให้สิ่งนี้ true เพื่อเพิ่มข้อมูลตำแหน่งลงในโพสต์เนื้อหาrehype : ค่าเริ่มต้นเป็น [] เพิ่มชุดปลั๊กอินสำหรับ rehyperemark : ค่าเริ่มต้นเป็น [] เพิ่มชุดปลั๊กอินสำหรับ remark ตัวกรองโพสต์โดยใช้คุณสมบัติเพื่อป้องกันไม่ให้ร่าง / รายการที่ไม่ได้เผยแพร่จะแสดง
ตัวเลือก:
field : ค่าเริ่มต้นเป็น 'published' จะตรวจสอบว่า field มีอยู่ใน data โพสต์และตัวกรองหากตั้งค่าเป็น falseคุณสามารถเขียนปลั๊กอินของคุณเอง มี 2 ประเภทที่แตกต่างกัน (แหล่งที่มาและการแปลง) ปลั๊กอินต้นทางจะถูกเรียกให้สร้างรายการโพสต์จากนั้นปลั๊กอินการแปลงจะได้รับรายการเหล่านั้นและสามารถแก้ไขกรองผนวกหรือแปลงในรายการโพสต์
ดูเอกสารการออกแบบปลั๊กอินและ Lifecyle