diff options
Diffstat (limited to 'packages/integrations')
-rw-r--r-- | packages/integrations/mdx/src/index.ts | 4 | ||||
-rw-r--r-- | packages/integrations/preact/package.json | 5 | ||||
-rw-r--r-- | packages/integrations/preact/src/index.ts | 122 | ||||
-rw-r--r-- | packages/integrations/preact/src/server.ts | 4 | ||||
-rw-r--r-- | packages/integrations/react/package.json | 4 | ||||
-rw-r--r-- | packages/integrations/react/src/index.ts | 44 | ||||
-rw-r--r-- | packages/integrations/solid/package.json | 3 | ||||
-rw-r--r-- | packages/integrations/solid/src/dependencies.ts | 27 | ||||
-rw-r--r-- | packages/integrations/solid/src/index.ts | 79 |
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), + }); }, }, }; |