markdown 转 html 需要先安装三个包:browser-sync,ejs,marked
第一步,先准备一个 ejs 模板:
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title><%= title %></title><link rel="stylesheet" href="index.css">
</head>
<body>
<%- content %>
</body>
</html>
第二步,准备生成 html 的样式文件:
/* Markdown通用样式 *//* 设置全局字体样式 */
body {font-family: Arial, sans-serif;font-size: 16px;line-height: 1.6;color: #333;
}/* 设置标题样式 */
h1,
h2,
h3,
h4,
h5,
h6 {margin-top: 1.3em;margin-bottom: 0.6em;font-weight: bold;
}h1 {font-size: 2.2em;
}h2 {font-size: 1.8em;
}h3 {font-size: 1.6em;
}h4 {font-size: 1.4em;
}h5 {font-size: 1.2em;
}h6 {font-size: 1em;
}/* 设置段落样式 */
p {margin-bottom: 1.3em;
}/* 设置链接样式 */
a {color: #337ab7;text-decoration: none;
}a:hover {text-decoration: underline;
}/* 设置列表样式 */
ul,
ol {margin-top: 0;margin-bottom: 1.3em;padding-left: 2em;
}/* 设置代码块样式 */
pre {background-color: #f7f7f7;padding: 1em;border-radius: 4px;overflow: auto;
}code {font-family: Consolas, Monaco, Courier, monospace;font-size: 0.9em;background-color: #f7f7f7;padding: 0.2em 0.4em;border-radius: 4px;
}/* 设置引用样式 */
blockquote {margin: 0;padding-left: 1em;border-left: 4px solid #ddd;color: #777;
}/* 设置表格样式 */
table {border-collapse: collapse;width: 100%;margin-bottom: 1.3em;
}table th,
table td {padding: 0.5em;border: 1px solid #ccc;
}/* 添加一些额外的样式,如图片居中显示 */
img {display: block;margin: 0 auto;max-width: 100%;height: auto;
}/* 设置代码行号样式 */
pre code .line-numbers {display: inline-block;width: 2em;padding-right: 1em;color: #999;text-align: right;user-select: none;pointer-events: none;border-right: 1px solid #ddd;margin-right: 0.5em;
}/* 设置代码行样式 */
pre code .line {display: block;padding-left: 1.5em;
}/* 设置代码高亮样式 */
pre code .line.highlighted {background-color: #f7f7f7;
}/* 添加一些响应式样式,适应移动设备 */
@media only screen and (max-width: 768px) {body {font-size: 14px;line-height: 1.5;}h1 {font-size: 1.8em;}h2 {font-size: 1.5em;}h3 {font-size: 1.3em;}h4 {font-size: 1.1em;}h5 {font-size: 1em;}h6 {font-size: 0.9em;}table {font-size: 14px;}
}
第三步,准备一个 md 文件:
EventEmitter 像是 Vue2 的event bus,或者Vue3 的 mitt。主要采用了发布订阅模式来处理事件。```js
const EventEmitter = require('events');const event = new EventEmitter()
// 监听(订阅)事件
event.on('test',(data)=>{console.log(data)
})event.emit('test','testtt') // 派发事件
监听的数量默认为10 个。当然我们可以自行修改event.setMaxListeners(20)
。
once 方法只监听一次。off 方法停止监听。
可以发现 process 可支持这些方法,底层就是因调用了 EventEmitter 的原型对象给 process 对象。主要使用 Object.setPrototypeOf(target, source)
。
const EventEmitter = require('events')
ObjectSetPrototypeOf(ObjectGetPrototypeOf(process), EventEmitter.prototype)
第四步,转:
const ejs = require('ejs')
const fs = require('fs')
const marked = require('marked')
const browserSync = require('browser-sync')
let browser;// 起一个服务 支持热更新
const server = () => {browser = browserSync.create()browser.init({server: {baseDir: './',index: 'index.html'}})
}
const init = (callback) => {// 读取 md 的内容const md = fs.readFileSync('README.md', 'utf8')// 读取文件并填充内容ejs.renderFile('template.ejs', {content: marked.parse(md),title: "markdown to html"}, (err, data) => {if (err) throw errfs.writeFileSync('index.html', data)callback && callback()})
}
//监听文件变化
fs.watchFile('README.md', (curr, prev) => {if (curr.mtime !== prev.mtime) {init(() => {browser.reload()})}
})
init(() => {server()
})
browser-sync 的主要作用是使支持热更新,实时预览,自动刷新
marked 主要用于 md 转 html
ejs JavaScript 的模板引擎,支持在 html 动态嵌入内容
此外,当我们同时多端打开该 html 文件时,多端都会同步运行(同步预览滑动拖拽)。