feat: add detect app micro
This commit is contained in:
parent
4bbc531ac7
commit
ce6037ead9
@ -23,7 +23,7 @@ export const loadAppInfo = async (): Promise<AppInfoConfig> => {
|
||||
const basePath = path.dirname(pkgs);
|
||||
if (!configFile) {
|
||||
configFile = path.join(basePath, 'apps.config.json');
|
||||
fs.writeFileSync(configFile, JSON.stringify({}));
|
||||
fs.writeFileSync(configFile, JSON.stringify({ list: [] }));
|
||||
return { list: [] };
|
||||
}
|
||||
const config = fs.readFileSync(configFile, 'utf-8');
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { app } from '@/app.ts';
|
||||
import { MicroAppModel } from './models.ts';
|
||||
import { appPathCheck, installApp } from './module/install-app.ts';
|
||||
import { appPathCheck, getAppPathKeys, installApp, installAppFromKey } from './module/install-app.ts';
|
||||
import { loadApp } from './module/load-app.ts';
|
||||
import { manager } from './manager-app.ts';
|
||||
|
||||
@ -10,6 +10,7 @@ app
|
||||
path: 'micro-app',
|
||||
key: 'upload',
|
||||
middleware: ['auth'],
|
||||
description: 'Upload micro app',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const { files, collection } = ctx.query?.data;
|
||||
@ -48,6 +49,7 @@ app
|
||||
.route({
|
||||
path: 'micro-app',
|
||||
key: 'deploy',
|
||||
description: 'Deploy micro app',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
// const { id, key} = ctx.query?.data;
|
||||
@ -80,6 +82,7 @@ app
|
||||
.route({
|
||||
path: 'micro-app',
|
||||
key: 'load',
|
||||
description: 'Load micro app, no use',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
// const { key } = ctx.query?.data;
|
||||
@ -95,8 +98,7 @@ app
|
||||
} catch (e) {
|
||||
ctx.throw(400, e.message);
|
||||
}
|
||||
})
|
||||
.addTo(app);
|
||||
});
|
||||
|
||||
// curl http://localhost:4002/api/router?path=micro-app&key=unload
|
||||
app
|
||||
@ -115,3 +117,39 @@ app
|
||||
ctx.body = main;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'micro-app',
|
||||
key: 'detect',
|
||||
description: 'Detect micro app,检测apps的没有加载进来的app模块',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const list = manager.getAllAppShowInfo();
|
||||
const appPathKeys = await getAppPathKeys();
|
||||
const notIn = appPathKeys.filter((key) => !list.find((item) => item.key === key));
|
||||
console.log('Not in', notIn);
|
||||
const loadInfo = [];
|
||||
if (notIn.length <= 0) {
|
||||
loadInfo.push('ok');
|
||||
ctx.body = {
|
||||
data: loadInfo,
|
||||
};
|
||||
ctx.message = 'All apps are loaded';
|
||||
return;
|
||||
}
|
||||
for (const key of notIn) {
|
||||
try {
|
||||
const { showAppInfo } = await installAppFromKey(key);
|
||||
await manager.add(showAppInfo);
|
||||
loadInfo.push(`Load ${key} success`);
|
||||
} catch (e) {
|
||||
loadInfo.push(`Load ${key} error`);
|
||||
}
|
||||
}
|
||||
ctx.body = {
|
||||
data: loadInfo,
|
||||
notIn,
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
@ -47,7 +47,14 @@ export const installApp = async (opts: InstallAppOpts) => {
|
||||
file: filePath,
|
||||
cwd: extractPath,
|
||||
});
|
||||
const pkgs = path.join(extractPath, 'package.json');
|
||||
return installAppFromKey(key);
|
||||
};
|
||||
export const installAppFromKey = async (key: string) => {
|
||||
const directory = path.join(appsPath, key);
|
||||
if (!fileIsExist(directory)) {
|
||||
throw new Error('App not found');
|
||||
}
|
||||
const pkgs = path.join(directory, 'package.json');
|
||||
if (!fileIsExist(pkgs)) {
|
||||
throw new Error('Invalid package.json');
|
||||
}
|
||||
@ -57,8 +64,7 @@ export const installApp = async (opts: InstallAppOpts) => {
|
||||
if (!name || !version || !app) {
|
||||
throw new Error('Invalid package.json');
|
||||
}
|
||||
|
||||
const readmeFile = path.join(extractPath, 'README.md');
|
||||
const readmeFile = path.join(directory, 'README.md');
|
||||
let readmeDesc = '';
|
||||
if (fileIsExist(readmeFile)) {
|
||||
readmeDesc = fs.readFileSync(readmeFile, 'utf-8');
|
||||
@ -71,11 +77,19 @@ export const installApp = async (opts: InstallAppOpts) => {
|
||||
version,
|
||||
//
|
||||
entry: app?.entry || '',
|
||||
path: extractPath,
|
||||
path: directory,
|
||||
origin: app,
|
||||
};
|
||||
app.key = key;
|
||||
fs.writeFileSync(pkgs, JSON.stringify(pkg, null, 2));
|
||||
// fs.unlinkSync(filePath);
|
||||
return { path: filePath, pkg, showAppInfo };
|
||||
return { pkg, showAppInfo };
|
||||
};
|
||||
export const getAppPathKeys = async () => {
|
||||
let files = fs.readdirSync(appsPath);
|
||||
files = files.filter((file) => {
|
||||
const stat = fs.statSync(path.join(appsPath, file));
|
||||
if (file === 'node_modules') return false;
|
||||
return stat.isDirectory();
|
||||
});
|
||||
return files;
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import { fork } from 'child_process';
|
||||
import { merge } from 'lodash-es';
|
||||
import { deleteFileAppInfo } from './load-app.ts';
|
||||
import { fileIsExist } from '@kevisual/use-config';
|
||||
import path from 'path';
|
||||
// 共享
|
||||
export const existDenpend = [
|
||||
'sequelize', // commonjs
|
||||
@ -82,8 +83,13 @@ export class Manager<T extends AppInfo = any> {
|
||||
if (app.status !== 'running') {
|
||||
return;
|
||||
}
|
||||
if (!fileIsExist(app.entry)) {
|
||||
console.error('file not found');
|
||||
if (!fileIsExist(app.path)) {
|
||||
console.error('app is not found');
|
||||
return;
|
||||
}
|
||||
const pathEntry = path.join(app.path, app.entry);
|
||||
if (!fileIsExist(pathEntry)) {
|
||||
console.error('file entry not found');
|
||||
return;
|
||||
}
|
||||
const entry = app.entry + `?timestamp=${app?.timestamp}`;
|
||||
@ -102,6 +108,7 @@ export class Manager<T extends AppInfo = any> {
|
||||
} else if (app.type === AppType.GatewayApp) {
|
||||
console.log('gateway app not support');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* create new app info
|
||||
@ -124,10 +131,21 @@ export class Manager<T extends AppInfo = any> {
|
||||
async load() {
|
||||
// 从apps文件夹列表当中中加载app信息
|
||||
const appInfos = await loadAppInfo();
|
||||
this.appInfo = appInfos;
|
||||
const list = appInfos?.list || [];
|
||||
for (const app of list) {
|
||||
try {
|
||||
this.loadApp(app);
|
||||
const loaded = await this.loadApp(app);
|
||||
if (!loaded) {
|
||||
// 加载失败,如果是running状态,设置为error
|
||||
if (app.status === 'running') {
|
||||
app.status = 'error';
|
||||
console.log('load app error', app); // save app error info
|
||||
await this.saveAppInfo(app);
|
||||
}
|
||||
} else {
|
||||
// console.log('load app success', app);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('load app', e);
|
||||
}
|
||||
|
8
src/routes/micro-app/test/path-keys.test.ts
Normal file
8
src/routes/micro-app/test/path-keys.test.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { getAppPathKeys } from '../module/install-app.ts';
|
||||
|
||||
const main = () => {
|
||||
const keys = getAppPathKeys();
|
||||
console.log('Keys', keys);
|
||||
};
|
||||
|
||||
main();
|
Loading…
x
Reference in New Issue
Block a user