-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Renderer plugins #231
Renderer plugins #231
Changes from 35 commits
e6d61e5
9ebe678
b34898d
8041f64
67f65c9
096688e
56637b9
05320b6
9a37889
9c723ec
681fe05
beca181
5daee3d
f790d49
ab61569
5d9e948
0927637
f5dd000
94b0a8d
4a06f5f
d213115
8a53669
bf81f9a
b35755f
1a0b8b8
f47ec37
2f2a0f2
a6f8f3a
1f5444a
a2528a1
543fb22
a9cdc7e
fe7c92c
bc3c369
caf7252
8d584f9
40a73d0
c2c1f6b
3c27099
76009ff
9932312
9650538
7d979cc
d530d90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
'astro': minor | ||
--- | ||
|
||
**This is a breaking change** | ||
|
||
Updated the rendering pipeline for `astro` to truly support any framework. | ||
|
||
For the vast majority of use cases, `astro` should _just work_ out of the box. Astro now depends on `@astro-renderer/preact`, `@astro-renderer/react`, `@astro-renderer/svelte`, and `@astro-renderer/vue`, rather than these being built into the core library. This opens the door for anyone to contribute additional renderers for Astro to support their favorite framework, as well as the ability for users to control which renderers should be used. | ||
|
||
**Features** | ||
- Expose a pluggable interface for controlling server-side rendering and client-side hydration | ||
- Allows components from different frameworks to be nested within each other. | ||
> Note: `svelte` currently does support non-destructive hydration, so components from other frameworks cannot currently be nested inside of a Svelte component. See https://github.com/sveltejs/svelte/issues/4308. | ||
|
||
**Breaking Changes** | ||
- To improve compiler performance, improve framework support, and minimize JS payloads, any children passed to hydrated components are automatically wrapped with an `<astro-fragment>` element. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
'@astro-renderer/preact': minor | ||
'@astro-renderer/react': minor | ||
'@astro-renderer/svelte': minor | ||
'@astro-renderer/vue': minor | ||
--- | ||
|
||
Initial release |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div class="children"> | ||
<h1>Hello Astro (A)</h1> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div class="children"> | ||
<h1>Hello Astro (B)</h1> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default as A } from './A.astro'; | ||
export { default as B } from './B.astro'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
--- | ||
import ReactCounter from '../components/ReactCounter.jsx'; | ||
import PreactCounter from '../components/PreactCounter.tsx'; | ||
import { A, B as Renamed } from '../components'; | ||
import * as react from '../components/ReactCounter.jsx'; | ||
import { PreactCounter } from '../components/PreactCounter.tsx'; | ||
import VueCounter from '../components/VueCounter.vue'; | ||
import SvelteCounter from '../components/SvelteCounter.svelte'; | ||
--- | ||
|
@@ -30,22 +31,28 @@ import SvelteCounter from '../components/SvelteCounter.svelte'; | |
</head> | ||
<body> | ||
<main> | ||
<ReactCounter:load> | ||
|
||
<react.Counter:visible> | ||
<h1>Hello React!</h1> | ||
<p>What's up?</p> | ||
</ReactCounter:load> | ||
</react.Counter:visible> | ||
Comment on lines
+35
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ReactCounter -> react.Counter will not match the COMPONENT_NAME_SCANNER regexp? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with your suggestion to use a more complete RegExp that checks for validity, too. But this does actually match! |
||
|
||
<PreactCounter:load> | ||
<h1>Hello Preact!</h1> | ||
</PreactCounter:load> | ||
<PreactCounter:visible> | ||
<h1>Hello Preact!</h1> | ||
</PreactCounter:visible> | ||
|
||
<VueCounter:load> | ||
<VueCounter:visible> | ||
<h1>Hello Vue!</h1> | ||
</VueCounter:load> | ||
</VueCounter:visible> | ||
|
||
<SvelteCounter:load> | ||
<SvelteCounter:visible> | ||
<h1>Hello Svelte!</h1> | ||
</SvelteCounter:load> | ||
</SvelteCounter:visible> | ||
|
||
<A /> | ||
|
||
<Renamed /> | ||
|
||
</main> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,10 +10,12 @@ | |
"dev:vscode": "lerna run dev --scope astro-languageserver --scope astro-vscode --scope astro-parser --parallel --stream", | ||
"format": "prettier -w \"**/*.{js,jsx,ts,tsx,md,json}\"", | ||
"lint": "eslint \"packages/**/*.ts\"", | ||
"test": "lerna run test --scope astro --scope prettier-plugin-astro --scope create-astro --stream" | ||
"test": "lerna run test --scope astro --scope prettier-plugin-astro --scope create-astro --stream", | ||
"test:core": "yarn workspace astro run test" | ||
}, | ||
"workspaces": [ | ||
"packages/*", | ||
"packages/renderers/*", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we gain anything by publishing these separately (given that we are depending on them in astro anyways)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now, no. But I think it’s safer to have them be external. We might have optional renderers in the future that require a manual install, maybe. This lets us have that without changing the setup. |
||
"examples/*", | ||
"tools/*", | ||
"scripts", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,24 +31,27 @@ | |
"test": "uvu test -i fixtures -i test-utils.js" | ||
}, | ||
"dependencies": { | ||
"@astro-renderer/preact": "0.0.1", | ||
"@astro-renderer/react": "0.0.1", | ||
"@astro-renderer/svelte": "0.0.1", | ||
"@astro-renderer/vue": "0.0.1", | ||
"@babel/code-frame": "^7.12.13", | ||
"@babel/generator": "^7.13.9", | ||
"@babel/parser": "^7.13.15", | ||
"@babel/traverse": "^7.13.15", | ||
"@silvenon/remark-smartypants": "^1.0.0", | ||
"@snowpack/plugin-postcss": "^1.4.0", | ||
"@snowpack/plugin-sass": "^1.4.0", | ||
"@snowpack/plugin-svelte": "^3.7.0", | ||
"@snowpack/plugin-vue": "^2.5.0", | ||
"@vue/server-renderer": "^3.0.10", | ||
"acorn": "^7.4.0", | ||
"astring": "^1.7.4", | ||
"astro-parser": "0.11.0", | ||
"astro-prism": "0.0.2", | ||
"autoprefixer": "^10.2.5", | ||
"cheerio": "^1.0.0-rc.6", | ||
"del": "^6.0.0", | ||
"es-module-lexer": "^0.4.1", | ||
"esbuild": "^0.10.1", | ||
"estree-util-value-to-estree": "^1.2.0", | ||
"estree-walker": "^3.0.0", | ||
"fast-xml-parser": "^3.19.0", | ||
"fdir": "^5.0.0", | ||
|
@@ -68,11 +71,7 @@ | |
"picomatch": "^2.2.3", | ||
"postcss": "^8.2.15", | ||
"postcss-icss-keyframes": "^0.2.1", | ||
"preact": "^10.5.13", | ||
"preact-render-to-string": "^5.1.18", | ||
"prismjs": "^1.23.0", | ||
"react": "^17.0.1", | ||
"react-dom": "^17.0.1", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🙌🏻 |
||
"rehype-parse": "^7.0.1", | ||
"rehype-raw": "^5.1.0", | ||
"rehype-stringify": "^8.0.0", | ||
|
@@ -88,10 +87,8 @@ | |
"snowpack": "^3.5.1", | ||
"source-map-support": "^0.5.19", | ||
"string-width": "^5.0.0", | ||
"svelte": "^3.35.0", | ||
"tiny-glob": "^0.2.8", | ||
"unified": "^9.2.1", | ||
"vue": "^3.0.10", | ||
"yargs-parser": "^20.2.7" | ||
}, | ||
"devDependencies": { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,10 @@ | ||
import type { LogOptions } from '../logger'; | ||
import type { AstroConfig, RuntimeMode, ValidExtensionPlugins } from './astro'; | ||
import type { AstroConfig, RuntimeMode } from './astro'; | ||
|
||
export interface CompileOptions { | ||
logging: LogOptions; | ||
resolvePackageUrl: (p: string) => Promise<string>; | ||
astroConfig: AstroConfig; | ||
extensions?: Record<string, ValidExtensionPlugins>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No more extensions needed! |
||
mode: RuntimeMode; | ||
tailwindConfig?: string; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import fs from 'fs'; | |
import path from 'path'; | ||
import { fileURLToPath } from 'url'; | ||
import { performance } from 'perf_hooks'; | ||
import eslexer from 'es-module-lexer'; | ||
import cheerio from 'cheerio'; | ||
import del from 'del'; | ||
import { bold, green, yellow } from 'kleur/colors'; | ||
|
@@ -94,6 +95,8 @@ export async function build(astroConfig: AstroConfig): Promise<0 | 1> { | |
// after pages are built, build depTree | ||
timer.deps = performance.now(); | ||
const scanPromises: Promise<void>[] = []; | ||
|
||
await eslexer.init; | ||
for (const id of Object.keys(buildState)) { | ||
if (buildState[id].contentType !== 'text/html') continue; // only scan HTML files | ||
const pageDeps = findDeps(buildState[id].contents as string, { | ||
|
@@ -237,8 +240,16 @@ export function findDeps(html: string, { astroConfig, srcPath }: { astroConfig: | |
|
||
$('script').each((i, el) => { | ||
const src = $(el).attr('src'); | ||
if (src && !isRemote(src)) { | ||
if (src) { | ||
if (isRemote(src)) return; | ||
pageDeps.js.add(getDistPath(src, { astroConfig, srcPath })); | ||
} else { | ||
const text = $(el).html(); | ||
if (!text) return; | ||
const [imports] = eslexer.parse(text); | ||
for (const spec of imports) { | ||
if (spec.n) pageDeps.js.add(spec.n); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we may need to resolve these specifiers with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah good callout. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it’s already absolute then you don’t need to bother, but |
||
} | ||
} | ||
}); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Artisanal changelog. Very nice 💯