Share assets between Bevy app and web frontend

This commit is contained in:
Danny McGee
2023-09-29 18:19:22 -04:00
parent 7cc20fa500
commit fc66d2e1b3
6 changed files with 159 additions and 2 deletions
@@ -0,0 +1,25 @@
import fs from "fs";
import {NormalizedOutputOptions} from "rollup";
function copyRecursively(src: string, dst: string) {
if (fs.statSync(src).isDirectory()) {
// folder
if (!fs.existsSync(dst)) {
fs.mkdirSync(dst);
}
for (const file of fs.readdirSync(src)) {
copyRecursively(src + "/" + file, dst + "/" + file);
}
} else {
// file
fs.copyFileSync(src, dst);
}
}
export function buildMiddleWare(options: NormalizedOutputOptions, assets: string[] = []) {
const dst = options.dir;
if (!dst) throw new Error("options.dir is undefined");
for (const dir of assets) {
copyRecursively(dir, dst)
}
}
@@ -0,0 +1,23 @@
// NOTE: This is an inline fork of this npm package:
// https://github.com/nguyenbatranvan/vite-multiple-assets
//
// The published version at time of writing doesn't include a mime type for
// WGSL, which is fixed in this copy. This module can be removed and replaced
// with the npm dependency if/when this PR is accepted:
// https://github.com/nguyenbatranvan/vite-multiple-assets/pull/5
import {PluginOption, ViteDevServer} from "vite";
import {ServerMiddleWare} from "./server";
import {buildMiddleWare} from "./build";
export default function DynamicPublicDirectory(assets: string[]): PluginOption {
return {
configureServer(server: ViteDevServer) {
return ServerMiddleWare(server, assets)
},
async writeBundle(options) {
buildMiddleWare(options, assets)
},
name: "dynamic assets"
};
}
@@ -0,0 +1,85 @@
import fs from "fs";
import path from "path";
import { ViteDevServer } from "vite";
interface IPropsFile {
name: string;
files: string[];
}
function getFiles(dir, files_): string[] {
files_ = files_ || [];
const files = fs.readdirSync(dir);
for (const i in files) {
const name = dir + "/" + files[i];
if (fs.statSync(name).isDirectory()) {
getFiles(name, files_);
} else {
files_.push(name);
}
}
return files_;
}
const mimeTypes = {
".html": "text/html",
".js": "text/javascript",
".css": "text/css",
".png": "image/png",
".jpg": "image/jpeg",
".gif": "image/gif",
".svg": "image/svg+xml",
".json": "application/json",
".woff": "font/woff",
".woff2": "font/woff2",
".ttf": "font/ttf",
".eot": "font/eot",
".otf": "font/otf",
".wasm": "application/wasm",
".mjs": "text/javascript",
".txt": "text/plain",
".xml": "text/xml",
".mp3": "audio/mpeg",
".mp4": "video/mp4",
".webm": "video/webm",
".webp": "image/webp",
".wgsl": "text/wgsl",
".ico": "image/x-icon",
".tiff": "image/tiff",
".gz": "application/gzip",
".zip": "application/zip",
".rar": "application/x-rar-compressed",
".7z": "application/x-7z-compressed",
}
export function ServerMiddleWare(server: ViteDevServer, assets: string[] = []) {
if (!assets || !assets.length)
return;
const fileObject: IPropsFile[] = [];
for (let i = 0; i < assets.length; i++) {
const files = getFiles(path.join(process.cwd(), `/${assets[i]}`), []);
fileObject.push({
name: assets[i],
files
});
}
return () => {
server.middlewares.use(async (req, res, next) => {
for (let i = 0; i < fileObject.length; i++) {
const file = path.join(process.cwd(), `${fileObject[i].name}/${req.originalUrl}`);
if (fileObject[i].files.some(f => path.relative(f, file) === "")) {
const extension = file.substring(file.lastIndexOf("."));
res.setHeader("Cache-Control", "max-age=31536000, immutable");
res.setHeader("Content-Type", mimeTypes[extension]);
res.writeHead(200);
res.write(fs.readFileSync(path.join(process.cwd(), "/" + fileObject[i].name + req.originalUrl)));
res.end();
break;
}
}
next();
});
};
}
+7
View File
@@ -1,10 +1,13 @@
/// <reference types='vitest' />
import { defineConfig } from "vite";
import { nxViteTsPaths } from "@nx/vite/plugins/nx-tsconfig-paths.plugin";
import wasm from "vite-plugin-wasm";
import topLevelAwait from "vite-plugin-top-level-await";
import mergeAssetsDirs from "./vite-plugins/multiple-assets";
export default defineConfig({
cacheDir: "../node_modules/.vite/hello-web",
server:{
@@ -19,5 +22,9 @@ export default defineConfig({
nxViteTsPaths(),
wasm(),
topLevelAwait(),
mergeAssetsDirs([
"hello-web/public",
"dist/hello-world/public",
]),
],
});
+6 -2
View File
@@ -18,9 +18,13 @@
"build:web": {
"executor": "nx:run-commands",
"options": {
"command": "wasm-pack build --out-dir ../dist/hello-world/ -- --features wasm",
"commands": [
"wasm-pack build --out-dir ../dist/hello-world/ -- --features wasm",
"node scripts/copy-assets.mjs"
],
"cwd": "hello-world",
"env": "hello-world/.env"
"envFile": "hello-world/.env",
"parallel": false
}
},
"run": {
+13
View File
@@ -0,0 +1,13 @@
import { promises as fs } from "node:fs";
import path from "node:path";
import url from "node:url";
async function main() {
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
const assetsSrc = path.resolve(__dirname, "../assets");
const assetsDest = path.resolve(__dirname, "../../dist/hello-world/public/assets");
await fs.cp(assetsSrc, assetsDest, { recursive: true });
}
main();