-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvite.config.js
More file actions
71 lines (69 loc) · 3.05 KB
/
Copy pathvite.config.js
File metadata and controls
71 lines (69 loc) · 3.05 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
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { essMockPlugin } from "./dev/mock/plugin.js";
// The shipped artifact is a browser-extension *content script*, which cannot be
// an ES module — it must be a single classic IIFE. So we build in library mode
// with formats:['iife'], entry src/main.js → dist/roster.js. content.js and
// background.js stay vanilla and are copied into dist/ by build/copy-static.js.
//
// CSS isolation: in the extension the app is a full-screen overlay dropped onto
// the ESS page, so its styles must not leak either way. We mount into a Shadow
// DOM (see src/main.js) and inject the bundle's CSS as a string. `inlineCss`
// pulls the emitted stylesheet out of the bundle and hands it to the runtime as
// globalThis.__ROSTER_CSS__. In `vite dev` there's no host page (we run the
// standalone dev/index.html), so main.js skips the shadow root and lets the Vue
// plugin hot-inject styles into <head> as usual — keeping HMR intact.
function inlineCss() {
let css = "";
return {
name: "roster-inline-css",
apply: "build",
// enforce:'post' + generateBundle order:'post' so this runs AFTER Vite's own
// CSS plugin has emitted the stylesheet asset — otherwise the bundle has no
// css yet and we'd inline an empty string.
enforce: "post",
generateBundle: {
order: "post",
handler(_opts, bundle) {
for (const [file, chunk] of Object.entries(bundle)) {
if (chunk.type === "asset" && file.endsWith(".css")) {
css += chunk.source;
delete bundle[file];
}
}
for (const chunk of Object.values(bundle)) {
if (chunk.type === "chunk" && chunk.isEntry) {
chunk.code =
`globalThis.__ROSTER_CSS__=${JSON.stringify(css)};\n` + chunk.code;
}
}
},
},
};
}
export default defineConfig(({ command }) => ({
// Root is the repo root: `vite dev` serves the standalone index.html here and
// can reach /src/*. In lib-build mode Vite ignores index.html and uses the
// entry below, so index.html stays a dev-only file (never copied into dist/).
// host:true binds 0.0.0.0 so the dev server is reachable from other LAN
// devices (e.g. a phone). The app fetches same-origin, so the mock still
// intercepts when the page is loaded via the machine's LAN IP.
server: { host: true },
// Vue's runtime references process.env.NODE_ENV. Vite's library mode does NOT
// inject it, and the shipped content script has no `process` — so it throws
// "process is not defined" and the bundle never sets window.NewRoster. Define
// it for the production build only; dev keeps Vue's full dev build + warnings.
define: command === "build" ? { "process.env.NODE_ENV": JSON.stringify("production") } : {},
plugins: [vue(), inlineCss(), essMockPlugin()],
build: {
cssCodeSplit: false,
outDir: "dist",
emptyOutDir: true,
lib: {
entry: "src/main.js",
formats: ["iife"],
name: "RosterExtensionApp",
fileName: () => "roster.js",
},
},
}));