153 lines
5.3 KiB
Plaintext
153 lines
5.3 KiB
Plaintext
import { getOutputDirectory, isServerLikeOutput } from "../../prerender/utils.js";
|
|
import { BEFORE_HYDRATION_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
|
|
import { Pipeline } from "../pipeline.js";
|
|
import { routeIsFallback, routeIsRedirect } from "../redirects/helpers.js";
|
|
import { createEnvironment } from "../render/index.js";
|
|
import { createAssetLink } from "../render/ssr-element.js";
|
|
import {
|
|
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
|
getVirtualModulePageNameFromPath
|
|
} from "./plugins/plugin-pages.js";
|
|
import { RESOLVED_SPLIT_MODULE_ID } from "./plugins/plugin-ssr.js";
|
|
import { ASTRO_PAGE_EXTENSION_POST_PATTERN } from "./plugins/util.js";
|
|
import { i18nHasFallback } from "./util.js";
|
|
class BuildPipeline extends Pipeline {
|
|
#internals;
|
|
#staticBuildOptions;
|
|
#manifest;
|
|
constructor(staticBuildOptions, internals, manifest) {
|
|
const ssr = isServerLikeOutput(staticBuildOptions.settings.config);
|
|
const resolveCache = /* @__PURE__ */ new Map();
|
|
super(
|
|
createEnvironment({
|
|
adapterName: manifest.adapterName,
|
|
logger: staticBuildOptions.logger,
|
|
mode: staticBuildOptions.mode,
|
|
renderers: manifest.renderers,
|
|
clientDirectives: manifest.clientDirectives,
|
|
compressHTML: manifest.compressHTML,
|
|
async resolve(specifier) {
|
|
if (resolveCache.has(specifier)) {
|
|
return resolveCache.get(specifier);
|
|
}
|
|
const hashedFilePath = manifest.entryModules[specifier];
|
|
if (typeof hashedFilePath !== "string" || hashedFilePath === "") {
|
|
if (specifier === BEFORE_HYDRATION_SCRIPT_ID) {
|
|
resolveCache.set(specifier, "");
|
|
return "";
|
|
}
|
|
throw new Error(`Cannot find the built path for ${specifier}`);
|
|
}
|
|
const assetLink = createAssetLink(hashedFilePath, manifest.base, manifest.assetsPrefix);
|
|
resolveCache.set(specifier, assetLink);
|
|
return assetLink;
|
|
},
|
|
routeCache: staticBuildOptions.routeCache,
|
|
site: manifest.site,
|
|
ssr,
|
|
streaming: true
|
|
})
|
|
);
|
|
this.#internals = internals;
|
|
this.#staticBuildOptions = staticBuildOptions;
|
|
this.#manifest = manifest;
|
|
this.setEndpointHandler(this.#handleEndpointResult);
|
|
}
|
|
getInternals() {
|
|
return this.#internals;
|
|
}
|
|
getSettings() {
|
|
return this.#staticBuildOptions.settings;
|
|
}
|
|
getStaticBuildOptions() {
|
|
return this.#staticBuildOptions;
|
|
}
|
|
getConfig() {
|
|
return this.#staticBuildOptions.settings.config;
|
|
}
|
|
getManifest() {
|
|
return this.#manifest;
|
|
}
|
|
getLogger() {
|
|
return this.getEnvironment().logger;
|
|
}
|
|
/**
|
|
* The SSR build emits two important files:
|
|
* - dist/server/manifest.mjs
|
|
* - dist/renderers.mjs
|
|
*
|
|
* These two files, put together, will be used to generate the pages.
|
|
*
|
|
* ## Errors
|
|
*
|
|
* It will throw errors if the previous files can't be found in the file system.
|
|
*
|
|
* @param staticBuildOptions
|
|
*/
|
|
static async retrieveManifest(staticBuildOptions, internals) {
|
|
const config = staticBuildOptions.settings.config;
|
|
const baseDirectory = getOutputDirectory(config);
|
|
const manifestEntryUrl = new URL(
|
|
`${internals.manifestFileName}?time=${Date.now()}`,
|
|
baseDirectory
|
|
);
|
|
const { manifest } = await import(manifestEntryUrl.toString());
|
|
if (!manifest) {
|
|
throw new Error(
|
|
"Astro couldn't find the emitted manifest. This is an internal error, please file an issue."
|
|
);
|
|
}
|
|
const renderersEntryUrl = new URL(`renderers.mjs?time=${Date.now()}`, baseDirectory);
|
|
const renderers = await import(renderersEntryUrl.toString());
|
|
if (!renderers) {
|
|
throw new Error(
|
|
"Astro couldn't find the emitted renderers. This is an internal error, please file an issue."
|
|
);
|
|
}
|
|
return {
|
|
...manifest,
|
|
renderers: renderers.renderers
|
|
};
|
|
}
|
|
/**
|
|
* It collects the routes to generate during the build.
|
|
*
|
|
* It returns a map of page information and their relative entry point as a string.
|
|
*/
|
|
retrieveRoutesToGenerate() {
|
|
const pages = /* @__PURE__ */ new Map();
|
|
for (const [entrypoint, filePath] of this.#internals.entrySpecifierToBundleMap) {
|
|
if (entrypoint.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || entrypoint.includes(RESOLVED_SPLIT_MODULE_ID)) {
|
|
const [, pageName] = entrypoint.split(":");
|
|
const pageData = this.#internals.pagesByComponent.get(
|
|
`${pageName.replace(ASTRO_PAGE_EXTENSION_POST_PATTERN, ".")}`
|
|
);
|
|
if (!pageData) {
|
|
throw new Error(
|
|
"Build failed. Astro couldn't find the emitted page from " + pageName + " pattern"
|
|
);
|
|
}
|
|
pages.set(pageData, filePath);
|
|
}
|
|
}
|
|
for (const [path, pageData] of this.#internals.pagesByComponent.entries()) {
|
|
if (routeIsRedirect(pageData.route)) {
|
|
pages.set(pageData, path);
|
|
} else if (routeIsFallback(pageData.route) && (i18nHasFallback(this.getConfig()) || routeIsFallback(pageData.route) && pageData.route.route === "/")) {
|
|
const moduleSpecifier = getVirtualModulePageNameFromPath(path);
|
|
const filePath = this.#internals.entrySpecifierToBundleMap.get(moduleSpecifier);
|
|
if (filePath) {
|
|
pages.set(pageData, filePath);
|
|
}
|
|
}
|
|
}
|
|
return pages;
|
|
}
|
|
async #handleEndpointResult(_, response) {
|
|
return response;
|
|
}
|
|
}
|
|
export {
|
|
BuildPipeline
|
|
};
|