From c825d1e374c39f0637a6a46ee3e95bc7270f4ebb Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Tue, 16 Nov 2021 11:29:00 -0500 Subject: [PATCH] Saving this experiment --- packages/astro/src/core/create-vite.ts | 2 + .../astro/src/runtime/server/hydration.ts | 2 +- packages/astro/src/runtime/server/index.ts | 1 + .../astro/src/vite-plugin-renderer/index.ts | 76 +++++++++++++++++++ .../src/components/PreactComponent.jsx | 11 +++ .../src/components/ReactComponent.jsx | 0 .../src/components/VueComponent.vue | 15 ++++ .../framework-agnostic/src/pages/index.astro | 16 ++++ .../astro/test/framework-agnostic.test.js | 17 +++++ packages/renderers/renderer-preact/server.js | 1 + 10 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 packages/astro/src/vite-plugin-renderer/index.ts create mode 100644 packages/astro/test/fixtures/framework-agnostic/src/components/PreactComponent.jsx create mode 100644 packages/astro/test/fixtures/framework-agnostic/src/components/ReactComponent.jsx create mode 100644 packages/astro/test/fixtures/framework-agnostic/src/components/VueComponent.vue create mode 100644 packages/astro/test/fixtures/framework-agnostic/src/pages/index.astro create mode 100644 packages/astro/test/framework-agnostic.test.js diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index c883333da..4a9a82664 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -10,6 +10,7 @@ import configAliasVitePlugin from '../vite-plugin-config-alias/index.js'; 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 rendererVitePlugin from '../vite-plugin-renderer/index.js'; import { resolveDependency } from './util.js'; // Some packages are just external, and that’s the way it goes. @@ -54,6 +55,7 @@ export async function createVite(inlineConfig: ViteConfigWithSSR, { astroConfig, jsxVitePlugin({ config: astroConfig, logging }), astroPostprocessVitePlugin({ config: astroConfig, devServer }), fetchVitePlugin(), + rendererVitePlugin({}), ], publicDir: fileURLToPath(astroConfig.public), root: fileURLToPath(astroConfig.projectRoot), diff --git a/packages/astro/src/runtime/server/hydration.ts b/packages/astro/src/runtime/server/hydration.ts index 4a67825a9..b074ae913 100644 --- a/packages/astro/src/runtime/server/hydration.ts +++ b/packages/astro/src/runtime/server/hydration.ts @@ -38,7 +38,7 @@ interface ExtractedProps { componentUrl: string; componentExport: { value: string }; } | null; - props: Record; + props: Record; } // Used to extract the directives, aka `client:load` information about a component. diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index 3985e7b51..2c70c1dc5 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -139,6 +139,7 @@ export async function renderComponent(result: SSRResult, displayName: string, Co if (typeof Component === 'string') { html = await renderAstroComponent(await render`<${Component}${spreadAttributes(props)}>${children}`); } else { + console.log('could not render this'); throw new Error(`Astro is unable to render ${metadata.displayName}!\nIs there a renderer to handle this type of component defined in your Astro config?`); } } else { diff --git a/packages/astro/src/vite-plugin-renderer/index.ts b/packages/astro/src/vite-plugin-renderer/index.ts new file mode 100644 index 000000000..b4b6954cb --- /dev/null +++ b/packages/astro/src/vite-plugin-renderer/index.ts @@ -0,0 +1,76 @@ +import type { TransformResult } from '@astrojs/compiler'; +import type { SourceMapInput } from 'rollup'; +import type vite from '../core/vite'; +import { pathToFileURL } from 'url'; +import type { AstroConfig } from '../@types/astro-core'; + +import esbuild from 'esbuild'; +import fs from 'fs'; +import { fileURLToPath } from 'url'; +import os from 'os'; +import { transform } from '@astrojs/compiler'; +import { decode } from 'sourcemap-codec'; +import { AstroDevServer } from '../core/dev/index.js'; + +function needsAstroLoader(id: string): URL | null { + try { + const url = new URL(`file://${id}`); + if(url.searchParams.has('astro')) { + return url; + } + } catch {} + return null; +} + + +/** Transform .astro files for Vite */ +export default function renderer({ }: any): vite.Plugin { + return { + name: '@astrojs/vite-plugin-renderer', + enforce: 'pre', // run transforms before other plugins can + /*configResolved(resolvedConfig) { + + },*/ + + resolveId(id, importer) { + if(id.startsWith('.')) { + const url = new URL(id, new URL(`file://${importer}`)); + if(url.searchParams.has('astro')) { + url.pathname += '.noop'; + // Remove file:// because Vite doesn't like it + return url.toString().substr(5); + } + } + + return null; + }, + + async load(id, opts) { + const url = needsAstroLoader(id); + if(url === null) { + return null; + } + + const renderer = url.searchParams.get('renderer'); + const rendererSpecifier = `@astrojs/renderer-${renderer}`; + console.log(rendererSpecifier) + + const source = ` + import RealComponent from '/@fs${url.pathname.substr(0, url.pathname.length - 5)}'; + import { renderComponent } from 'astro/internal'; + import { h } from 'preact'; + import d from '@astrojs/renderer-vue/server.js'; + + export default function FrameworkComponent(props) { + //return h('div', null, 'works'); + debugger; + return d.renderToStaticMarkup(RealComponent, props, null); + } + `; + + return { + code: source + } + } + }; +} diff --git a/packages/astro/test/fixtures/framework-agnostic/src/components/PreactComponent.jsx b/packages/astro/test/fixtures/framework-agnostic/src/components/PreactComponent.jsx new file mode 100644 index 000000000..19becfc89 --- /dev/null +++ b/packages/astro/test/fixtures/framework-agnostic/src/components/PreactComponent.jsx @@ -0,0 +1,11 @@ +import { h, Fragment } from 'preact'; +import VueComponent from './VueComponent.vue?astro&renderer=preact'; + +export default function() { + return ( + +
i am preact
+ +
+ ); +} \ No newline at end of file diff --git a/packages/astro/test/fixtures/framework-agnostic/src/components/ReactComponent.jsx b/packages/astro/test/fixtures/framework-agnostic/src/components/ReactComponent.jsx new file mode 100644 index 000000000..e69de29bb diff --git a/packages/astro/test/fixtures/framework-agnostic/src/components/VueComponent.vue b/packages/astro/test/fixtures/framework-agnostic/src/components/VueComponent.vue new file mode 100644 index 000000000..dcc401594 --- /dev/null +++ b/packages/astro/test/fixtures/framework-agnostic/src/components/VueComponent.vue @@ -0,0 +1,15 @@ + + + + diff --git a/packages/astro/test/fixtures/framework-agnostic/src/pages/index.astro b/packages/astro/test/fixtures/framework-agnostic/src/pages/index.astro new file mode 100644 index 000000000..8d1b4effe --- /dev/null +++ b/packages/astro/test/fixtures/framework-agnostic/src/pages/index.astro @@ -0,0 +1,16 @@ +--- +//import Test from '../components/AstroComponent.astro'; +//import JsxComponent from '../components/JsxComponent.jsx'; +//import SvelteComponent from '../components/SvelteComponent.svelte'; +//import VueComponent from '../components/VueComponent.vue'; +import PreactComponent from '../components/PreactComponent.jsx'; +--- + + + + Framework agnostic component usage + + + + + diff --git a/packages/astro/test/framework-agnostic.test.js b/packages/astro/test/framework-agnostic.test.js new file mode 100644 index 000000000..a46930726 --- /dev/null +++ b/packages/astro/test/framework-agnostic.test.js @@ -0,0 +1,17 @@ +import { expect } from 'chai'; +import cheerio from 'cheerio'; +import { loadFixture } from './test-utils.js'; + +describe('Framework Agnostic components', () => { + let fixture; + + before(async () => { + fixture = await loadFixture({ projectRoot: './fixtures/framework-agnostic/' }); + await fixture.build(); + }); + + it('works', async () => { + const html = await fixture.readFile('/index.html'); + console.log(html); + }); +}); \ No newline at end of file diff --git a/packages/renderers/renderer-preact/server.js b/packages/renderers/renderer-preact/server.js index b50468ab5..c6ea7ecad 100644 --- a/packages/renderers/renderer-preact/server.js +++ b/packages/renderers/renderer-preact/server.js @@ -20,6 +20,7 @@ function check(Component, props, children) { return !/\/.test(html); } catch (err) { + debugger; return false; } }