diff --git a/packages/astro/package.json b/packages/astro/package.json index a5da7560f..17a7de933 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -79,6 +79,7 @@ "node-fetch": "^2.6.5", "path-to-regexp": "^6.2.0", "remark-slug": "^7.0.0", + "resolve": "^1.20.0", "sass": "^1.43.3", "semver": "^7.3.5", "send": "^0.17.1", @@ -104,6 +105,7 @@ "@types/mime": "^2.0.3", "@types/mocha": "^9.0.0", "@types/node-fetch": "^2.5.12", + "@types/resolve": "^1.20.1", "@types/rimraf": "^3.0.2", "@types/send": "^0.17.1", "@types/yargs-parser": "^20.2.1", diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index dc0633f53..b35922f64 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -11,7 +11,7 @@ import astroPostprocessVitePlugin from '../vite-plugin-astro-postprocess/index.j import markdownVitePlugin from '../vite-plugin-markdown/index.js'; import jsxVitePlugin from '../vite-plugin-jsx/index.js'; import fetchVitePlugin from '../vite-plugin-fetch/index.js'; -import { getPackageJSON, parseNpmName } from './util.js'; +import { getPackageJSON, parseNpmName, resolveDependency } from './util.js'; const require = createRequire(import.meta.url); @@ -88,7 +88,7 @@ export async function createVite(inlineConfig: ViteConfigWithSSR, { astroConfig, // Add in Astro renderers, which will extend the base config for (const name of astroConfig.renderers) { try { - const { default: renderer } = await import(name); + const { default: renderer } = await import(resolveDependency(name, astroConfig)); if (!renderer) continue; // if a renderer provides viteConfig(), call it and pass in results if (renderer.viteConfig) { diff --git a/packages/astro/src/core/ssr/index.ts b/packages/astro/src/core/ssr/index.ts index 07755d79a..4407db834 100644 --- a/packages/astro/src/core/ssr/index.ts +++ b/packages/astro/src/core/ssr/index.ts @@ -8,7 +8,7 @@ import { fileURLToPath } from 'url'; import fs from 'fs'; import path from 'path'; import { renderPage, renderSlot } from '../../runtime/server/index.js'; -import { canonicalURL as getCanonicalURL, codeFrame } from '../util.js'; +import { canonicalURL as getCanonicalURL, codeFrame, resolveDependency } from '../util.js'; import { addLinkTagsToHTML, getStylesForID } from './css.js'; import { generatePaginateFunction } from './paginate.js'; import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from './routing.js'; @@ -37,14 +37,14 @@ interface SSROptions { const cache = new Map>(); // TODO: improve validation and error handling here. -async function resolveRenderer(viteServer: ViteDevServer, renderer: string) { +async function resolveRenderer(viteServer: ViteDevServer, renderer: string, astroConfig: AstroConfig) { const resolvedRenderer: any = {}; // We can dynamically import the renderer by itself because it shouldn't have // any non-standard imports, the index is just meta info. // The other entrypoints need to be loaded through Vite. const { default: { name, client, polyfills, hydrationPolyfills, server }, - } = await import(renderer); + } = await import(resolveDependency(renderer, astroConfig)); resolvedRenderer.name = name; if (client) resolvedRenderer.source = path.posix.join(renderer, client); @@ -58,11 +58,12 @@ async function resolveRenderer(viteServer: ViteDevServer, renderer: string) { return completedRenderer; } -async function resolveRenderers(viteServer: ViteDevServer, ids: string[]): Promise { +async function resolveRenderers(viteServer: ViteDevServer, astroConfig: AstroConfig): Promise { + const ids: string[] = astroConfig.renderers; const renderers = await Promise.all( ids.map((renderer) => { if (cache.has(renderer)) return cache.get(renderer)!; - let promise = resolveRenderer(viteServer, renderer); + let promise = resolveRenderer(viteServer, renderer, astroConfig); cache.set(renderer, promise); return promise; }) @@ -75,7 +76,7 @@ async function resolveRenderers(viteServer: ViteDevServer, ids: string[]): Promi export async function ssr({ astroConfig, filePath, logging, mode, origin, pathname, route, routeCache, viteServer }: SSROptions): Promise { try { // Important: This needs to happen first, in case a renderer provides polyfills. - const renderers = await resolveRenderers(viteServer, astroConfig.renderers); + const renderers = await resolveRenderers(viteServer, astroConfig); // Load the module from the Vite SSR Runtime. const mod = (await viteServer.ssrLoadModule(fileURLToPath(filePath))) as ComponentInstance; // Handle dynamic routes diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts index eeb061ae1..31d0e107e 100644 --- a/packages/astro/src/core/util.ts +++ b/packages/astro/src/core/util.ts @@ -1,6 +1,9 @@ +import type { AstroConfig } from '../@types/astro-core'; import type { ErrorPayload } from 'vite'; import fs from 'fs'; import path from 'path'; +import { fileURLToPath } from 'url'; +import resolve from 'resolve'; /** Normalize URL to its canonical form */ export function canonicalURL(url: string, base?: string): URL { @@ -71,3 +74,9 @@ export function codeFrame(src: string, loc: ErrorPayload['err']['loc']): string } return output; } + +export function resolveDependency(dep: string, astroConfig: AstroConfig) { + return resolve.sync(dep, { + basedir: fileURLToPath(astroConfig.projectRoot) + }); +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 4a8c9b7d0..5d1daad1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1975,6 +1975,11 @@ dependencies: "@types/node" "*" +"@types/resolve@^1.20.1": + version "1.20.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.1.tgz#3727e48042fda81e374f5d5cf2fa92288bf698f8" + integrity sha512-Ku5+GPFa12S3W26Uwtw+xyrtIpaZsGYHH6zxNbZlstmlvMYSZRzOwzwsXbxlVUbHyUucctSyuFtu6bNxwYomIw== + "@types/rimraf@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.2.tgz#a63d175b331748e5220ad48c901d7bbf1f44eef8"