当前位置:网站首页>Next. JS hot update markdown file change
Next. JS hot update markdown file change
2022-06-25 17:09:00 【qq_ forty-three million four hundred and seventy-nine thousand 】
High quality resource sharing
| Learning route guidance ( Click unlock ) | Knowledge orientation | Crowd positioning |
|---|---|---|
| 🧡 Python Actual wechat ordering applet 🧡 | Progressive class | This course is python flask+ Perfect combination of wechat applet , From the deployment of Tencent to the launch of the project , Create a full stack ordering system . |
| Python Quantitative trading practice | beginner | Take you hand in hand to create an easy to expand 、 More secure 、 More efficient quantitative trading system |
Next.js Provides Fast-Refresh Ability , It can help you to React The edits made by the component provide immediate feedback .
however , When you pass Markdown File provides website content , because Markdown No React Components , Hot update will fail .
How do you do it?
This problem can be solved from the following aspects :
- How the server monitors file updates
- How the server notifies the browser
- How the browser updates the page
- How to get the latest Markdown Content
- How to communicate with Next.js Start up with the development server
Monitoring file updates
Appointment : markdown The documents are stored in Next.js In the root directory of the project
_contents/in
adopt node:fs.watch Module recursive monitoring _contents Catalog , When the document changes , Trigger listener perform .
New file scripts/watch.js monitor _contents Catalog .
const { watch } = require('node:fs');
function main(){
watch(process.cwd() + '/\_contents', { recursive: true }, (eventType, filename) => {
console.log(eventType, filename)
});
}
Notification browser
Server through WebSocket Connect to the browser , When the development server finds that the file changes , adopt WS Notify the browser to update the page .
The browser needs to know whether the updated file is related to the route of the current page , therefore , The message sent by the server to the browser should at least contain the current
Update the page route corresponding to the file .
WebSocket
ws It's easy to use 、 Extremely fast and fully tested WebSocket Client and server implementation . adopt ws start-up WebSocket The server .
const { watch } = require('node:fs');
const { WebSocketServer } = require('ws')
function main() {
const wss = new WebSocketServer({ port: 80 })
wss.on('connection', (ws, req) => {
watch(process.cwd() + '/\_contents', { recursive: true }, (eventType, filename) => {
const path = filename.replace(/\.md/, '/')
ws.send(JSON.stringify({ event: 'markdown-changed', path }))
})
})
}
The browser connects to the server
Create a new one HotLoad Components , Be responsible for listening for messages from the server , And hot page updates . The components meet the following requirements :
- Maintain a singleton pattern with WebSocekt Server The connection of
- After listening to the server message , Determine whether the current page route is related to the changed file , Ignore if irrelevant
- Server side messages may be sent intensively , You need to do anti shake processing when loading new version content
- load Markdown File and complete the update
- This component is only available in
Development modeWork under the
import { useRouter } from "next/router"
import { useEffect } from "react"
interface Instance {
ws: WebSocket
timer: any
}
let instance: Instance = {
ws: null as any,
timer: null as any
}
function getInstance() {
if (instance.ws === null) {
instance.ws = new WebSocket('ws://localhost')
}
return instance
}
function \_HotLoad({ setPost, params }: any) {
const { asPath } = useRouter()
useEffect(() => {
const instance = getInstance()
instance.ws.onmessage = async (res: any) => {
const data = JSON.parse(res.data)
if (data.event === 'markdown-changed') {
if (data.path === asPath) {
const post = await getPreviewData(params)
setPost(post)
}
}
}
return () => {
instance.ws.CONNECTING && instance.ws.close(4001, asPath)
}
}, [])
return null
}
export function getPreviewData(params: {id:string[]}) {
if (instance.timer) {
clearTimeout(instance.timer)
}
return new Promise((resolve) => {
instance.timer = setTimeout(async () => {
const res = await fetch('http://localhost:3000/api/preview/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
})
resolve(res.json())
}, 200)
})
}
let core = ({ setPost, params }: any)=>null
if(process.env.NODE\_ENV === 'development'){
console.log('development hot load');
core = _HotLoad
}
export const HotLoad = core
Data preview API
Create data preview API, Read Markdown The contents of the document , And compile it into the format used for page rendering . The results here
Should and [...id].tsx On the page getStaticProps() Method returns a page with exactly the same data structure , relevant
Logic can be reused directly .
newly build API file pages/api/preview.ts,
import type { NextApiRequest, NextApiResponse } from 'next'
import { getPostData } from '../../lib/posts'
type Data = {
name: string
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (process.env.NODE\_ENV === 'development') {
const params = req.body
const post = await getPostData(['posts', ...params.id])
return res.status(200).json(post)
} else {
return res.status(200)
}
}
Update page
page pages/[...id].tsx Introduction in HotLoad Components , And transmission setPostData() And params to HotLoad Components .
...
import { HotLoad } from '../../components/hot-load'
const Post = ({ params, post, prev, next }: Params) => {
const [postData, setPostData] = useState(post)
useEffect(()=>{
setPostData(post)
},[post])
return (
<Layout>
<Head>
<title>{postData.title} - Gauliangtitle>
Head>
<PostContent post={postData} prev={prev} next={next} />
<BackToTop />
<HotLoad setPost={setPostData} params={params} />
Layout>
)
}
export async function getStaticProps({ params }: Params) {
return {
props: {
params,
post:await getPostData(['posts', ...params.id])
}
}
}
export async function getStaticPaths() {
const paths = getAllPostIdByType()
return {
paths,
fallback: false
}
}
export default Post
The startup script
to update package.json Of dev Script :
"scripts": {
"dev": "node scripts/watch.js & \n next dev"
},
summary
Above , Overall overview of the general implementation logic . When the specific project is implemented , There are some details to consider ,
Such as : When updating a file, you want to prompt for a different file name on the command line 、 Adjust the matching logic between file and route according to personalized route information .
Next.js Original blog version :https://gauliang.github.io/blogs/2022/watch-markdown-files-and-hot-load-the-nextjs-page/
边栏推荐
猜你喜欢

