Files

74 lines
2.4 KiB
TypeScript

import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig, type Plugin } from "vite";
const __dirname = dirname(fileURLToPath(import.meta.url));
/**
* Vite plugin that inlines extracted CSS into the JS entry chunk.
* Injects a <style> tag at runtime so the module is a single .js file.
*/
function inlineCssPlugin(): Plugin {
return {
name: "inline-css",
apply: "build",
enforce: "post",
generateBundle(_, bundle) {
let cssContent = "";
const cssKeys: string[] = [];
for (const [key, chunk] of Object.entries(bundle)) {
if (key.endsWith(".css") && chunk.type === "asset" && typeof chunk.source === "string") {
cssContent += chunk.source;
cssKeys.push(key);
}
}
// Remove CSS files from the bundle
for (const key of cssKeys) {
delete bundle[key];
}
// Inject CSS into the entry JS chunk
if (cssContent) {
for (const chunk of Object.values(bundle)) {
if (chunk.type === "chunk" && chunk.isEntry) {
const injection =
`(function(){` +
`var s=document.createElement("style");` +
`s.textContent=${JSON.stringify(cssContent)};` +
`document.head.appendChild(s)` +
`})();\n`;
chunk.code = injection + chunk.code;
}
}
}
},
};
}
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, "src/index.ts"),
formats: ["es"],
fileName: "user-directory-module",
},
outDir: "dist",
rollupOptions: {
/* @element-hq/element-web-module-api is type-only at runtime;
the module API object is passed via constructor, not imported. */
external: ["@element-hq/element-web-module-api"],
},
cssCodeSplit: false,
},
resolve: {
alias: {
/* React is provided globally by Element Web (window.React).
Alias to a shim so the bundle uses the host app's React. */
"react": resolve(__dirname, "src/shims/react.ts"),
},
},
plugins: [inlineCssPlugin()],
});