Skip to content

Commit efb87e5

Browse files
committed
Merge branch 'master' of github.com:zenn-dev/zenn-editor
2 parents 2cbccb0 + 4b19edc commit efb87e5

File tree

5 files changed

+368
-28
lines changed

5 files changed

+368
-28
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,23 @@
1-
import { createServer } from "http";
1+
import { createServer, Server } from "http";
22
import { parse } from "url";
33
import next from "next";
4-
import arg from "arg";
54

6-
import { cliCommand } from ".";
7-
8-
export const exec: cliCommand = (argv) => {
9-
const args = arg(
10-
{
11-
// Types
12-
"--port": Number,
13-
14-
// Alias
15-
"-p": "--port",
16-
},
17-
{ argv }
18-
);
19-
20-
const port = args["--port"] || 8000;
21-
const previewUrl = `http://localhost:${port}`;
5+
type BuildArgs = {
6+
srcDir: string;
7+
port: number;
8+
previewUrl: string;
9+
};
2210

23-
const srcDir = `${__dirname}/../../.`; // refer project root from dist/cli/zenn-preview.js
11+
export const build = async ({
12+
srcDir,
13+
port,
14+
previewUrl,
15+
}: BuildArgs): Promise<Server> => {
2416
const app = next({ dev: false, dir: srcDir, conf: {} });
2517
const handle = app.getRequestHandler();
26-
27-
app.prepare().then(() => {
28-
createServer((req, res) => {
18+
await app.prepare();
19+
return new Promise((resolve) => {
20+
const server = createServer((req, res) => {
2921
const requestUrl = req.url;
3022
if (!requestUrl) {
3123
return console.error("Undefined request url");
@@ -38,6 +30,7 @@ export const exec: cliCommand = (argv) => {
3830
process.exit(1);
3931
}
4032
console.log(`👀Preview on ${previewUrl}`);
33+
resolve(server);
4134
});
4235
});
4336
};
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import arg from "arg";
2+
import { cliCommand } from "..";
3+
import { build } from "./build";
4+
import chokidar from "chokidar";
5+
import socketIo from "socket.io";
6+
import open from "open";
7+
8+
export const exec: cliCommand = async (argv) => {
9+
const args = arg(
10+
{
11+
// Types
12+
"--port": Number,
13+
14+
// Alias
15+
"-p": "--port",
16+
17+
// Types
18+
"--watch": Boolean,
19+
20+
// Alias
21+
"-w": "--watch",
22+
},
23+
{ argv }
24+
);
25+
26+
const port = args["--port"] || 8000;
27+
const watch = args["--watch"] ?? true;
28+
const previewUrl = `http://localhost:${port}`;
29+
const srcDir = process.cwd(); // refer project root from dist/cli/zenn-preview.js
30+
const server = await build({ port, previewUrl, srcDir });
31+
await open(previewUrl);
32+
if (watch) {
33+
const watcher = chokidar.watch(srcDir);
34+
const io = socketIo(server);
35+
watcher.on("ready", () => {
36+
io.on("connection", (socket) => {
37+
watcher.on("all", async (_, path) => {
38+
if (/articles|books/.test(path)) {
39+
socket.emit("reload");
40+
}
41+
});
42+
});
43+
});
44+
}
45+
};

packages/zenn-cli/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,20 @@
2121
"build": "npm run lint && npm run build:bin & npm run build:next"
2222
},
2323
"dependencies": {
24+
"@types/socket.io": "^2.1.11",
2425
"arg": "^4.1.3",
26+
"chokidar": "^3.4.2",
2527
"colors": "^1.4.0",
2628
"crypto-random-string": "^3.2.0",
2729
"fs-extra": "^9.0.1",
2830
"gray-matter": "^4.0.2",
2931
"js-yaml": "^3.14.0",
3032
"next": "9.5.2",
33+
"open": "^7.2.1",
3134
"react": "^16.13.1",
3235
"react-dom": "^16.13.1",
36+
"socket.io": "^2.3.0",
37+
"socket.io-client": "^2.3.0",
3338
"update-notifier": "^4.1.0",
3439
"zenn-content-css": "^0.1.22",
3540
"zenn-init-embed": "^0.1.3",

packages/zenn-cli/pages/_app.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
1-
import React from "react";
1+
import React, { useEffect } from "react";
22
import { AppProps } from "next/app";
33
import Head from "next/head";
44

55
import "zenn-content-css";
66
import "@styles/index.scss";
77

8+
declare global {
9+
interface Window {
10+
io: any;
11+
}
12+
}
13+
814
export default function MyApp({ Component, pageProps }: AppProps) {
15+
useEffect(() => {
16+
const { body } = document;
17+
const script = document.createElement("script");
18+
script.src = "/socket.io/socket.io.js";
19+
script.onload = () => {
20+
const socket = (window.io as any).connect(location.origin);
21+
socket.on("reload", () => {
22+
location.reload();
23+
});
24+
};
25+
body.append(script);
26+
}, []);
27+
928
return (
1029
<>
1130
<Head>

0 commit comments

Comments
 (0)