Files
2026-08-08 16:55:22 +08:00

139 lines
5.5 KiB
TypeScript

import react from '@vitejs/plugin-react';
import {readdirSync, readFileSync, statSync} from 'node:fs';
import {extname, resolve, sep} from 'node:path';
import {fileURLToPath, URL} from 'node:url';
import {defineConfig, type Plugin} from 'vite';
const output_dir = fileURLToPath(new URL('../frontend_dist', import.meta.url));
const cache_dir = fileURLToPath(new URL('./node_modules/.vite-adminive', import.meta.url));
const amis_sdk_dir = fileURLToPath(new URL('./node_modules/amis/sdk', import.meta.url));
const amis_package = JSON.parse(readFileSync(fileURLToPath(new URL('./node_modules/amis/package.json', import.meta.url)), 'utf8')) as {version: string};
const amis_sdk_url_prefix = `/vendor/amis/${amis_package.version}/`;
function content_type(file_name: string) {
switch(extname(file_name).toLowerCase()) {
case '.css':
return 'text/css; charset=utf-8';
case '.js':
return 'text/javascript; charset=utf-8';
case '.json':
return 'application/json; charset=utf-8';
case '.svg':
return 'image/svg+xml';
case '.woff':
return 'font/woff';
case '.woff2':
return 'font/woff2';
case '.ttf':
return 'font/ttf';
default:
return 'application/octet-stream';
}
}
function amis_sdk_plugin(): Plugin {
return {
name: 'adminive-amis-sdk',
enforce: 'pre',
resolveId(source) {
if(source === 'amis' || source.startsWith('amis/')) {
this.error(`Do not import ${source} into the Adminive Vite module graph; use the AMIS SDK runtime instead`);
}
return null;
},
buildStart() {
const emit_directory = (directory: string, prefix: string) => {
for(const entry of readdirSync(directory)) {
const source_path = resolve(directory, entry);
const relative_path = `${prefix}${entry}`;
if(statSync(source_path).isDirectory()) {
emit_directory(source_path, `${relative_path}/`);
continue;
}
this.emitFile({
type: 'asset',
fileName: `vendor/amis/${amis_package.version}/${relative_path}`,
source: readFileSync(source_path)
});
}
};
emit_directory(amis_sdk_dir, '');
},
transformIndexHtml: {
order: 'post',
handler() {
return [
{tag: 'link', attrs: {rel: 'stylesheet', href: `${amis_sdk_url_prefix}sdk.css`}, injectTo: 'head-prepend'},
{tag: 'link', attrs: {rel: 'stylesheet', href: `${amis_sdk_url_prefix}helper.css`}, injectTo: 'head-prepend'},
{tag: 'link', attrs: {rel: 'stylesheet', href: `${amis_sdk_url_prefix}iconfont.css`}, injectTo: 'head-prepend'},
{tag: 'script', attrs: {src: `${amis_sdk_url_prefix}sdk.js`}, injectTo: 'head-prepend'}
];
}
},
configureServer(server) {
server.middlewares.use((request, response, next) => {
const pathname = new URL(request.url ?? '/', 'http://localhost').pathname;
if(!pathname.startsWith(amis_sdk_url_prefix)) {
next();
return;
}
const relative_path = decodeURIComponent(pathname.slice(amis_sdk_url_prefix.length));
const source_path = resolve(amis_sdk_dir, relative_path);
if(source_path !== amis_sdk_dir && !source_path.startsWith(`${amis_sdk_dir}${sep}`)) {
next();
return;
}
try {
const source = readFileSync(source_path);
response.statusCode = 200;
response.setHeader('Content-Type', content_type(source_path));
response.end(source);
} catch {
next();
}
});
},
configurePreviewServer(server) {
server.middlewares.use((request, response, next) => {
const pathname = new URL(request.url ?? '/', 'http://localhost').pathname;
if(!pathname.startsWith(amis_sdk_url_prefix)) {
next();
return;
}
const relative_path = decodeURIComponent(pathname.slice(amis_sdk_url_prefix.length));
const source_path = resolve(amis_sdk_dir, relative_path);
if(source_path !== amis_sdk_dir && !source_path.startsWith(`${amis_sdk_dir}${sep}`)) {
next();
return;
}
try {
const source = readFileSync(source_path);
response.statusCode = 200;
response.setHeader('Content-Type', content_type(source_path));
response.end(source);
} catch {
next();
}
});
}
};
}
export default defineConfig({
cacheDir: cache_dir,
plugins: [react(), amis_sdk_plugin()],
resolve: {
dedupe: ['react', 'react-dom']
},
server: {
host: '0.0.0.0',
port: 5173,
proxy: {
'/admin': {
target: 'http://127.0.0.1:9999',
changeOrigin: true
}
}
},
build: {
outDir: output_dir,
emptyOutDir: true
}
});