-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvite.config.ts
136 lines (101 loc) · 5.22 KB
/
vite.config.ts
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
import fs from "fs/promises";
import path from "path";
import { defineConfig, type Plugin } from "vite";
import { minify } from "terser";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import tailwindcss from "@tailwindcss/vite";
import mkcert from "vite-plugin-mkcert";
const FONTS_EXTENSION_NAMES: string[] = [".ttf", ".otf"];
const IGNORE_PRELOADING_EXTENSION_NAMES: string[] = [".txt"];
const STATIC_ASSETS_FOLDER_NAME: string = "public/static";
const SOUNDS_FOLDER_NAME: string = "public/sounds";
const LIB_SRC_FOLDER_NAME: string = "lib";
const LIB_DEST_FOLDER_NAME: string = "scripts/lib";
const LIB_PATHS: Record<string, string> = {
"spine-ts/build/spine-webgl.js": "spine-webgl.min.js",
"pako/pako.js": "pako.min.js",
"upng-js/UPNG.js": "UPNG.min.js",
"eruda/eruda.js": ""
};
const nonModuleImporterPlugin = (): Plugin => ({
name: "non-module-importer",
apply: "build",
async generateBundle() {
await fs.mkdir(path.join(__dirname, "dist", LIB_DEST_FOLDER_NAME), { recursive: true });
for (const [src, dest] of Object.entries(LIB_PATHS)) {
if (!dest) return;
const input = await fs.readFile(path.join(__dirname, LIB_SRC_FOLDER_NAME, src), "utf-8");
const { code: output = "" } = await minify(input);
await fs.writeFile(path.join(__dirname, "dist", LIB_DEST_FOLDER_NAME, dest), output, "utf-8");
}
},
transformIndexHtml: async (html: string): Promise<string> => {
html = html.replace("</title>", "</title>\n");
for (const [src, dest] of Object.entries(LIB_PATHS).reverse()) {
const srcPath = path.join(LIB_SRC_FOLDER_NAME, src).replaceAll("\\", "/");
const destPath = dest ? path.join(LIB_DEST_FOLDER_NAME, dest).replaceAll("\\", "/") : "";
html = html.replace(`\n <script src="${srcPath}"></script>`, "");
if (destPath) html = html.replace("</title>", `</title>\n <script src="${destPath}" defer></script>`);
}
html = html.replace("</title>", "</title>\n");
return html.replaceAll(/\n </g, "\n <");
// not necessary, very dumb (causes large network payloads)
html = html.replace("</head>", "\n </head>");
const preloadFiles = await fs.readdir(STATIC_ASSETS_FOLDER_NAME).then((files) => files.map((file) => path.join(__dirname, STATIC_ASSETS_FOLDER_NAME, file)));
for (const srcPath of preloadFiles) {
const props = await fs.stat(srcPath);
if (props.isDirectory()) {
preloadFiles.push(...await fs.readdir(srcPath).then((files) => files.map((file) => path.join(srcPath, file))));
continue;
}
const extension = path.extname(srcPath);
if (IGNORE_PRELOADING_EXTENSION_NAMES.includes(extension)) continue;
const destPath = srcPath.replace(path.join(__dirname, "public"), "").replaceAll("\\", "/");
const type = FONTS_EXTENSION_NAMES.includes(extension) ? "font" : "image";
html = html.replace("</head>", `<link rel="preload" crossorigin="anonymous" href="${destPath}" as="${type}" type="${type}/${extension.slice(1)}">\n </head>`);
}
const preloadSoundFiles = await fs.readdir(SOUNDS_FOLDER_NAME).then((files) => files.map((file) => path.join(__dirname, SOUNDS_FOLDER_NAME, file)));
for (const srcPath of preloadSoundFiles) {
const props = await fs.stat(srcPath);
if (props.isDirectory()) {
preloadFiles.push(...await fs.readdir(srcPath).then((files) => files.map((file) => path.join(srcPath, file))));
continue;
}
const extension = path.extname(srcPath);
if (IGNORE_PRELOADING_EXTENSION_NAMES.includes(extension)) continue;
const destPath = srcPath.replace(path.join(__dirname, "public"), "").replaceAll("\\", "/");
html = html.replace("</head>", `<link rel="preload" crossorigin="anonymous" href="${destPath}" as="audio" type="audio/${extension.slice(1)}">\n </head>`);
}
html = html.replace(" </head>", "</head>");
return html.replaceAll(/\n </g, "\n <");
}
});
// https://vite.dev/config/
export default defineConfig({
server: {
https: {
cert: ".certs/cert.pem",
key: ".certs/dev.pem"
}
},
resolve: { external: ["extraction", "setup", "markdown"] },
build: {
assetsDir: ".",
sourcemap: true,
target: "ES2022",
rollupOptions: {
output: {
entryFileNames: "scripts/[name]-[hash].js",
chunkFileNames: "scripts/[name]-[hash].js",
assetFileNames: ({ names: [name] }) => `${name.endsWith(".css") ? "styles" : "assets"}/[name]-[hash][extname]`,
manualChunks: (path: string) => path.includes("node_modules") ? "vendor" : ""
},
external: (path: string) => path.includes("lib/")
}
},
plugins: [svelte({ compilerOptions: { runes: true } }), tailwindcss(), mkcert({
autoUpgrade: true,
force: true,
savePath: ".certs"
}), nonModuleImporterPlugin()]
});