host-mdx 2.1.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -29
- package/index.js +29 -19
- package/mdx-to-html.js +9 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# host-mdx
|
|
2
|
-
[](https://www.npmjs.com/package/host-mdx)
|
|
3
|
-
A cli tool to create and serve a static html website from a given mdx directory
|
|
4
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/host-mdx)\
|
|
4
|
+
A cli tool to create and serve a static html website from a given mdx directory
|
|
5
5
|
|
|
6
6
|
## 🛠️ Usage
|
|
7
|
+
|
|
7
8
|
```
|
|
8
9
|
host-mdx [options]
|
|
9
10
|
|
|
@@ -16,35 +17,48 @@ Options:
|
|
|
16
17
|
--track-changes, -t Tracks any changes made & auto reloads
|
|
17
18
|
--verobse, -v Shows additional log messages
|
|
18
19
|
```
|
|
19
|
-
|
|
20
|
-
> If `--input-path` is not provided it will default to `./` i.e. current working directory
|
|
21
|
-
> If `--output-path` is not provided a temp folder will be created automatically & deleted upon exit
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
> If `--input-path` is not provided it will default to `./` i.e. current working directory\
|
|
22
|
+
> If `--output-path` is not provided a temp folder will be created automatically & deleted upon exit
|
|
25
23
|
|
|
24
|
+
You can add a file by the name `.hostmdxignore` at the root of your project to filter out which files/folders to skip while generating html
|
|
25
|
+
(similar to [.gitignore](https://git-scm.com/docs/gitignore))
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
You can also add a file by the name `host-mdx.js` at the root of your input folder as a config file with access to the following:
|
|
28
28
|
|
|
29
29
|
```js
|
|
30
|
+
onHostStart(port)
|
|
31
|
+
onHostEnd(port)
|
|
32
|
+
toTriggerRecreate(event, path)
|
|
30
33
|
onSiteCreateStart(inputPath, outputPath)
|
|
31
34
|
onSiteCreateEnd(inputPath, outputPath, wasInterrupted)
|
|
32
|
-
onFileCreateStart(
|
|
33
|
-
onFileCreateEnd(
|
|
35
|
+
onFileCreateStart(inputPath, outputPath, inFilePath, outFilePath)
|
|
36
|
+
onFileCreateEnd(inputPath, outputPath, inFilePath, outFilePath, result)
|
|
37
|
+
modMDXCode(inputPath, outputPath, inFilePath, outFilePath, code)
|
|
38
|
+
modGlobalArgs(inputPath, outputPath, globalArgs)
|
|
34
39
|
modBundleMDXSettings(inputPath, outputPath, settings)
|
|
35
|
-
toTriggerRecreate(event, path)
|
|
36
40
|
```
|
|
37
41
|
|
|
38
42
|
> **Note:** Any changes made to `host-mdx.js` or any new package added requires complete restart otherwise changes will not reflect due to [this bug](https://github.com/nodejs/node/issues/49442)
|
|
39
43
|
|
|
44
|
+
Default global variables you can use inside any .mdx files:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
hostmdxCwd
|
|
48
|
+
hostmdxInputPath
|
|
49
|
+
hostmdxOutputPath
|
|
50
|
+
```
|
|
40
51
|
|
|
41
52
|
## 📖 Example
|
|
53
|
+
|
|
42
54
|
Command:
|
|
55
|
+
|
|
43
56
|
```bash
|
|
44
57
|
npx host-mdx --input-path="path/to/my-website-template" --output-path="path/to/my-website" --port=3113 -t
|
|
45
58
|
```
|
|
46
59
|
|
|
47
60
|
Input Directory:
|
|
61
|
+
|
|
48
62
|
```
|
|
49
63
|
my-website-template/
|
|
50
64
|
├─ index.mdx
|
|
@@ -68,6 +82,7 @@ my-website-template/
|
|
|
68
82
|
```
|
|
69
83
|
|
|
70
84
|
`.hostmdxignore` file content:
|
|
85
|
+
|
|
71
86
|
```sh
|
|
72
87
|
*.jsx
|
|
73
88
|
blog/page2/
|
|
@@ -76,40 +91,50 @@ static/temp.jpg
|
|
|
76
91
|
```
|
|
77
92
|
|
|
78
93
|
`host-mdx.js` file content:
|
|
94
|
+
|
|
79
95
|
```js
|
|
80
|
-
export function
|
|
96
|
+
export async function onHostStart(port) {
|
|
97
|
+
console.log("onHostStart", port)
|
|
98
|
+
}
|
|
99
|
+
export async function onHostEnd(port) {
|
|
100
|
+
console.log("onHostEnd", port)
|
|
101
|
+
}
|
|
102
|
+
export async function toTriggerRecreate(event, path) {
|
|
103
|
+
const isGOutputStream = /\.goutputstream-\w+$/.test(path);
|
|
104
|
+
if (isGOutputStream) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
export async function onSiteCreateStart(inputPath, outputPath) {
|
|
81
111
|
console.log("onSiteCreateStart", inputPath, outputPath)
|
|
82
112
|
}
|
|
83
|
-
export function onSiteCreateEnd(inputPath, outputPath, wasSuccessful) {
|
|
113
|
+
export async function onSiteCreateEnd(inputPath, outputPath, wasSuccessful) {
|
|
84
114
|
console.log("onSiteCreateEnd", inputPath, outputPath, wasSuccessful)
|
|
85
115
|
}
|
|
86
|
-
export function onFileCreateStart(inputFilePath, outputFilePath) {
|
|
116
|
+
export async function onFileCreateStart(inputFilePath, outputFilePath) {
|
|
87
117
|
console.log("onFileCreateStart", inputFilePath, outputFilePath)
|
|
88
118
|
}
|
|
89
|
-
export function onFileCreateEnd(inputFilePath, outputFilePath) {
|
|
119
|
+
export async function onFileCreateEnd(inputFilePath, outputFilePath) {
|
|
90
120
|
console.log("onFileCreateEnd", inputFilePath, outputFilePath)
|
|
91
121
|
}
|
|
92
|
-
export function
|
|
93
|
-
|
|
122
|
+
export async function modMDXCode(inputPath, outputPath, inFilePath, outFilePath, code){
|
|
123
|
+
// Modify code ...
|
|
124
|
+
return code;
|
|
94
125
|
}
|
|
95
|
-
export function
|
|
96
|
-
|
|
126
|
+
export async function modGlobalArgs(inputPath, outputPath, globalArgs){
|
|
127
|
+
// Modify globalArgs ...
|
|
128
|
+
return globalArgs;
|
|
97
129
|
}
|
|
98
|
-
export function modBundleMDXSettings(inputPath, outputPath, settings) {
|
|
130
|
+
export async function modBundleMDXSettings(inputPath, outputPath, settings) {
|
|
99
131
|
// Modify settings ...
|
|
100
132
|
return settings
|
|
101
133
|
}
|
|
102
|
-
export function toTriggerRecreate(event, path) {
|
|
103
|
-
const isGOutputStream = /\.goutputstream-\w+$/.test(path);
|
|
104
|
-
if (isGOutputStream) {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return true;
|
|
109
|
-
}
|
|
110
134
|
```
|
|
111
135
|
|
|
112
136
|
Output Directory:
|
|
137
|
+
|
|
113
138
|
```
|
|
114
139
|
my-website/
|
|
115
140
|
├─ index.html
|
|
@@ -127,6 +152,6 @@ my-website/
|
|
|
127
152
|
|
|
128
153
|
The site will now be visible in the browser at `localhost:3113`
|
|
129
154
|
|
|
130
|
-
|
|
131
155
|
## 🔑 License
|
|
156
|
+
|
|
132
157
|
MIT © [Manas Ravindra Makde](https://manasmakde.github.io/)
|
package/index.js
CHANGED
|
@@ -141,7 +141,7 @@ async function createSite(inputPath, outputPath) {
|
|
|
141
141
|
|
|
142
142
|
// Broadcast site creation started
|
|
143
143
|
log("Creating site...")
|
|
144
|
-
configs?.onSiteCreateStart?.(inputPath, outputPath)
|
|
144
|
+
await configs?.onSiteCreateStart?.(inputPath, outputPath)
|
|
145
145
|
|
|
146
146
|
|
|
147
147
|
// Remove html folder if it already exists
|
|
@@ -182,9 +182,9 @@ async function createSite(inputPath, outputPath) {
|
|
|
182
182
|
// Make dir
|
|
183
183
|
if (isDir) {
|
|
184
184
|
log(`${currentPath} ---> ${absToOutput}`, true)
|
|
185
|
-
configs?.onFileCreateStart?.(currentPath, absToOutput)
|
|
185
|
+
await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absToOutput)
|
|
186
186
|
fs.mkdirSync(absToOutput, { recursive: true });
|
|
187
|
-
configs?.onFileCreateEnd?.(currentPath, absToOutput)
|
|
187
|
+
await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absToOutput, undefined)
|
|
188
188
|
}
|
|
189
189
|
// Make html file from mdx
|
|
190
190
|
else if (!isDir && isMdx) {
|
|
@@ -192,30 +192,39 @@ async function createSite(inputPath, outputPath) {
|
|
|
192
192
|
// Broadcast file creation started
|
|
193
193
|
let absHtmlPath = path.format({ ...path.parse(absToOutput), base: '', ext: '.html' })
|
|
194
194
|
log(`${currentPath} ---> ${absHtmlPath}`, true)
|
|
195
|
-
configs?.onFileCreateStart?.(currentPath, absHtmlPath)
|
|
195
|
+
await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absHtmlPath)
|
|
196
196
|
|
|
197
197
|
|
|
198
|
-
//
|
|
198
|
+
// Intercept mdx code
|
|
199
199
|
let mdxCode = fs.readFileSync(currentPath, 'utf8');
|
|
200
|
-
|
|
200
|
+
if (typeof configs?.modMDXCode === 'function') {
|
|
201
|
+
log(`Modifying mdx code of ${currentPath}`, true);
|
|
202
|
+
mdxCode = await configs?.modMDXCode(inputPath, outputPath, currentPath, absHtmlPath, mdxCode);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
// convert mdx code into html & paste into file
|
|
207
|
+
let parentDir = path.dirname(currentPath);
|
|
201
208
|
let globalArgs = {
|
|
202
209
|
hostmdxCwd: parentDir,
|
|
203
210
|
hostmdxInputPath: inputPath,
|
|
204
211
|
hostmdxOutputPath: outputPath
|
|
205
212
|
};
|
|
206
|
-
|
|
207
|
-
|
|
213
|
+
globalArgs = await configs?.modGlobalArgs?.(inputPath, outputPath, globalArgs) ?? globalArgs;
|
|
214
|
+
let result = await mdxToHtml(mdxCode, parentDir, globalArgs, async (settings) => { return await configs?.modBundleMDXSettings?.(inputPath, outputPath, settings) ?? settings });
|
|
215
|
+
let htmlCode = result.html;
|
|
216
|
+
createFile(absHtmlPath, `<!DOCTYPE html>${htmlCode}`);
|
|
208
217
|
|
|
209
218
|
|
|
210
219
|
// Broadcast file creation ended
|
|
211
|
-
configs?.onFileCreateEnd?.(currentPath, absHtmlPath)
|
|
220
|
+
await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absHtmlPath, result)
|
|
212
221
|
}
|
|
213
222
|
// Copy paste file
|
|
214
223
|
else if (!isDir) {
|
|
215
224
|
log(`${currentPath} ---> ${absToOutput}`, true)
|
|
216
|
-
configs?.onFileCreateStart?.(currentPath, absToOutput)
|
|
225
|
+
await configs?.onFileCreateStart?.(inputPath, outputPath, currentPath, absToOutput)
|
|
217
226
|
fs.copyFileSync(currentPath, absToOutput)
|
|
218
|
-
configs?.onFileCreateEnd?.(currentPath, absToOutput)
|
|
227
|
+
await configs?.onFileCreateEnd?.(inputPath, outputPath, currentPath, absToOutput, undefined)
|
|
219
228
|
}
|
|
220
229
|
|
|
221
230
|
|
|
@@ -244,7 +253,7 @@ async function createSite(inputPath, outputPath) {
|
|
|
244
253
|
else {
|
|
245
254
|
log(`Created site at ${outputPath}`)
|
|
246
255
|
}
|
|
247
|
-
configs?.onSiteCreateEnd?.(inputPath, outputPath, isCreateSitePending)
|
|
256
|
+
await configs?.onSiteCreateEnd?.(inputPath, outputPath, isCreateSitePending)
|
|
248
257
|
|
|
249
258
|
|
|
250
259
|
// Reinvoke creation
|
|
@@ -305,7 +314,7 @@ function isSubPath(potentialParent, thePath) {
|
|
|
305
314
|
thePath[potentialParent.length] === path.sep ||
|
|
306
315
|
thePath[potentialParent.length] === undefined
|
|
307
316
|
);
|
|
308
|
-
}
|
|
317
|
+
}
|
|
309
318
|
async function filterArgs(rawArgs) {
|
|
310
319
|
// Assign to create
|
|
311
320
|
let toCreateOnly = rawArgs.includes(CREATE_FLAG) || rawArgs.includes(CREATE_SHORT_FLAG)
|
|
@@ -412,10 +421,10 @@ async function watchForChanges(pathTowatch, callback) {
|
|
|
412
421
|
ignoreInitial: true
|
|
413
422
|
}).on('all', callback);
|
|
414
423
|
}
|
|
415
|
-
function startServer(htmlDir, port) { // Starts server at given port
|
|
424
|
+
async function startServer(htmlDir, port) { // Starts server at given port
|
|
416
425
|
|
|
417
426
|
// Broadcast server starting
|
|
418
|
-
configs?.onHostStart?.(port)
|
|
427
|
+
await configs?.onHostStart?.(port)
|
|
419
428
|
|
|
420
429
|
|
|
421
430
|
// Start Server
|
|
@@ -446,7 +455,7 @@ function startServer(htmlDir, port) { // Starts server at given port
|
|
|
446
455
|
|
|
447
456
|
// Start listening
|
|
448
457
|
newApp.listen(port)
|
|
449
|
-
newApp.server.on("close", () => { configs?.onHostEnd?.(port) });
|
|
458
|
+
newApp.server.on("close", async () => { await configs?.onHostEnd?.(port) });
|
|
450
459
|
newApp.server.on("error", (e) => { log(`Failed to start server: ${e.message}`); throw e; });
|
|
451
460
|
log(`Server listening at ${port} ... (Press 'r' to manually reload, Press 'Ctrl+c' to exit)`)
|
|
452
461
|
|
|
@@ -480,6 +489,7 @@ async function Main() {
|
|
|
480
489
|
// Get config
|
|
481
490
|
let configFilePath = path.join(args.inputPath, `./${CONFIG_FILE_NAME}`)
|
|
482
491
|
if (fs.existsSync(configFilePath)) {
|
|
492
|
+
log(`Importing config file ${CONFIG_FILE_NAME}`);
|
|
483
493
|
configs = await import(pathToFileURL(configFilePath).href);
|
|
484
494
|
}
|
|
485
495
|
|
|
@@ -498,8 +508,8 @@ async function Main() {
|
|
|
498
508
|
|
|
499
509
|
// Watch for changes
|
|
500
510
|
if (args.toTrackChanges) {
|
|
501
|
-
watchForChanges(args.inputPath, (event, path) => {
|
|
502
|
-
if (typeof configs
|
|
511
|
+
watchForChanges(args.inputPath, async (event, path) => {
|
|
512
|
+
if (typeof configs?.toTriggerRecreate === 'function' && !(await configs?.toTriggerRecreate(event, path))) {
|
|
503
513
|
return;
|
|
504
514
|
}
|
|
505
515
|
|
|
@@ -510,7 +520,7 @@ async function Main() {
|
|
|
510
520
|
|
|
511
521
|
|
|
512
522
|
// Start server
|
|
513
|
-
app = startServer(args.outputPath, args.port);
|
|
523
|
+
app = await startServer(args.outputPath, args.port);
|
|
514
524
|
|
|
515
525
|
|
|
516
526
|
// Handle quit
|
package/mdx-to-html.js
CHANGED
|
@@ -27,10 +27,9 @@ const jsxBundlerConfig = {
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
// Methods
|
|
30
|
-
function
|
|
30
|
+
function getMDXExport(code, globals) {
|
|
31
31
|
const fn = new Function(...Object.keys(globals), code);
|
|
32
|
-
|
|
33
|
-
return mdxExport.default;
|
|
32
|
+
return fn(...Object.values(globals));
|
|
34
33
|
}
|
|
35
34
|
export async function mdxToHtml(mdxCode, baseUrl, globalArgs = {}, modSettingsCallback = undefined) {
|
|
36
35
|
|
|
@@ -55,14 +54,18 @@ export async function mdxToHtml(mdxCode, baseUrl, globalArgs = {}, modSettingsCa
|
|
|
55
54
|
|
|
56
55
|
// Modify settings
|
|
57
56
|
if (modSettingsCallback !== undefined) {
|
|
58
|
-
settings = modSettingsCallback(settings)
|
|
57
|
+
settings = await modSettingsCallback(settings)
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
|
|
62
61
|
// Generate html
|
|
63
62
|
const { code } = await bundleMDX(settings);
|
|
64
|
-
const
|
|
63
|
+
const Exports = getMDXExport(code, { Preact, PreactDOM, _jsx_runtime, require: nativeRequire, ...globalArgs });
|
|
64
|
+
const Component = Exports.default;
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
return
|
|
67
|
+
return {
|
|
68
|
+
html: renderToString(Preact.h(Component, {})),
|
|
69
|
+
exports: Exports
|
|
70
|
+
}
|
|
68
71
|
}
|