diff --git a/frontend/package.json b/frontend/package.json
index 6cd3351..86806fe 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -38,7 +38,6 @@
"typescript": "^5.1.6",
"uuid": "^9.0.0",
"vite": "^4.4.9",
- "vite-plugin-singlefile": "git://github.com/CoolElectronics/vite-plugin-singlefile.git",
"vite-plugin-svelte": "^3.0.1"
}
}
\ No newline at end of file
diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte
index f053ff4..fbb66c8 100644
--- a/frontend/src/App.svelte
+++ b/frontend/src/App.svelte
@@ -238,12 +238,14 @@
-
+ {#if !import.meta.env.VITE_ADRIFT_SINGLEFILE}
+
+ {/if}
diff --git a/frontend/vite-singlefile.js b/frontend/vite-singlefile.js
new file mode 100644
index 0000000..fb30d12
--- /dev/null
+++ b/frontend/vite-singlefile.js
@@ -0,0 +1,151 @@
+import micromatch from "micromatch"
+
+const defaultConfig = {
+ useRecommendedBuildConfig: true,
+ removeViteModuleLoader: false,
+ deleteInlinedFiles: true
+}
+
+export function replaceScript(
+ html,
+ scriptFilename,
+ scriptCode,
+ removeViteModuleLoader = false
+) {
+ const reScript = new RegExp(
+ ``
+ )
+ // we can't use String.prototype.replaceAll since it isn't supported in Node.JS 14
+ const preloadMarker = /"__VITE_PRELOAD__"/g
+ const newCode = scriptCode.replace(preloadMarker, "void 0")
+ const inlined = html.replace(
+ reScript,
+ (_, beforeSrc, afterSrc) =>
+ ``
+ )
+ return removeViteModuleLoader ? _removeViteModuleLoader(inlined) : inlined
+}
+
+export function replaceCss(html, scriptFilename, scriptCode) {
+ const reCss = new RegExp(`]*? href="[./]*${scriptFilename}"[^>]*?>`)
+ const inlined = html.replace(reCss, ``)
+ return inlined
+}
+
+const warnNotInlined = filename =>
+ console.warn(`WARNING: asset not inlined: ${filename}`)
+
+export function viteSingleFile({
+ useRecommendedBuildConfig = true,
+ removeViteModuleLoader = false,
+ inlinePattern = [],
+ deleteInlinedFiles = true
+} = defaultConfig) {
+ return {
+ name: "vite:singlefile",
+ config: useRecommendedBuildConfig ? _useRecommendedBuildConfig : undefined,
+ enforce: "post",
+ generateBundle: (_, bundle) => {
+ const jsExtensionTest = /\.[mc]?js$/
+ const htmlFiles = Object.keys(bundle).filter(i => i.endsWith(".html"))
+ const cssAssets = Object.keys(bundle).filter(i => i.endsWith(".css"))
+ const jsAssets = Object.keys(bundle).filter(i => jsExtensionTest.test(i))
+ const bundlesToDelete = []
+ for (const name of htmlFiles) {
+ const htmlChunk = bundle[name]
+ let replacedHtml = htmlChunk.source
+ for (const jsName of jsAssets) {
+ if (
+ !inlinePattern.length ||
+ micromatch.isMatch(jsName, inlinePattern)
+ ) {
+ const jsChunk = bundle[jsName]
+ if (jsChunk.code != null) {
+ bundlesToDelete.push(jsName)
+ replacedHtml = replaceScript(
+ replacedHtml,
+ jsChunk.fileName,
+ jsChunk.code,
+ removeViteModuleLoader
+ )
+ }
+ } else {
+ warnNotInlined(jsName)
+ }
+ }
+ for (const cssName of cssAssets) {
+ if (
+ !inlinePattern.length ||
+ micromatch.isMatch(cssName, inlinePattern)
+ ) {
+ const cssChunk = bundle[cssName]
+ bundlesToDelete.push(cssName)
+ replacedHtml = replaceCss(
+ replacedHtml,
+ cssChunk.fileName,
+ cssChunk.source
+ )
+ } else {
+ warnNotInlined(cssName)
+ }
+ }
+ htmlChunk.source = replacedHtml
+ }
+ if (deleteInlinedFiles) {
+ for (const name of bundlesToDelete) {
+ delete bundle[name]
+ }
+ }
+ for (const name of Object.keys(bundle).filter(
+ i =>
+ !jsExtensionTest.test(i) &&
+ !i.endsWith(".css") &&
+ !i.endsWith(".html")
+ )) {
+ warnNotInlined(name)
+ }
+ }
+ }
+}
+
+// Optionally remove the Vite module loader since it's no longer needed because this plugin has inlined all code.
+// This assumes that the Module Loader is (1) the FIRST function declared in the module, (2) an IIFE, (4) is within
+// a script with no unexpected attribute values, and (5) that the containing script is the first script tag that
+// matches the above criteria. Changes to the SCRIPT tag especially could break this again in the future. It should
+// work whether `minify` is enabled or not.
+// Update example:
+// https://github.com/richardtallent/vite-plugin-singlefile/issues/57#issuecomment-1263950209
+const _removeViteModuleLoader = html =>
+ html.replace(
+ /(