115 lines
3.6 KiB
JavaScript
115 lines
3.6 KiB
JavaScript
import { transform } from "esbuild";
|
|
import MagicString from "magic-string";
|
|
import { createFilter, isCSSRequest } from "vite";
|
|
const importMetaEnvOnlyRe = /\bimport\.meta\.env\b(?!\.)/;
|
|
function getReferencedPrivateKeys(source, privateEnv) {
|
|
const references = /* @__PURE__ */ new Set();
|
|
for (const key in privateEnv) {
|
|
if (source.includes(key)) {
|
|
references.add(key);
|
|
}
|
|
}
|
|
return references;
|
|
}
|
|
async function replaceDefine(code, id, define, config) {
|
|
const replacementMarkers = {};
|
|
const env = define["import.meta.env"];
|
|
if (env) {
|
|
const marker = `__astro_import_meta_env${"_".repeat(
|
|
env.length - 23
|
|
)}`;
|
|
replacementMarkers[marker] = env;
|
|
define = { ...define, "import.meta.env": marker };
|
|
}
|
|
const esbuildOptions = config.esbuild || {};
|
|
const result = await transform(code, {
|
|
loader: "js",
|
|
charset: esbuildOptions.charset ?? "utf8",
|
|
platform: "neutral",
|
|
define,
|
|
sourcefile: id,
|
|
sourcemap: config.command === "build" ? !!config.build.sourcemap : true
|
|
});
|
|
for (const marker in replacementMarkers) {
|
|
result.code = result.code.replaceAll(marker, replacementMarkers[marker]);
|
|
}
|
|
return {
|
|
code: result.code,
|
|
map: result.map || null
|
|
};
|
|
}
|
|
function importMetaEnv({ envLoader }) {
|
|
let privateEnv;
|
|
let defaultDefines;
|
|
let isDev;
|
|
let devImportMetaEnvPrepend;
|
|
let viteConfig;
|
|
const filter = createFilter(null, ["**/*.html", "**/*.htm", "**/*.json"]);
|
|
return {
|
|
name: "astro:vite-plugin-env",
|
|
config(_, { command }) {
|
|
isDev = command !== "build";
|
|
},
|
|
configResolved(resolvedConfig) {
|
|
viteConfig = resolvedConfig;
|
|
const viteDefinePluginIndex = resolvedConfig.plugins.findIndex(
|
|
(p) => p.name === "vite:define"
|
|
);
|
|
if (viteDefinePluginIndex !== -1) {
|
|
const myPluginIndex = resolvedConfig.plugins.findIndex(
|
|
(p) => p.name === "astro:vite-plugin-env"
|
|
);
|
|
if (myPluginIndex !== -1) {
|
|
const myPlugin = resolvedConfig.plugins[myPluginIndex];
|
|
resolvedConfig.plugins.splice(viteDefinePluginIndex, 0, myPlugin);
|
|
resolvedConfig.plugins.splice(myPluginIndex, 1);
|
|
}
|
|
}
|
|
},
|
|
transform(source, id, options) {
|
|
if (!options?.ssr || !source.includes("import.meta.env") || !filter(id) || isCSSRequest(id) || viteConfig.assetsInclude(id)) {
|
|
return;
|
|
}
|
|
privateEnv ??= envLoader.getPrivateEnv();
|
|
if (isDev) {
|
|
const s = new MagicString(source);
|
|
if (!devImportMetaEnvPrepend) {
|
|
devImportMetaEnvPrepend = `Object.assign(import.meta.env,{`;
|
|
for (const key in privateEnv) {
|
|
devImportMetaEnvPrepend += `${key}:${privateEnv[key]},`;
|
|
}
|
|
devImportMetaEnvPrepend += "});";
|
|
}
|
|
s.prepend(devImportMetaEnvPrepend);
|
|
return {
|
|
code: s.toString(),
|
|
map: s.generateMap({ hires: "boundary" })
|
|
};
|
|
}
|
|
if (!defaultDefines) {
|
|
defaultDefines = {};
|
|
for (const key in privateEnv) {
|
|
defaultDefines[`import.meta.env.${key}`] = privateEnv[key];
|
|
}
|
|
}
|
|
let defines = defaultDefines;
|
|
if (importMetaEnvOnlyRe.test(source)) {
|
|
const references = getReferencedPrivateKeys(source, privateEnv);
|
|
let replacement = `(Object.assign(import.meta.env,{`;
|
|
for (const key of references.values()) {
|
|
replacement += `${key}:${privateEnv[key]},`;
|
|
}
|
|
replacement += "}))";
|
|
defines = {
|
|
...defaultDefines,
|
|
"import.meta.env": replacement
|
|
};
|
|
}
|
|
return replaceDefine(source, id, defines, viteConfig);
|
|
}
|
|
};
|
|
}
|
|
export {
|
|
importMetaEnv
|
|
};
|