Support the Markdown component in SSR (#3036)

* Support the Markdown component in SSR

* Adds a changeset

* Support runtime markdown in Node.js

* Remove option from test adapter
This commit is contained in:
Matthew Phillips 2022-04-14 09:51:53 -04:00 committed by GitHub
parent 1b6cb6cfea
commit 4ac0d5d4e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 712 additions and 507 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Support runtime markdown parsing

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fixes usage of the Markdown component in SSR

View file

@ -19,7 +19,6 @@ import {
createModuleScriptElementWithSrcSet, createModuleScriptElementWithSrcSet,
} from '../render/ssr-element.js'; } from '../render/ssr-element.js';
import { prependForwardSlash } from '../path.js'; import { prependForwardSlash } from '../path.js';
import { createRequest } from '../request.js';
export class App { export class App {
#manifest: Manifest; #manifest: Manifest;

View file

@ -105,7 +105,7 @@ class AstroBuilder {
client: new URL('./client/', this.config.outDir), client: new URL('./client/', this.config.outDir),
server: new URL('./server/', this.config.outDir), server: new URL('./server/', this.config.outDir),
serverEntry: 'entry.mjs', serverEntry: 'entry.mjs',
staticMode: undefined, staticMode: undefined
}; };
await runHookBuildStart({ config: this.config, buildConfig }); await runHookBuildStart({ config: this.config, buildConfig });

View file

@ -13,6 +13,7 @@ import { BEFORE_HYDRATION_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
export const virtualModuleId = '@astrojs-ssr-virtual-entry'; export const virtualModuleId = '@astrojs-ssr-virtual-entry';
const resolvedVirtualModuleId = '\0' + virtualModuleId; const resolvedVirtualModuleId = '\0' + virtualModuleId;
const manifestReplace = '@@ASTRO_MANIFEST_REPLACE@@'; const manifestReplace = '@@ASTRO_MANIFEST_REPLACE@@';
const replaceExp = new RegExp(`['"](${manifestReplace})['"]`, 'g');
export function vitePluginSSR( export function vitePluginSSR(
buildOpts: StaticBuildOptions, buildOpts: StaticBuildOptions,
@ -64,18 +65,16 @@ if(_start in adapter) {
} }
return void 0; return void 0;
}, },
generateBundle(_opts, bundle) { generateBundle(_opts, bundle) {
const manifest = buildManifest(buildOpts, internals); const manifest = buildManifest(buildOpts, internals);
for (const [_chunkName, chunk] of Object.entries(bundle)) { for (const [_chunkName, chunk] of Object.entries(bundle)) {
if (chunk.type === 'asset') continue; if (chunk.type === 'asset') continue;
if (chunk.modules[resolvedVirtualModuleId]) { if (chunk.modules[resolvedVirtualModuleId]) {
const exp = new RegExp(`['"]${manifestReplace}['"]`);
const code = chunk.code; const code = chunk.code;
chunk.code = code.replace(exp, () => { chunk.code = code.replace(replaceExp, () => {
return JSON.stringify(manifest); return JSON.stringify(manifest);
}); })
} }
} }
}, },

View file

@ -196,7 +196,7 @@ export const AstroConfigSchema = z.object({
export async function validateConfig( export async function validateConfig(
userConfig: any, userConfig: any,
root: string, root: string,
cmd: string cmd: string,
): Promise<AstroConfig> { ): Promise<AstroConfig> {
const fileProtocolRoot = pathToFileURL(root + path.sep); const fileProtocolRoot = pathToFileURL(root + path.sep);
// Manual deprecation checks // Manual deprecation checks
@ -433,7 +433,7 @@ export async function resolveConfig(
userConfig: AstroUserConfig, userConfig: AstroUserConfig,
root: string, root: string,
flags: CLIFlags = {}, flags: CLIFlags = {},
cmd: string cmd: string,
): Promise<AstroConfig> { ): Promise<AstroConfig> {
const mergedConfig = mergeCLIFlags(userConfig, flags, cmd); const mergedConfig = mergeCLIFlags(userConfig, flags, cmd);
const validatedConfig = await validateConfig(mergedConfig, root, cmd); const validatedConfig = await validateConfig(mergedConfig, root, cmd);

View file

@ -0,0 +1,8 @@
{
"name": "@test/ssr-markdown",
"version": "0.0.0",
"private": true,
"dependencies": {
"astro": "workspace:*"
}
}

View file

@ -0,0 +1,8 @@
<html>
<head>Testing</head>
<body>
<article>
<slot />
</article>
</body>
</html>

View file

@ -0,0 +1,14 @@
---
import { Markdown } from 'astro/components';
---
<html>
<head><title>Testing</title></head>
<body>
<Markdown>
# Something
else here
</Markdown>
</body>
</html>

View file

@ -0,0 +1,9 @@
---
layout: ../layouts/Base.astro
---
# Hello world
This is some test
## Subheading

View file

@ -0,0 +1,41 @@
import { expect } from 'chai';
import { load as cheerioLoad } from 'cheerio';
import { loadFixture } from './test-utils.js';
import testAdapter from './test-adapter.js';
describe('Markdown pages in SSR', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
before(async () => {
fixture = await loadFixture({
root: './fixtures/ssr-markdown/',
experimental: {
ssr: true,
},
adapter: testAdapter(),
});
await fixture.build();
});
async function fetchHTML(path) {
const app = await fixture.loadTestAdapterApp();
const request = new Request('http://example.com' + path);
const response = await app.render(request);
const html = await response.text();
return html;
}
it('Renders markdown pages correctly', async () => {
const html = await fetchHTML('/post');
const $ = cheerioLoad(html);
expect($('#subheading').text()).to.equal('Subheading');
});
it('Renders the Markdown component correctly', async () => {
const html = await fetchHTML('/page');
const $ = cheerioLoad(html);
expect($('#something')).to.have.lengthOf(1);
});
});

View file

@ -37,7 +37,7 @@ export default function () {
serverEntrypoint: '@my-ssr', serverEntrypoint: '@my-ssr',
exports: ['manifest', 'createApp'], exports: ['manifest', 'createApp'],
}); });
}, }
}, },
}; };
} }

View file

@ -14,7 +14,7 @@ export default function createIntegration(): AstroIntegration {
hooks: { hooks: {
'astro:config:done': ({ setAdapter }) => { 'astro:config:done': ({ setAdapter }) => {
setAdapter(getAdapter()); setAdapter(getAdapter());
}, }
}, },
}; };
} }

File diff suppressed because it is too large Load diff