summaryrefslogtreecommitdiff
path: root/packages/integrations
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations')
-rw-r--r--packages/integrations/mdx/src/index.ts4
-rw-r--r--packages/integrations/preact/package.json5
-rw-r--r--packages/integrations/preact/src/index.ts122
-rw-r--r--packages/integrations/preact/src/server.ts4
-rw-r--r--packages/integrations/react/package.json4
-rw-r--r--packages/integrations/react/src/index.ts44
-rw-r--r--packages/integrations/solid/package.json3
-rw-r--r--packages/integrations/solid/src/dependencies.ts27
-rw-r--r--packages/integrations/solid/src/index.ts79
9 files changed, 115 insertions, 177 deletions
diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts
index ecf2a9a95..4cce23921 100644
--- a/packages/integrations/mdx/src/index.ts
+++ b/packages/integrations/mdx/src/index.ts
@@ -13,6 +13,7 @@ import type { Plugin as VitePlugin } from 'vite';
import { getRehypePlugins, getRemarkPlugins, recmaInjectImportMetaEnvPlugin } from './plugins.js';
import type { OptimizeOptions } from './rehype-optimize-static.js';
import { getFileInfo, ignoreStringPlugins, parseFrontmatter } from './utils.js';
+import astroJSXRenderer from 'astro/jsx/renderer.js';
export type MdxOptions = Omit<typeof markdownConfigDefaults, 'remarkPlugins' | 'rehypePlugins'> & {
extendMarkdownConfig: boolean;
@@ -37,9 +38,10 @@ export default function mdx(partialMdxOptions: Partial<MdxOptions> = {}): AstroI
name: '@astrojs/mdx',
hooks: {
'astro:config:setup': async (params) => {
- const { updateConfig, config, addPageExtension, addContentEntryType, command } =
+ const { updateConfig, config, addPageExtension, addContentEntryType, command, addRenderer } =
params as SetupHookParams;
+ addRenderer(astroJSXRenderer);
addPageExtension('.mdx');
addContentEntryType({
extensions: ['.mdx'],
diff --git a/packages/integrations/preact/package.json b/packages/integrations/preact/package.json
index f1a5f08f4..5fefa53eb 100644
--- a/packages/integrations/preact/package.json
+++ b/packages/integrations/preact/package.json
@@ -35,10 +35,11 @@
"dev": "astro-scripts dev \"src/**/*.ts\""
},
"dependencies": {
- "@babel/core": "^7.22.5",
"@babel/plugin-transform-react-jsx": "^7.22.5",
+ "@babel/plugin-transform-react-jsx-development": "^7.22.5",
+ "babel-plugin-transform-hook-names": "^1.0.2",
+ "@preact/preset-vite": "^2.5.0",
"@preact/signals": "^1.1.3",
- "babel-plugin-module-resolver": "^5.0.0",
"preact-render-to-string": "^5.2.6"
},
"devDependencies": {
diff --git a/packages/integrations/preact/src/index.ts b/packages/integrations/preact/src/index.ts
index 98a2dd205..153b9e1c3 100644
--- a/packages/integrations/preact/src/index.ts
+++ b/packages/integrations/preact/src/index.ts
@@ -1,94 +1,68 @@
import type { AstroIntegration, AstroRenderer, ViteUserConfig } from 'astro';
+import preact, {type PreactPluginOptions as VitePreactPluginOptions} from '@preact/preset-vite';
+import { fileURLToPath } from 'node:url';
+
+const babelCwd = new URL('../', import.meta.url);
function getRenderer(development: boolean): AstroRenderer {
return {
name: '@astrojs/preact',
clientEntrypoint: development ? '@astrojs/preact/client-dev.js' : '@astrojs/preact/client.js',
serverEntrypoint: '@astrojs/preact/server.js',
- jsxImportSource: 'preact',
- jsxTransformOptions: async () => {
- // @ts-expect-error types not found
- const plugin = await import('@babel/plugin-transform-react-jsx');
- const jsx = plugin.default?.default ?? plugin.default;
- return {
- plugins: [jsx({}, { runtime: 'automatic', importSource: 'preact' })],
- };
- },
};
}
-function getCompatRenderer(development: boolean): AstroRenderer {
+export type Options =Pick<VitePreactPluginOptions, 'include' | 'exclude'> & { compat?: boolean };
+
+export default function ({include, exclude, compat}: Options = {}): AstroIntegration {
return {
name: '@astrojs/preact',
- clientEntrypoint: development ? '@astrojs/preact/client-dev.js' : '@astrojs/preact/client.js',
- serverEntrypoint: '@astrojs/preact/server.js',
- jsxImportSource: 'react',
- jsxTransformOptions: async () => {
- // @ts-expect-error types not found
- const plugin = await import('@babel/plugin-transform-react-jsx');
- const jsx = plugin.default?.default ?? plugin.default;
- return {
- plugins: [
- jsx({}, { runtime: 'automatic', importSource: 'preact/compat' }),
- [
- 'babel-plugin-module-resolver',
- {
- alias: {
- react: 'preact/compat',
- 'react-dom/test-utils': 'preact/test-utils',
- 'react-dom': 'preact/compat',
- 'react/jsx-runtime': 'preact/jsx-runtime',
- },
- },
- ],
- ],
- };
- },
- };
-}
+ hooks: {
+ 'astro:config:setup': ({ addRenderer, updateConfig, command }) => {
+ const preactPlugin = preact({
+ include,
+ exclude,
+ babel: {
+ cwd: fileURLToPath(babelCwd)
+ }
+ });
-function getViteConfiguration(compat?: boolean): ViteUserConfig {
- const viteConfig: ViteUserConfig = {
- optimizeDeps: {
- include: ['@astrojs/preact/client.js', 'preact', 'preact/jsx-runtime'],
- exclude: ['@astrojs/preact/server.js'],
- },
- };
+ const viteConfig: ViteUserConfig = {
+ optimizeDeps: {
+ include: ['@astrojs/preact/client.js', 'preact', 'preact/jsx-runtime'],
+ exclude: ['@astrojs/preact/server.js'],
+ },
+ };
- if (compat) {
- viteConfig.optimizeDeps!.include!.push(
- 'preact/compat',
- 'preact/test-utils',
- 'preact/compat/jsx-runtime'
- );
- viteConfig.resolve = {
- alias: [
- { find: 'react', replacement: 'preact/compat' },
- { find: 'react-dom/test-utils', replacement: 'preact/test-utils' },
- { find: 'react-dom', replacement: 'preact/compat' },
- { find: 'react/jsx-runtime', replacement: 'preact/jsx-runtime' },
- ],
- dedupe: ['preact/compat', 'preact'],
- };
- // noExternal React entrypoints to be bundled, resolved, and aliased by Vite
- viteConfig.ssr = {
- noExternal: ['react', 'react-dom', 'react-dom/test-utils', 'react/jsx-runtime'],
- };
- }
+ // If not compat, delete the plugin that does it
+ if(!compat) {
+ const pIndex = preactPlugin.findIndex(p => p.name == 'preact:config');
+ if (pIndex >= 0) {
+ preactPlugin.splice(pIndex, 1);
+ }
+ } else {
+ viteConfig.optimizeDeps!.include!.push(
+ 'preact/compat',
+ 'preact/test-utils',
+ 'preact/compat/jsx-runtime',
+ );
+ viteConfig.resolve = {
+ alias: [
+ { find: 'react/jsx-runtime', replacement: 'preact/jsx-runtime' },
+ ],
+ dedupe: ['preact/compat', 'preact'],
+ };
+ // noExternal React entrypoints to be bundled, resolved, and aliased by Vite
+ viteConfig.ssr = {
+ noExternal: ['react', 'react-dom', 'react-dom/test-utils', 'react/jsx-runtime'],
+ };
+ }
- return viteConfig;
-}
+ viteConfig.plugins = [preactPlugin];
-export default function ({ compat }: { compat?: boolean } = {}): AstroIntegration {
- return {
- name: '@astrojs/preact',
- hooks: {
- 'astro:config:setup': ({ addRenderer, updateConfig, command }) => {
- const development = command === 'dev';
- if (compat) addRenderer(getCompatRenderer(development));
- addRenderer(getRenderer(development));
+ addRenderer(getRenderer(command === 'dev'));
updateConfig({
- vite: getViteConfiguration(compat),
+ vite: viteConfig,
});
},
},
diff --git a/packages/integrations/preact/src/server.ts b/packages/integrations/preact/src/server.ts
index 6a2ceb612..b9d063b62 100644
--- a/packages/integrations/preact/src/server.ts
+++ b/packages/integrations/preact/src/server.ts
@@ -29,8 +29,8 @@ function check(this: RendererContext, Component: any, props: Record<string, any>
// There are edge cases (SolidJS) where Preact *might* render a string,
// but components would be <undefined></undefined>
-
- return !/\<undefined\>/.test(html);
+ // It also might render an empty sting.
+ return html == '' ? false : !/\<undefined\>/.test(html);
} catch (err) {
return false;
}
diff --git a/packages/integrations/react/package.json b/packages/integrations/react/package.json
index 958ee5ed7..28dbf0891 100644
--- a/packages/integrations/react/package.json
+++ b/packages/integrations/react/package.json
@@ -44,8 +44,8 @@
"dev": "astro-scripts dev \"src/**/*.ts\""
},
"dependencies": {
- "@babel/core": "^7.22.5",
- "@babel/plugin-transform-react-jsx": "^7.22.5"
+ "@astrojs/internal-helpers": "0.2.0-beta.0",
+ "@vitejs/plugin-react": "^4.0.3"
},
"devDependencies": {
"@types/react": "^17.0.62",
diff --git a/packages/integrations/react/src/index.ts b/packages/integrations/react/src/index.ts
index d7906fe4a..da008a670 100644
--- a/packages/integrations/react/src/index.ts
+++ b/packages/integrations/react/src/index.ts
@@ -1,5 +1,10 @@
import type { AstroIntegration } from 'astro';
import { version as ReactVersion } from 'react-dom';
+import react, {type Options as ViteReactPluginOptions} from '@vitejs/plugin-react';
+import { appendForwardSlash } from '@astrojs/internal-helpers/path';
+
+
+const FAST_REFRESH_PREAMBLE = react.preambleCode;
function getRenderer() {
return {
@@ -10,33 +15,10 @@ function getRenderer() {
serverEntrypoint: ReactVersion.startsWith('18.')
? '@astrojs/react/server.js'
: '@astrojs/react/server-v17.js',
- jsxImportSource: 'react',
- jsxTransformOptions: async () => {
- // @ts-expect-error types not found
- const babelPluginTransformReactJsxModule = await import('@babel/plugin-transform-react-jsx');
- const jsx =
- babelPluginTransformReactJsxModule?.default?.default ??
- babelPluginTransformReactJsxModule?.default;
- return {
- plugins: [
- jsx(
- {},
- {
- runtime: 'automatic',
- // This option tells the JSX transform how to construct the "*/jsx-runtime" import.
- // In React v17, we had to shim this due to an export map issue in React.
- // In React v18, this issue was fixed and we can import "react/jsx-runtime" directly.
- // See `./jsx-runtime.js` for more details.
- importSource: ReactVersion.startsWith('18.') ? 'react' : '@astrojs/react',
- }
- ),
- ],
- };
- },
};
}
-function getViteConfiguration() {
+function getViteConfiguration({include, exclude}: Options = {}) {
return {
optimizeDeps: {
include: [
@@ -54,8 +36,9 @@ function getViteConfiguration() {
: '@astrojs/react/server-v17.js',
],
},
+ plugins: [react({include, exclude})],
resolve: {
- dedupe: ['react', 'react-dom'],
+ dedupe: ['react', 'react-dom', 'react-dom/server'],
},
ssr: {
external: ReactVersion.startsWith('18.')
@@ -73,13 +56,18 @@ function getViteConfiguration() {
};
}
-export default function (): AstroIntegration {
+export type Options =Pick<ViteReactPluginOptions, 'include' | 'exclude'>;
+export default function ({include, exclude}: Pick<ViteReactPluginOptions, 'include' | 'exclude'> = {}): AstroIntegration {
return {
name: '@astrojs/react',
hooks: {
- 'astro:config:setup': ({ addRenderer, updateConfig }) => {
+ 'astro:config:setup': ({ config, command, addRenderer, updateConfig, injectScript }) => {
addRenderer(getRenderer());
- updateConfig({ vite: getViteConfiguration() });
+ updateConfig({ vite: getViteConfiguration({include, exclude}) });
+ if (command === 'dev') {
+ const preamble = FAST_REFRESH_PREAMBLE.replace(`__BASE__`, appendForwardSlash(config.base))
+ injectScript('before-hydration', preamble);
+ }
},
},
};
diff --git a/packages/integrations/solid/package.json b/packages/integrations/solid/package.json
index c962e025a..580545f44 100644
--- a/packages/integrations/solid/package.json
+++ b/packages/integrations/solid/package.json
@@ -35,8 +35,7 @@
"dev": "astro-scripts dev \"src/**/*.ts\""
},
"dependencies": {
- "babel-preset-solid": "^1.7.4",
- "vitefu": "^0.2.4"
+ "vite-plugin-solid": "^2.7.0"
},
"devDependencies": {
"astro": "workspace:*",
diff --git a/packages/integrations/solid/src/dependencies.ts b/packages/integrations/solid/src/dependencies.ts
deleted file mode 100644
index ac6e5c655..000000000
--- a/packages/integrations/solid/src/dependencies.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import type { AstroConfig } from 'astro';
-import { fileURLToPath } from 'node:url';
-import { crawlFrameworkPkgs } from 'vitefu';
-
-export async function getSolidPkgsConfig(isBuild: boolean, astroConfig: AstroConfig) {
- return await crawlFrameworkPkgs({
- root: fileURLToPath(astroConfig.root),
- isBuild,
- viteUserConfig: astroConfig.vite,
- isFrameworkPkgByJson(pkgJson) {
- return containsSolidField(pkgJson.exports || {});
- },
- });
-}
-
-// Reference vite-plugin-solid heuristic
-// https://github.com/solidjs/vite-plugin-solid/blob/5558486b0c63788e1275244256918f80294a8338/src/index.ts#L251-L259
-// License: MIT (https://github.com/solidjs/vite-plugin-solid/blob/5558486b0c63788e1275244256918f80294a8338/package.json#L38)
-function containsSolidField(fields: Record<string, any>) {
- const keys = Object.keys(fields);
- for (const key of keys) {
- if (key === 'solid') return true;
- if (typeof fields[key] === 'object' && fields[key] != null && containsSolidField(fields[key]))
- return true;
- }
- return false;
-}
diff --git a/packages/integrations/solid/src/index.ts b/packages/integrations/solid/src/index.ts
index cfd38224c..1385ffc21 100644
--- a/packages/integrations/solid/src/index.ts
+++ b/packages/integrations/solid/src/index.ts
@@ -1,63 +1,64 @@
-import type { AstroConfig, AstroIntegration, AstroRenderer } from 'astro';
-import { getSolidPkgsConfig } from './dependencies.js';
+import type { AstroIntegration, AstroRenderer } from 'astro';
+import solid, { type Options as ViteSolidPluginOptions } from 'vite-plugin-solid';
-function getRenderer(): AstroRenderer {
- return {
- name: '@astrojs/solid-js',
- clientEntrypoint: '@astrojs/solid-js/client.js',
- serverEntrypoint: '@astrojs/solid-js/server.js',
- jsxImportSource: 'solid-js',
- jsxTransformOptions: async ({ ssr }) => {
- // @ts-expect-error types not found
- const [{ default: solid }] = await Promise.all([import('babel-preset-solid')]);
- const options = {
- presets: [solid({}, { generate: ssr ? 'ssr' : 'dom', hydratable: true })],
- plugins: [],
- // Otherwise, babel will try to consume the source map generated by esbuild
- // This causes unexpected issues with newline characters: https://github.com/withastro/astro/issues/3371
- // Note "vite-plugin-solid" does the same: https://github.com/solidjs/vite-plugin-solid/blob/master/src/index.ts#L344-L345
- inputSourceMap: false as any,
- };
-
- return options;
- },
- };
-}
-
-async function getViteConfiguration(isDev: boolean, astroConfig: AstroConfig) {
+async function getViteConfiguration(
+ isDev: boolean,
+ { include, exclude }: Options = {},
+) {
// https://github.com/solidjs/vite-plugin-solid
// We inject the dev mode only if the user explicitly wants it or if we are in dev (serve) mode
const nestedDeps = ['solid-js', 'solid-js/web', 'solid-js/store', 'solid-js/html', 'solid-js/h'];
- const solidPkgsConfig = await getSolidPkgsConfig(!isDev, astroConfig);
return {
- /**
- * We only need esbuild on .ts or .js files.
- * .tsx & .jsx files are handled by us
- */
- esbuild: { include: /\.ts$/ },
resolve: {
conditions: ['solid', ...(isDev ? ['development'] : [])],
dedupe: nestedDeps,
alias: [{ find: /^solid-refresh$/, replacement: '/@solid-refresh' }],
},
optimizeDeps: {
- include: [...nestedDeps, ...solidPkgsConfig.optimizeDeps.include],
- exclude: ['@astrojs/solid-js/server.js', ...solidPkgsConfig.optimizeDeps.exclude],
+ include: [...nestedDeps],
+ exclude: ['@astrojs/solid-js/server.js'],
},
+ plugins: [
+ solid({ include, exclude, dev: isDev, ssr: true }),
+ {
+ name: '@astrojs/solid:config-overrides',
+ enforce: 'post',
+ config() {
+ return {
+ esbuild: {
+ // To support using alongside other JSX frameworks, still let
+ // esbuild compile stuff. Solid goes first anyways.
+ include: /\.(m?ts|[jt]sx)$/
+ },
+ }
+ },
+ }
+ ],
ssr: {
- external: ['babel-preset-solid', ...solidPkgsConfig.ssr.external],
- noExternal: [...solidPkgsConfig.ssr.noExternal],
+ external: ['babel-preset-solid'],
},
};
}
-export default function (): AstroIntegration {
+function getRenderer(): AstroRenderer {
+ return {
+ name: '@astrojs/solid-js',
+ clientEntrypoint: '@astrojs/solid-js/client.js',
+ serverEntrypoint: '@astrojs/solid-js/server.js',
+ };
+}
+
+export type Options = Pick<ViteSolidPluginOptions, 'include' | 'exclude'>;
+
+export default function (opts: Options = {}): AstroIntegration {
return {
name: '@astrojs/solid-js',
hooks: {
- 'astro:config:setup': async ({ command, addRenderer, updateConfig, config }) => {
+ 'astro:config:setup': async ({ command, addRenderer, updateConfig }) => {
addRenderer(getRenderer());
- updateConfig({ vite: await getViteConfiguration(command === 'dev', config) });
+ updateConfig({
+ vite: await getViteConfiguration(command === 'dev', opts),
+ });
},
},
};