Doric cli: add dev
This commit is contained in:
parent
a9cfd8b41a
commit
d4c8d08660
@ -17,16 +17,21 @@ export async function clean() {
|
|||||||
await Shell.exec("rm", ["-rf", "bundle"]);
|
await Shell.exec("rm", ["-rf", "bundle"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function doMerge(jsFile: string) {
|
async function doMerge(jsFile: string) {
|
||||||
const mappingFile = `${jsFile}.map`;
|
const mapFile = `${jsFile}.map`;
|
||||||
console.log(`Bundle -> ${jsFile.green}`);
|
console.log(`Bundle -> ${jsFile.green}`);
|
||||||
if (!fs.existsSync(mappingFile)) {
|
if (!fs.existsSync(mapFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log(` -> ${mappingFile.green}`);
|
console.log(` -> ${mapFile.green}`);
|
||||||
const mergedMap = createMergedSourceMapFromFiles([
|
await mergeMap(mapFile);
|
||||||
mappingFile.replace(/bundle\//, 'build/'),
|
|
||||||
mappingFile,
|
|
||||||
], true);
|
|
||||||
await fs.promises.writeFile(mappingFile, mergedMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function mergeMap(mapFile: string) {
|
||||||
|
const mergedMap = createMergedSourceMapFromFiles([
|
||||||
|
mapFile.replace(/bundle\//, 'build/'),
|
||||||
|
mapFile,
|
||||||
|
], true);
|
||||||
|
await fs.promises.writeFile(mapFile, mergedMap);
|
||||||
|
}
|
99
doric-cli/src/dev.ts
Normal file
99
doric-cli/src/dev.ts
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import { exec } from "child_process"
|
||||||
|
import chokidar from "chokidar";
|
||||||
|
import { createServer } from "./server"
|
||||||
|
import { delay } from "./util";
|
||||||
|
import fs from "fs";
|
||||||
|
import { mergeMap } from "./actions";
|
||||||
|
import os from "os";
|
||||||
|
import qrcode from "qrcode-terminal";
|
||||||
|
import keypress from "keypress";
|
||||||
|
|
||||||
|
function getIPAdress() {
|
||||||
|
const ret: string[] = [];
|
||||||
|
const interfaces = os.networkInterfaces();
|
||||||
|
Object.entries(interfaces).map(e => e[1])
|
||||||
|
.forEach(e => {
|
||||||
|
if (!!!e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.forEach(e => {
|
||||||
|
if (
|
||||||
|
e.family === "IPv4" &&
|
||||||
|
e.address !== "127.0.0.1" &&
|
||||||
|
!e.internal
|
||||||
|
) {
|
||||||
|
ret.push(e.address);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function dev() {
|
||||||
|
const server = await createServer()
|
||||||
|
const tscProcess = exec("node node_modules/.bin/tsc -w -p .");
|
||||||
|
const rollupProcess = exec("node node_modules/.bin/rollup -c -w");
|
||||||
|
console.warn("Waiting ...");
|
||||||
|
const ips = getIPAdress();
|
||||||
|
ips.forEach((e) => {
|
||||||
|
console.log(`IP:${e}`);
|
||||||
|
qrcode.generate(e, { small: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
keypress(process.stdin);
|
||||||
|
process.stdin.on("keypress", function (ch, key) {
|
||||||
|
if (key && key.ctrl && key.name == "r") {
|
||||||
|
ips.forEach((e) => {
|
||||||
|
console.log(`IP:${e}`);
|
||||||
|
qrcode.generate(e, { small: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (key && key.ctrl && key.name == "c") {
|
||||||
|
process.stdin.pause();
|
||||||
|
tscProcess.kill("SIGABRT");
|
||||||
|
rollupProcess.kill("SIGABRT");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
process.stdin.setRawMode(true);
|
||||||
|
process.stdin.resume();
|
||||||
|
await delay(3000);
|
||||||
|
console.warn("Start watching");
|
||||||
|
server.listen(7777);
|
||||||
|
chokidar
|
||||||
|
.watch(process.cwd() + "/bundle", {
|
||||||
|
ignored: /.*?\.map/,
|
||||||
|
alwaysStat: true,
|
||||||
|
})
|
||||||
|
.on("change", (jsFile) => {
|
||||||
|
console.log("*******", jsFile.replace(process.cwd(), "")
|
||||||
|
.replace("/bundle/src/", "")
|
||||||
|
.replace(".js", "")
|
||||||
|
.green, "*******")
|
||||||
|
if ((server as any).debugging) {
|
||||||
|
console.log("debugging, hot reload by pass");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fs.readFile(jsFile, "utf-8", (error, data) => {
|
||||||
|
try {
|
||||||
|
const sourceMap = mergeMap(`${jsFile}.map`);
|
||||||
|
server.connections.forEach((e: any) => {
|
||||||
|
e.sendText(
|
||||||
|
JSON.stringify({
|
||||||
|
cmd: "RELOAD",
|
||||||
|
script: data,
|
||||||
|
source: (jsFile.match(/[^/\\]*$/) || [""])[0],
|
||||||
|
sourceMap,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
import commander from "commander"
|
import commander from "commander"
|
||||||
import { build, clean } from "./actions";
|
import { build, clean } from "./actions";
|
||||||
import create from "./create"
|
import create from "./create"
|
||||||
|
import dev from "./dev"
|
||||||
commander
|
commander
|
||||||
.command('create <name>')
|
.command('create <name>')
|
||||||
.action(async function (name, cmd) {
|
.action(async function (name, cmd) {
|
||||||
@ -16,7 +16,8 @@ commander
|
|||||||
})
|
})
|
||||||
commander
|
commander
|
||||||
.command('dev')
|
.command('dev')
|
||||||
.action(function () {
|
.action(async function () {
|
||||||
|
await dev()
|
||||||
})
|
})
|
||||||
commander
|
commander
|
||||||
.command('build')
|
.command('build')
|
||||||
|
5
doric-cli/src/modules.d.ts
vendored
5
doric-cli/src/modules.d.ts
vendored
@ -1 +1,4 @@
|
|||||||
declare module 'source-map-merger'
|
declare module 'source-map-merger'
|
||||||
|
declare module 'nodejs-websocket'
|
||||||
|
declare module 'qrcode-terminal'
|
||||||
|
declare module 'keypress'
|
77
doric-cli/src/server.ts
Normal file
77
doric-cli/src/server.ts
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import fs from "fs";
|
||||||
|
import { exec, spawn } from "child_process";
|
||||||
|
import ws from "nodejs-websocket";
|
||||||
|
import "colors";
|
||||||
|
|
||||||
|
export async function createServer() {
|
||||||
|
console.log("Create Server")
|
||||||
|
let contextId: string = "0"
|
||||||
|
let clientConnection: any = null
|
||||||
|
let debuggerConnection: any = null
|
||||||
|
const server = (ws as any).createServer((connection: any) => {
|
||||||
|
console.log('Connected', connection.headers.host)
|
||||||
|
if (connection.headers.host.startsWith("localhost")) {
|
||||||
|
console.log(`Debugger ${connection.key} attached to dev kit`.green)
|
||||||
|
debuggerConnection = connection
|
||||||
|
clientConnection.sendText(JSON.stringify({
|
||||||
|
cmd: 'SWITCH_TO_DEBUG',
|
||||||
|
contextId: contextId
|
||||||
|
}), () => { })
|
||||||
|
} else {
|
||||||
|
console.log(`Client ${connection.key} attached to dev kit`.green)
|
||||||
|
}
|
||||||
|
|
||||||
|
connection.on('text', function (result: string) {
|
||||||
|
let resultObject = JSON.parse(result)
|
||||||
|
switch (resultObject.cmd) {
|
||||||
|
case 'DEBUG':
|
||||||
|
clientConnection = connection;
|
||||||
|
(server as any).debugging = true;
|
||||||
|
console.log("Enter debugging");
|
||||||
|
contextId = resultObject.data.contextId;
|
||||||
|
let projectHome = '.';
|
||||||
|
|
||||||
|
fs.writeFileSync(projectHome + '/build/context', contextId, 'utf8');
|
||||||
|
|
||||||
|
let source = resultObject.data.source;
|
||||||
|
console.log(connection.key + " request debug, project home: " + projectHome);
|
||||||
|
spawn('code', [projectHome, projectHome + "/src/" + source]);
|
||||||
|
setTimeout(() => {
|
||||||
|
exec('osascript -e \'tell application "System Events"\ntell application "Visual Studio Code" to activate\nkey code 96\nend tell\'', (err, stdout, stderr) => {
|
||||||
|
if (err) {
|
||||||
|
console.log(`stdout: ${err}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 1500);
|
||||||
|
break;
|
||||||
|
case 'EXCEPTION':
|
||||||
|
console.log(resultObject.data.source.red);
|
||||||
|
console.log(resultObject.data.exception.red);
|
||||||
|
break;
|
||||||
|
case 'LOG':
|
||||||
|
if (resultObject.data.type == 'DEFAULT') {
|
||||||
|
console.log((resultObject.data.message as string).green);
|
||||||
|
} else if (resultObject.data.type == 'ERROR') {
|
||||||
|
console.log((resultObject.data.message as string).red);
|
||||||
|
} else if (resultObject.data.type == 'WARN') {
|
||||||
|
console.log((resultObject.data.message as string).yellow);
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
connection.on('connect', function (code: number) {
|
||||||
|
console.log('connect', code)
|
||||||
|
})
|
||||||
|
connection.on('close', function (code: number) {
|
||||||
|
console.log('close: code = ' + code, connection.key)
|
||||||
|
console.log("quit debugging");
|
||||||
|
(server as any).debugging = false
|
||||||
|
})
|
||||||
|
connection.on('error', function (code: number) {
|
||||||
|
console.log('error', code)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
|||||||
import globLib, { IOptions } from "glob";
|
import globLib, { IOptions } from "glob";
|
||||||
|
|
||||||
|
export async function delay(timeout: number) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve('');
|
||||||
|
}, timeout);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function getAssetsDir() {
|
export function getAssetsDir() {
|
||||||
return `${__dirname}/../assets`;
|
return `${__dirname}/../assets`;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user