-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathbuild_post_index.js
113 lines (105 loc) · 3.18 KB
/
build_post_index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const mdx = require('@mdx-js/mdx')
const babel = require("@babel/core")
const fs = require('fs')
const path = require('path')
const RSS = require('rss')
function requireFromStringSync(src, filename) {
const Module = module.constructor;
const m = new Module();
m._compile(src, filename);
return m.exports;
}
function requireMDXSync(mdxSrc, filename) {
const jsx = mdx.sync(mdxSrc)
const babelOptions = babel.loadOptions({
babelrc: false,
presets: [
'@babel/preset-react',
// ^^^ mitigates error:
// SyntaxError: unknown: Unexpected token (6:33)
// > 6 | export default ({components}) => <MDXTag name="wrapper">{`
// | ^
],
plugins: [
"@babel/plugin-transform-modules-commonjs",
// ^^^ mitigages error:
// hello.mdx:1
// (function (exports, require, module, __filename, __dirname) { export const meta = {
// ^^^^^^
// SyntaxError: Unexpected token export
]
})
const transformed = babel.transformSync(jsx, babelOptions)
return requireFromStringSync(transformed.code, filename)
}
function requireMDXFileSync(path) {
const mdxSrc = fs.readFileSync(path, { encoding: 'utf-8' })
return requireMDXSync(mdxSrc, path)
}
function scanDir(dirPath, extension) {
const mdxFiles = []
const scan = (dirPath) => {
const filenames = fs.readdirSync(dirPath)
filenames.sort()
filenames.map(filename => {
const filePath = path.join(dirPath, filename)
const st = fs.statSync(filePath)
if (st.isFile() && filePath.endsWith(extension)) {
mdxFiles.push(filePath)
}
if (st.isDirectory()) {
scan(filePath)
}
})
}
scan(dirPath)
return mdxFiles
}
function readPostMetadata(postPath) {
const mod = requireMDXFileSync(postPath)
const { meta } = mod
return {
filePath: postPath,
urlPath: postPath.replace(/\\/, '/').replace(/^pages/, '').replace(/\.mdx?$/, ''),
title: meta.title || path.basename(postPath),
publishDate: new Date(meta.publishDate),
}
}
function generateRSS(posts) {
const siteUrl = 'https://nextjs-mdx-blog-example.now.sh'
const feed = new RSS({
title: 'My blog',
site_url: siteUrl,
})
posts.map(post => {
feed.item({
title: post.title,
guid: post.urlPath,
url: siteUrl + post.urlPath,
date: post.publishDate,
})
})
return feed.xml({ indent: true })
}
function main() {
const postPaths = scanDir('pages', '.mdx')
//console.debug({ postPaths })
const now = new Date()
const posts = postPaths
.map(readPostMetadata)
.filter(post => post.publishDate <= now)
posts.sort((a, b) => b.publishDate - a.publishDate)
//console.debug({ posts })
const postsJSON = JSON.stringify(posts, null, 2)
const exportPath = 'posts.js'
fs.writeFileSync(exportPath,
'// automatically generated by build_post_index.js\n' +
`export default ${postsJSON}\n`
)
console.info(`Saved ${posts.length} posts in ${exportPath}`)
const rssPath = 'static/rss-feed.xml'
const rssXML = generateRSS(posts)
fs.writeFileSync(rssPath, rssXML)
console.info(`Saved RSS feed to ${rssPath}`)
}
main()