-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvite.config.ts
More file actions
122 lines (117 loc) · 3.9 KB
/
Copy pathvite.config.ts
File metadata and controls
122 lines (117 loc) · 3.9 KB
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
/// <reference types="vitest/config" />
import { execSync } from "node:child_process";
import { createReadStream, existsSync, statSync } from "node:fs";
import { resolve } from "node:path";
import tailwindcss from "@tailwindcss/vite";
import vue from "@vitejs/plugin-vue";
import { defineConfig, type Plugin } from "vite";
import { VitePWA } from "vite-plugin-pwa";
const buildDate = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
let buildSha = "dev";
try {
buildSha = execSync("git rev-parse --short HEAD").toString().trim();
} catch {
// not a git checkout (e.g. tarball build)
}
const port = process.env.PORT ? Number(process.env.PORT) : undefined;
/**
* Serves the developer's own gitignored sample takeout (data/Audible.zip)
* at /__sample/Audible.zip during `vite serve` only. `apply: 'serve'` means
* the middleware does not exist in builds, so real data can never ship.
*/
function sampleZipPlugin(): Plugin {
return {
name: "audiotrail:sample-zip",
apply: "serve",
configureServer(server) {
server.middlewares.use("/__sample/Audible.zip", (req, res) => {
const zipPath = resolve(import.meta.dirname, "data/Audible.zip");
if (!existsSync(zipPath)) {
res.statusCode = 404;
res.end("No sample zip at data/Audible.zip");
return;
}
res.setHeader("Content-Type", "application/zip");
res.setHeader("Content-Length", String(statSync(zipPath).size));
if (req.method === "HEAD") {
res.end();
return;
}
createReadStream(zipPath).pipe(res);
});
},
};
}
export default defineConfig({
plugins: [
vue(),
tailwindcss(),
sampleZipPlugin(),
VitePWA({
registerType: "prompt",
manifest: {
name: "Audiotrail",
short_name: "Audiotrail",
description: "Turn your Audible data takeout into a private dashboard, parsed entirely in your browser.",
theme_color: "#c96a15",
background_color: "#faf8f4",
display: "standalone",
start_url: "/",
scope: "/",
id: "audiotrail",
orientation: "natural",
},
workbox: {
// Precache only the built app shell. User-imported Audible data is never
// a network resource, so it is never cached by the service worker.
globPatterns: ["**/*.{js,css,html,svg,png,ico,woff,woff2}"],
},
pwaAssets: {
htmlPreset: "2023",
preset: {
transparent: { sizes: [64, 192, 512], favicons: [[48, "favicon.ico"]] },
maskable: { sizes: [512], padding: 0.15, resizeOptions: { background: "#c96a15" } },
apple: { sizes: [180], padding: 0.15, resizeOptions: { background: "#c96a15" } },
},
image: "public/logo.svg",
},
devOptions: {
type: "module",
},
}),
],
server: { port, strictPort: port !== undefined },
preview: { port, strictPort: port !== undefined },
resolve: {
tsconfigPaths: true,
},
define: {
__BUILD_DATE__: JSON.stringify(buildDate),
__BUILD_SHA__: JSON.stringify(buildSha),
},
build: {
// echarts is one deliberate lazy-loaded chunk shared by all chart views;
// it never blocks the upload page. ~245 kB gzip is its expected size.
chunkSizeWarningLimit: 800,
rolldownOptions: {
// Silence @vueuse/core's misplaced /* #__PURE__ */ annotation warning
onLog(level, log, handler) {
if (log.code === "INVALID_ANNOTATION" && log.id?.includes("@vueuse/core")) return;
handler(level, log);
},
output: {
codeSplitting: {
groups: [
{ name: "vue", test: /@vue|vue-router|pinia|@vueuse/, priority: 60 },
{ name: "echarts", test: /echarts|vue-echarts/, priority: 30 },
{ name: "vendor", test: /node_modules/, priority: 10 },
],
},
},
},
},
test: {
environment: "node",
include: ["src/**/*.test.ts"],
},
});