Skip to content

Commit 32dcd3f

Browse files
feat(dx): add a dev-server for debugging on mobile devices from a local network (codex-team#2009)
* Add server * Get rid of express * Cleanup * Revert lock * Revert lock 2 * Update script to substitute ip address automatically * terminal output improved * npm ignore devserver.js * rm spaces * handle offline state * Update devserver.js * Update changelog Co-authored-by: Peter Savchenko <[email protected]>
1 parent 771437e commit 32dcd3f

File tree

4 files changed

+135
-1
lines changed

4 files changed

+135
-1
lines changed

.npmignore

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ tsconfig.json
1919
tslint.json
2020
webpack.config.js
2121
yarn.lock
22+
devserver.js

devserver.js

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/**
2+
* Server for testing example page on mobile devices.
3+
*
4+
* Usage:
5+
* 1. run `yarn devserver:start`
6+
* 2. Open `http://{ip_address}:3000/example/example-dev.html`
7+
* where {ip_address} is IP of your machine.
8+
*
9+
* Also, can serve static files from `/example` or `/dist` on any device in local network.
10+
*/
11+
const path = require('path');
12+
const fs = require('fs');
13+
const http = require('http');
14+
const { networkInterfaces } = require('os');
15+
16+
const port = 3000;
17+
const localhost = '127.0.0.1';
18+
const nonRoutableAddress = '0.0.0.0';
19+
const host = getHost();
20+
const server = http.createServer(serveStatic([
21+
'/example',
22+
'/dist',
23+
]));
24+
25+
server.listen(port, nonRoutableAddress, () => {
26+
console.log(`
27+
28+
${wrapInColor('Editor.js 💖', consoleColors.hiColor)} devserver is running ᕕ(⌐■_■)ᕗ ✨
29+
---------------------------------------------
30+
${wrapInColor('http://' + host + ':' + port + '/example/example-dev.html', consoleColors.fgGreen)}
31+
---------------------------------------------
32+
Page can be opened from any device connected to the same local network.
33+
`);
34+
35+
if (host === localhost) {
36+
console.log(wrapInColor('Looks like you are not connected to any Network so you couldn\'t debug the Editor on your mobile device at the moment.', consoleColors.fgRed));
37+
}
38+
});
39+
40+
/**
41+
* Serves files from specified directories
42+
*
43+
* @param {string[]} paths - directories files from which should be served
44+
* @returns {Function}
45+
*/
46+
function serveStatic(paths) {
47+
return (request, response) => {
48+
const resource = request.url;
49+
const isPathAllowed = paths.find(p => resource.startsWith(p));
50+
51+
if (!isPathAllowed) {
52+
response.writeHead(404);
53+
response.end();
54+
55+
return;
56+
}
57+
const filePath = path.join(__dirname, resource);
58+
59+
try {
60+
const stat = fs.statSync(filePath);
61+
62+
response.writeHead(200, {
63+
'Content-Length': stat.size,
64+
});
65+
const readStream = fs.createReadStream(filePath);
66+
67+
readStream.on('error', e => {
68+
throw e;
69+
});
70+
readStream.pipe(response);
71+
} catch (e) {
72+
response.writeHead(500);
73+
response.end(e.toString());
74+
}
75+
};
76+
}
77+
78+
/**
79+
* Returns IP address of a machine
80+
*
81+
* @returns {string}
82+
*/
83+
function getHost() {
84+
const nets = networkInterfaces();
85+
const results = {};
86+
87+
for (const name of Object.keys(nets)) {
88+
for (const net of nets[name]) {
89+
// Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
90+
if (net.family === 'IPv4' && !net.internal) {
91+
if (!results[name]) {
92+
results[name] = [];
93+
}
94+
results[name].push(net.address);
95+
}
96+
}
97+
}
98+
99+
/**
100+
* Offline case
101+
*/
102+
if (Object.keys(results).length === 0) {
103+
return localhost;
104+
}
105+
106+
return results['en0'][0];
107+
}
108+
109+
/**
110+
* Terminal output colors
111+
*/
112+
const consoleColors = {
113+
fgMagenta: 35,
114+
fgRed: 31,
115+
fgGreen: 32,
116+
hiColor: 1,
117+
};
118+
119+
/**
120+
* Set a terminal color to the message
121+
*
122+
* @param {string} msg - text to wrap
123+
* @param {string} color - color
124+
* @returns {string}
125+
*/
126+
function wrapInColor(msg, color) {
127+
return '\x1b[' + color + 'm' + msg + '\x1b[0m';
128+
}

docs/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
### 2.23.3
4+
5+
- `Improvement`*Dev Example Page* - Server added to allow opening example page on other devices in network.
6+
37
### 2.23.2
48

59
`Fix` — Crash on initialization in the read-only mode [#1968](https://github.com/codex-team/editor.js/issues/1968)

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"_tools:make": "yarn _tools:yarn && yarn _tools:build",
3232
"tools:update": "yarn _tools:checkout && yarn _tools:pull && yarn _tools:make",
3333
"test:e2e": "yarn build && cypress run",
34-
"test:e2e:open": "yarn build && cypress open"
34+
"test:e2e:open": "yarn build && cypress open",
35+
"devserver:start": "yarn build && node ./devserver.js"
3536
},
3637
"author": "CodeX",
3738
"license": "Apache-2.0",

0 commit comments

Comments
 (0)