【无标题】
![[Jianzhi offer II 091. painting the house]](/img/63/dc54c411b1a2f2b1d69b62edafde38.png)
[Jianzhi offer II 091. painting the house]

Xshell connecting VMware virtual machines

What are the steps for launching the mobile ERP system? It's important to keep it tight

FreeRTOS内核时钟不对的问题解决

这些老系统代码,是猪写的么?

剑指 Offer 39. 数组中出现次数超过一半的数字

2022-06-17 advanced network engineering (x) is-is-general header, establishment of adjacency relationship, IIH message, DIS and pseudo node

How smart PLC constructs ALT instruction

【黑苹果】联想拯救者Y70002019PG0
随机推荐
知道这些面试技巧,让你的测试求职少走弯路
STM32 hardware error hardfault_ Handler processing method
足下教育日精进自动提交
3. conditional probability and independence
PLSQL storage function SQL programming
【微服务|Sentinel】流控规则概述|针对来源|流控模式详解<直接 关联 链路>
App测试工具大全,收藏这篇就够了
2022云的世界会更好吗
2022-06-17 advanced network engineering (IX) is-is- principle, NSAP, net, area division, network type, and overhead value
剑指 Offer II 025. 链表中的两数相加
Kalman filter meets deep learning: papers on Kalman filter and deep learning
[untitled]
Knowing these interview skills will help you avoid detours in your test job search
JVM memory structure
Good fat man takes you to learn Flink series -flink source code analysis episode I standalone startup script analysis
【精通高并发】深入理解汇编语言基础
心情
mysql使用过程中遇到的问题
1-8file sharing in VMWare
Optimization of lazyagg query rewriting in parsing data warehouse