File size: 3,383 Bytes
a03b3ba |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
import { join } from "path";
import * as fs from "fs";
import { createServer, createLogger } from "vite";
import { plugins, make_gradio_plugin } from "./plugins";
import { examine_module } from "./index";
const vite_messages_to_ignore = [
"Default and named imports from CSS files are deprecated.",
"The above dynamic import cannot be analyzed by Vite."
];
const logger = createLogger();
const originalWarning = logger.warn;
logger.warn = (msg, options) => {
if (vite_messages_to_ignore.some((m) => msg.includes(m))) return;
originalWarning(msg, options);
};
interface ServerOptions {
component_dir: string;
root_dir: string;
frontend_port: number;
backend_port: number;
host: string;
}
export async function create_server({
component_dir,
root_dir,
frontend_port,
backend_port,
host
}: ServerOptions): Promise<void> {
process.env.gradio_mode = "dev";
const imports = generate_imports(component_dir, root_dir);
const NODE_DIR = join(root_dir, "..", "..", "node", "dev");
const svelte_dir = join(root_dir, "assets", "svelte");
try {
const server = await createServer({
esbuild: false,
customLogger: logger,
mode: "development",
configFile: false,
root: root_dir,
optimizeDeps: {
disabled: true
},
server: {
port: frontend_port,
host: host,
fs: {
allow: [root_dir, NODE_DIR, component_dir]
}
},
plugins: [
...plugins,
make_gradio_plugin({
mode: "dev",
backend_port,
svelte_dir,
imports
})
]
});
await server.listen();
console.info(
`[orange3]Frontend Server[/] (Go here): ${server.resolvedUrls?.local}`
);
} catch (e) {
console.error(e);
}
}
function find_frontend_folders(start_path: string): string[] {
if (!fs.existsSync(start_path)) {
console.warn("No directory found at:", start_path);
return [];
}
if (fs.existsSync(join(start_path, "pyproject.toml"))) return [start_path];
const results: string[] = [];
const dir = fs.readdirSync(start_path);
dir.forEach((dir) => {
const filepath = join(start_path, dir);
if (fs.existsSync(filepath)) {
if (fs.existsSync(join(filepath, "pyproject.toml")))
results.push(filepath);
}
});
return results;
}
function to_posix(_path: string): string {
const isExtendedLengthPath = /^\\\\\?\\/.test(_path);
const hasNonAscii = /[^\u0000-\u0080]+/.test(_path); // eslint-disable-line no-control-regex
if (isExtendedLengthPath || hasNonAscii) {
return _path;
}
return _path.replace(/\\/g, "/");
}
function generate_imports(component_dir: string, root: string): string {
const components = find_frontend_folders(component_dir);
const component_entries = components.flatMap((component) => {
return examine_module(component, root, "dev");
});
const imports = component_entries.reduce((acc, component) => {
const pkg = JSON.parse(
fs.readFileSync(join(component.frontend_dir, "package.json"), "utf-8")
);
const exports: Record<string, string | undefined> = {
component: pkg.exports["."],
example: pkg.exports["./example"]
};
const example = exports.example
? `example: () => import("${to_posix(
join(component.frontend_dir, exports.example)
)}"),\n`
: "";
return `${acc}"${component.component_class_id}": {
${example}
component: () => import("${to_posix(component.frontend_dir)}")
},\n`;
}, "");
return `{${imports}}`;
}
|