Replace the vite-multiple-assets dev dependency with a small custom Vite plugin (#3976)
* Replace the vite-multiple-assets dev dependency with a small custom Vite plugin * Restore exception
This commit is contained in:
parent
a3ea6ab0af
commit
203910a92f
File diff suppressed because it is too large
Load Diff
|
|
@ -52,8 +52,7 @@
|
||||||
"tar": "^7.5.12",
|
"tar": "^7.5.12",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"typescript-eslint": "^8.57.1",
|
"typescript-eslint": "^8.57.1",
|
||||||
"vite": "^8.0.1",
|
"vite": "^8.0.1"
|
||||||
"vite-multiple-assets": "2.2.6"
|
|
||||||
},
|
},
|
||||||
"homepage": "https://graphite.art",
|
"homepage": "https://graphite.art",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
import { execSync } from "child_process";
|
import { execSync } from "child_process";
|
||||||
import { readFileSync } from "fs";
|
import { copyFileSync, cpSync, existsSync, readFileSync, statSync } from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import type { PluginOption } from "vite";
|
import type { PluginOption } from "vite";
|
||||||
import { DynamicPublicDirectory as viteMultipleAssets } from "vite-multiple-assets";
|
|
||||||
|
|
||||||
const projectRootDir = path.resolve(__dirname);
|
const projectRootDir = path.resolve(__dirname);
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(({ mode }) => {
|
export default defineConfig(({ mode }) => {
|
||||||
return {
|
return {
|
||||||
plugins: plugins(mode),
|
plugins: [svelte(), staticAssets(), mode !== "native" && thirdPartyLicenses()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: [{ find: /\/..\/branding\/(.*\.svg)/, replacement: path.resolve(projectRootDir, "../branding", "$1?raw") }],
|
alias: [{ find: /\/..\/branding\/(.*\.svg)/, replacement: path.resolve(projectRootDir, "../branding", "$1?raw") }],
|
||||||
},
|
},
|
||||||
|
|
@ -22,42 +21,78 @@ export default defineConfig(({ mode }) => {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
function plugins(mode: string): PluginOption[] {
|
function staticAssets(): PluginOption {
|
||||||
const plugins = [
|
const STATIC_ASSET_DIRS: { source: string; urlPrefix: string }[] = [
|
||||||
svelte(),
|
{ source: "../demo-artwork", urlPrefix: "/demo-artwork" },
|
||||||
viteMultipleAssets(
|
{ source: "../branding/favicons", urlPrefix: "" },
|
||||||
// Additional static asset directories
|
|
||||||
[
|
|
||||||
{ input: "../demo-artwork/**", output: "demo-artwork" },
|
|
||||||
{ input: "../branding/favicons/**", output: "" },
|
|
||||||
],
|
|
||||||
// Options where we set custom MIME types
|
|
||||||
{ mimeTypes: { ".graphite": "application/json" } },
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
if (mode !== "native") {
|
// MIME types for all file extensions found in the static asset directories
|
||||||
plugins.push({
|
const MIME_TYPES: Record<string, string> = {
|
||||||
name: "third-party-licenses",
|
".graphite": "application/json",
|
||||||
buildStart() {
|
".ico": "image/x-icon",
|
||||||
try {
|
".png": "image/png",
|
||||||
execSync("cargo run -p third-party-licenses", {
|
".svg": "image/svg+xml",
|
||||||
stdio: "inherit",
|
".webmanifest": "application/manifest+json",
|
||||||
});
|
".xml": "application/xml",
|
||||||
} catch (_e) {
|
};
|
||||||
this.error("Failed to generate third-party licenses");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
generateBundle() {
|
|
||||||
const source = readFileSync(path.resolve(projectRootDir, "third-party-licenses.txt"), "utf-8");
|
|
||||||
this.emitFile({
|
|
||||||
type: "asset",
|
|
||||||
fileName: "third-party-licenses.txt",
|
|
||||||
source,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return plugins;
|
return {
|
||||||
|
name: "static-assets",
|
||||||
|
// Dev: serve files from the listed directories via middleware
|
||||||
|
configureServer(server) {
|
||||||
|
server.middlewares.use((req, res, next) => {
|
||||||
|
if (!req.url) return next();
|
||||||
|
const urlPath = decodeURIComponent(req.url.split("?")[0]);
|
||||||
|
|
||||||
|
const match = STATIC_ASSET_DIRS.find(({ source, urlPrefix }) => {
|
||||||
|
if (urlPrefix && !urlPath.startsWith(urlPrefix + "/") && urlPath !== urlPrefix) return false;
|
||||||
|
if (!urlPrefix && urlPath.startsWith("/@")) return false;
|
||||||
|
|
||||||
|
const relativePath = urlPrefix ? urlPath.slice(urlPrefix.length) : urlPath;
|
||||||
|
const filePath = path.resolve(projectRootDir, source, "." + relativePath);
|
||||||
|
|
||||||
|
const sourceDir = path.resolve(projectRootDir, source) + path.sep;
|
||||||
|
if (!filePath.startsWith(sourceDir)) return false;
|
||||||
|
|
||||||
|
return existsSync(filePath) && !statSync(filePath).isDirectory();
|
||||||
|
});
|
||||||
|
if (!match) return next();
|
||||||
|
const { source, urlPrefix } = match;
|
||||||
|
|
||||||
|
const relativePath = urlPrefix ? urlPath.slice(urlPrefix.length) : urlPath;
|
||||||
|
const filePath = path.resolve(projectRootDir, source, "." + relativePath);
|
||||||
|
const extension = path.extname(filePath).toLowerCase();
|
||||||
|
const contentType = MIME_TYPES[extension] || "application/octet-stream";
|
||||||
|
|
||||||
|
res.setHeader("Content-Type", contentType);
|
||||||
|
res.end(readFileSync(filePath));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// Build: copy the listed directories into the output
|
||||||
|
writeBundle(options) {
|
||||||
|
STATIC_ASSET_DIRS.forEach(({ source, urlPrefix }) => {
|
||||||
|
const sourceDir = path.resolve(projectRootDir, source);
|
||||||
|
const destinationDir = path.join(options.dir || "dist", urlPrefix);
|
||||||
|
|
||||||
|
if (existsSync(sourceDir)) cpSync(sourceDir, destinationDir, { recursive: true });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function thirdPartyLicenses(): PluginOption {
|
||||||
|
return {
|
||||||
|
name: "third-party-licenses",
|
||||||
|
buildStart() {
|
||||||
|
try {
|
||||||
|
execSync("cargo run -p third-party-licenses", { stdio: "inherit" });
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error("Failed to generate third-party licenses", { cause: e });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
writeBundle(options) {
|
||||||
|
copyFileSync(path.resolve(projectRootDir, "third-party-licenses.txt"), path.join(options.dir || "dist", "third-party-licenses.txt"));
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue