195 lines
6.4 KiB
JavaScript
195 lines
6.4 KiB
JavaScript
import { prependForwardSlash } from "@astrojs/internal-helpers/path";
|
|
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";
|
|
import { wrapId } from "../core/util.js";
|
|
import { inlineRE, isBuildableCSSRequest, rawRE } from "../vite-plugin-astro-server/util.js";
|
|
import { getVirtualModulePageNameForComponent } from "../vite-plugin-pages/util.js";
|
|
import { getDevCSSModuleName } from "./util.js";
|
|
import { CSS_LANGS_RE } from "../core/viteUtils.js";
|
|
import { PROPAGATED_ASSET_QUERY_PARAM } from "../content/consts.js";
|
|
import {
|
|
ASTRO_CSS_EXTENSION_POST_PATTERN,
|
|
MODULE_DEV_CSS,
|
|
MODULE_DEV_CSS_ALL,
|
|
MODULE_DEV_CSS_PREFIX,
|
|
RESOLVED_MODULE_DEV_CSS,
|
|
RESOLVED_MODULE_DEV_CSS_ALL,
|
|
RESOLVED_MODULE_DEV_CSS_PREFIX
|
|
} from "./const.js";
|
|
function getComponentFromVirtualModuleCssName(virtualModulePrefix, id) {
|
|
return id.slice(virtualModulePrefix.length).replace(new RegExp(ASTRO_CSS_EXTENSION_POST_PATTERN, "g"), ".");
|
|
}
|
|
async function ensureModulesLoaded(env, mod, seen = /* @__PURE__ */ new Set()) {
|
|
const id = mod.id ?? mod.url;
|
|
if (seen.has(id)) return;
|
|
seen.add(id);
|
|
for (const imp of mod.importedModules) {
|
|
if (!imp.id) continue;
|
|
if (seen.has(imp.id)) continue;
|
|
if (imp.id.includes(PROPAGATED_ASSET_QUERY_PARAM)) continue;
|
|
if (imp.id === RESOLVED_MODULE_DEV_CSS || imp.id === RESOLVED_MODULE_DEV_CSS_ALL || imp.id.startsWith(RESOLVED_MODULE_DEV_CSS_PREFIX))
|
|
continue;
|
|
if (!imp.transformResult) {
|
|
try {
|
|
await env.fetchModule(imp.id);
|
|
} catch {
|
|
}
|
|
}
|
|
await ensureModulesLoaded(env, imp, seen);
|
|
}
|
|
}
|
|
function* collectCSSWithOrder(id, mod, seen = /* @__PURE__ */ new Set()) {
|
|
seen.add(id);
|
|
if (id.includes(PROPAGATED_ASSET_QUERY_PARAM)) {
|
|
return;
|
|
}
|
|
const imported = Array.from(mod.importedModules);
|
|
if (isBuildableCSSRequest(id)) {
|
|
yield {
|
|
id: wrapId(mod.id ?? mod.url),
|
|
idKey: id,
|
|
content: "",
|
|
url: prependForwardSlash(wrapId(mod.url))
|
|
};
|
|
return;
|
|
} else if (id.endsWith("?raw")) {
|
|
return;
|
|
}
|
|
for (const imp of imported) {
|
|
if (imp.id && !seen.has(imp?.id)) {
|
|
yield* collectCSSWithOrder(imp.id, imp, seen);
|
|
}
|
|
}
|
|
}
|
|
function astroDevCssPlugin({ routesList, command }) {
|
|
let server;
|
|
const cssContentCache = /* @__PURE__ */ new Map();
|
|
function getCurrentEnvironment(pluginEnv) {
|
|
return pluginEnv ?? server?.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr];
|
|
}
|
|
return [
|
|
{
|
|
name: MODULE_DEV_CSS,
|
|
async configureServer(viteServer) {
|
|
server = viteServer;
|
|
},
|
|
applyToEnvironment(env) {
|
|
return env.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr || env.name === ASTRO_VITE_ENVIRONMENT_NAMES.client || env.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender;
|
|
},
|
|
resolveId: {
|
|
filter: {
|
|
id: new RegExp(`^(${MODULE_DEV_CSS}|${MODULE_DEV_CSS_PREFIX}.*)$`)
|
|
},
|
|
handler(id) {
|
|
if (id === MODULE_DEV_CSS) {
|
|
return RESOLVED_MODULE_DEV_CSS;
|
|
}
|
|
return RESOLVED_MODULE_DEV_CSS_PREFIX + id.slice(MODULE_DEV_CSS_PREFIX.length);
|
|
}
|
|
},
|
|
load: {
|
|
filter: {
|
|
id: new RegExp(`^(${RESOLVED_MODULE_DEV_CSS}|${RESOLVED_MODULE_DEV_CSS_PREFIX}.*)$`)
|
|
},
|
|
async handler(id) {
|
|
if (id === RESOLVED_MODULE_DEV_CSS) {
|
|
return {
|
|
code: `export const css = new Set()`
|
|
};
|
|
}
|
|
if (id.startsWith(RESOLVED_MODULE_DEV_CSS_PREFIX)) {
|
|
const componentPath = getComponentFromVirtualModuleCssName(
|
|
RESOLVED_MODULE_DEV_CSS_PREFIX,
|
|
id
|
|
);
|
|
const cssWithOrder = /* @__PURE__ */ new Map();
|
|
const componentPageId = getVirtualModulePageNameForComponent(componentPath);
|
|
const env = getCurrentEnvironment(this.environment);
|
|
await env?.fetchModule(componentPageId);
|
|
const resolved = await env?.pluginContainer.resolveId(componentPageId);
|
|
if (!resolved?.id) {
|
|
return {
|
|
code: "export const css = new Set()"
|
|
};
|
|
}
|
|
const mod = env?.moduleGraph.getModuleById(resolved.id);
|
|
if (!mod) {
|
|
return {
|
|
code: "export const css = new Set()"
|
|
};
|
|
}
|
|
if (env) {
|
|
await ensureModulesLoaded(env, mod);
|
|
}
|
|
for (const collected of collectCSSWithOrder(componentPageId, mod)) {
|
|
if (!cssWithOrder.has(collected.idKey)) {
|
|
const content = cssContentCache.get(collected.id) || collected.content;
|
|
cssWithOrder.set(collected.idKey, { ...collected, content });
|
|
}
|
|
}
|
|
const cssArray = Array.from(cssWithOrder.values());
|
|
const cleanedCss = cssArray.map(({ content, id: cssId, url }) => ({
|
|
content,
|
|
id: cssId,
|
|
url
|
|
}));
|
|
return {
|
|
code: `export const css = new Set(${JSON.stringify(cleanedCss)})`
|
|
};
|
|
}
|
|
}
|
|
},
|
|
transform: {
|
|
filter: {
|
|
id: {
|
|
include: [CSS_LANGS_RE],
|
|
exclude: [rawRE, inlineRE]
|
|
}
|
|
},
|
|
handler(code, id) {
|
|
if (command === "build") {
|
|
return;
|
|
}
|
|
const env = getCurrentEnvironment(this.environment);
|
|
const mod = env?.moduleGraph.getModuleById(id);
|
|
if (mod) {
|
|
cssContentCache.set(id, code);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
name: MODULE_DEV_CSS_ALL,
|
|
applyToEnvironment(env) {
|
|
return env.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr || env.name === ASTRO_VITE_ENVIRONMENT_NAMES.client || env.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender;
|
|
},
|
|
resolveId: {
|
|
filter: {
|
|
id: new RegExp(`^${MODULE_DEV_CSS_ALL}$`)
|
|
},
|
|
handler() {
|
|
return RESOLVED_MODULE_DEV_CSS_ALL;
|
|
}
|
|
},
|
|
load: {
|
|
filter: {
|
|
id: new RegExp(`^${RESOLVED_MODULE_DEV_CSS_ALL}$`)
|
|
},
|
|
handler() {
|
|
let code = `export const devCSSMap = new Map([`;
|
|
for (const route of routesList.routes) {
|
|
code += `
|
|
[${JSON.stringify(route.component)}, () => import(${JSON.stringify(getDevCSSModuleName(route.component))})],`;
|
|
}
|
|
code += "]);";
|
|
return {
|
|
code
|
|
};
|
|
}
|
|
}
|
|
}
|
|
];
|
|
}
|
|
export {
|
|
astroDevCssPlugin
|
|
};
|