vite-plugin-runtime
Version:
Vite plugin that enables configuring runtime environment variables when building
110 lines (108 loc) • 4.1 kB
JavaScript
import b from "path";
import g from "dotenv";
import c from "fs";
import N from "prettier";
const d = (e) => e.name ? typeof e.name == "string" ? e.name : e.name() : "env", x = (e) => {
if (e.generatedTypesPath)
return typeof e.generatedTypesPath == "string" ? e.generatedTypesPath : e.generatedTypesPath();
}, E = (e) => typeof e == "number" && !Number.isNaN(e) ? !0 : typeof e != "string" ? !1 : !Number.isNaN(Number(e)) && !Number.isNaN(Number.parseFloat(e)), j = (e) => typeof e == "boolean" ? !0 : typeof e != "string" ? !1 : !!["true", "1", "yes", "on", "false", "0", "no", "off"].includes(e.trim().toLowerCase()), y = (e) => E(e) ? "number" : j(e) ? "boolean" : typeof e, $ = (e, i) => ["MODE", "BASE_URL", "PROD", "DEV", "SSR"].includes(e) ? !0 : i.some((o) => e.startsWith(o)), I = (e = { injectHtml: !0 }) => {
let i = {}, s, o, u;
const h = /(?:[$_\p{ID_Start}])(?:[$\u200C\u200D\p{ID_Continue}])*/u;
return {
name: "vite-plugin-runtime-env",
configResolved(t) {
s = t;
let r = s.envPrefix ?? ["VITE_"];
typeof r == "string" && (r = [r]), u = r, o = { ...e, ...s.runtimeEnv };
},
buildStart() {
const t = b.resolve(s.root, s.envDir, ".env");
c.existsSync(t) && (i = { ...i, ...g.parse(c.readFileSync(t)) });
const r = b.resolve(s.root, s.envDir, `.env.${s.mode}`);
if (c.existsSync(r) && (i = { ...i, ...g.parse(c.readFileSync(r)) }), Object.keys(i).forEach((m) => {
$(m, u) && delete i[m];
}), o.generateTypes && s.command === "serve") {
const m = x(o) ?? s.root, n = d(o), l = b.resolve(m, `${n}.d.ts`), v = n === "env" ? "ImportMetaEnv" : "ImportMetaRuntimeEnv";
let f = `/// <reference types="vite/client" />
/** generated by vite-plugin-runtime */
interface ${v} {`;
Object.entries(i).forEach((p) => {
f += `readonly ${p[0]}: ${y(p[1])};`;
}), f += `} interface ImportMeta {readonly ${n}: ${v};}`, N.format(f, {
semi: !0,
singleQuote: !0,
arrowParens: "avoid",
tabWidth: 2,
useTabs: !1,
printWidth: 100,
parser: "typescript"
}).then((p) => c.writeFileSync(l, p));
}
},
transform(t) {
const r = "window", a = d(o), m = new RegExp(`(import\\.meta\\.${a})(.+)`, "g");
for (let n = m.exec(t); n !== null; n = m.exec(t)) {
const l = h.exec(n[2]);
if (l === null)
continue;
const v = l[0];
if ($(v, u))
continue;
const f = n.index, p = f + n[1].length;
t = t.slice(0, f) + `${r}.${a}` + t.slice(p);
}
return t;
},
transformIndexHtml() {
if (o.injectHtml !== !0)
return;
const t = "window", r = d(o);
let a;
return s.command === "serve" ? a = `${t}.${r} = {...${t}.${r}, ...${JSON.stringify(i)}};` : a = `import rtenv from '/${r}.js'; ${t}.${r} = {...${t}.${r}, ...rtenv};`, [
{
tag: "script",
attrs: {
type: "module"
},
children: a,
injectTo: "head-prepend"
}
];
},
generateBundle() {
const t = d(o), r = {}, a = {};
Object.entries(i).forEach((n) => {
const l = y(n[1]);
r[n[0]] = l === "number" ? Number(n[1]) : l === "boolean" ? !!n[1] : n[1], o.envsubstTemplate === !0 && (a[n[0]] = `$${n[0]}`);
});
const m = `export default ${JSON.stringify(r)} ;`;
if (this.emitFile({
type: "asset",
fileName: `${t}.js`,
source: m
}), o.envsubstTemplate === !0) {
const n = `export default ${JSON.stringify(a)} ;`;
this.emitFile({
type: "asset",
fileName: `${t}.template.js`,
source: n
});
}
}
};
}, _ = (e) => {
let i, s;
return {
name: "vite-plugin-runtime-html",
configResolved(o) {
i = o, s = { ...e, ...i.runtimeHtml };
},
transformIndexHtml() {
return (s[i.mode] ?? []).map((u) => typeof u == "function" ? u() : u);
}
};
};
export {
I as runtimeEnv,
_ as runtimeHtml
};