From 5a31433f693d40015c59db0cb85e3c345d0bfe24 Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 12 Oct 2022 17:28:08 +0800 Subject: [PATCH 1/7] Add test --- .../astro/test/fixtures/solid-component/package.json | 1 + .../fixtures/solid-component/src/pages/index.astro | 2 ++ pnpm-lock.yaml | 10 ++++++++++ 3 files changed, 13 insertions(+) diff --git a/packages/astro/test/fixtures/solid-component/package.json b/packages/astro/test/fixtures/solid-component/package.json index 6863b1978762..cf557f06d0d7 100644 --- a/packages/astro/test/fixtures/solid-component/package.json +++ b/packages/astro/test/fixtures/solid-component/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@astrojs/solid-js": "workspace:*", + "@solidjs/router": "^0.5.0", "astro": "workspace:*", "solid-js": "^1.5.6" } diff --git a/packages/astro/test/fixtures/solid-component/src/pages/index.astro b/packages/astro/test/fixtures/solid-component/src/pages/index.astro index 1f7522cedcb4..06c48e18a68d 100644 --- a/packages/astro/test/fixtures/solid-component/src/pages/index.astro +++ b/packages/astro/test/fixtures/solid-component/src/pages/index.astro @@ -1,6 +1,7 @@ --- import Hello from '../components/Hello.jsx'; import WithNewlines from '../components/WithNewlines.jsx'; +import { Router } from "@solidjs/router"; --- Solid @@ -8,6 +9,7 @@ import WithNewlines from '../components/WithNewlines.jsx';
+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 00cc78cb51dc..c4990eb94234 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2115,10 +2115,12 @@ importers: packages/astro/test/fixtures/solid-component: specifiers: '@astrojs/solid-js': workspace:* + '@solidjs/router': ^0.5.0 astro: workspace:* solid-js: ^1.5.6 dependencies: '@astrojs/solid-js': link:../../../../integrations/solid + '@solidjs/router': 0.5.0_solid-js@1.5.7 astro: link:../../.. solid-js: 1.5.7 @@ -9268,6 +9270,14 @@ packages: picomatch: 2.3.1 dev: false + /@solidjs/router/0.5.0_solid-js@1.5.7: + resolution: {integrity: sha512-rNR07l21tWWDVmCbaapggB89rEX7jlM2XChpTLqEGEnj46LzVZ8zgvjcF6NNKScByAlLpoQUkVIjB2KHpcMi+w==} + peerDependencies: + solid-js: ^1.5.3 + dependencies: + solid-js: 1.5.7 + dev: false + /@spectrum-icons/ui/3.3.3_jshkqybnlidashxgfmbz45rdaq: resolution: {integrity: sha512-KGPRQidTviIZWI1VHQCqNZ1dgPuOjXVTjr0ELih4y7+fV2r39qeukiKCs0AzePs7VUj04sZGRL+ZezKcvk/98Q==} peerDependencies: From 80009451652e4d92a4d5db194407edac650ae6d3 Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 12 Oct 2022 17:28:50 +0800 Subject: [PATCH 2/7] noExternal solid deps --- .../integrations/solid/src/dependencies.ts | 52 +++++++++++++++++++ packages/integrations/solid/src/index.ts | 9 ++-- 2 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 packages/integrations/solid/src/dependencies.ts diff --git a/packages/integrations/solid/src/dependencies.ts b/packages/integrations/solid/src/dependencies.ts new file mode 100644 index 000000000000..cf694997cf84 --- /dev/null +++ b/packages/integrations/solid/src/dependencies.ts @@ -0,0 +1,52 @@ +import fs from 'fs'; +import path from 'path'; +import { createRequire } from 'module'; +import { fileURLToPath } from 'url'; + +function containsSolidField(fields: Record) { + const keys = Object.keys(fields); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if (key === 'solid') return true; + if (typeof fields[key] === 'object' && containsSolidField(fields[key])) return true; + } + return false; +} + +export function getSolidDeps(root: URL) { + const pkgPath = path.join(fileURLToPath(root), 'package.json'); + if (!fs.existsSync(pkgPath)) { + console.log('No package.json found at project root'); + return []; + } + const require = createRequire(pkgPath); + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); + const deps = [...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.devDependencies || {})]; + const pkgs = deps.map((dep) => { + try { + return require(`${dep}/package.json`); + } catch (e) { + try { + let dir = path.dirname(require.resolve(dep)); + while (dir) { + const pkgPath = path.join(dir, 'package.json'); + if (fs.existsSync(pkgPath)) { + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); + if (pkg && pkg.name === dep) return pkg; + } + const parent = path.dirname(dir); + if (parent === dir) { + break; + } + dir = parent; + } + } catch (e) { + console.log("Couldn't find package.json for", dep, e); + } + } + }); + return deps.reduce((acc, dep, i) => { + if (pkgs[i] && pkgs[i].exports && containsSolidField(pkgs[i].exports)) acc.push(dep); + return acc; + }, []); +} diff --git a/packages/integrations/solid/src/index.ts b/packages/integrations/solid/src/index.ts index 20df48297b3f..5241141a92c1 100644 --- a/packages/integrations/solid/src/index.ts +++ b/packages/integrations/solid/src/index.ts @@ -1,4 +1,5 @@ import type { AstroIntegration, AstroRenderer } from 'astro'; +import { getSolidDeps } from './dependencies.js'; function getRenderer(): AstroRenderer { return { @@ -23,7 +24,7 @@ function getRenderer(): AstroRenderer { }; } -function getViteConfiguration(isDev: boolean) { +function getViteConfiguration(isDev: boolean, root: URL) { // https://github.com/solidjs/vite-plugin-solid // We inject the dev mode only if the user explicitely 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']; @@ -45,7 +46,7 @@ function getViteConfiguration(isDev: boolean) { ssr: { external: ['babel-preset-solid'], target: 'node', - noExternal: ['solid-js'], + noExternal: ['solid-js', ...getSolidDeps(root)], }, }; } @@ -54,9 +55,9 @@ export default function (): AstroIntegration { return { name: '@astrojs/solid-js', hooks: { - 'astro:config:setup': ({ command, addRenderer, updateConfig }) => { + 'astro:config:setup': ({ command, addRenderer, updateConfig, config }) => { addRenderer(getRenderer()); - updateConfig({ vite: getViteConfiguration(command === 'dev') }); + updateConfig({ vite: getViteConfiguration(command === 'dev', config.root) }); }, }, }; From 5109b5501b078db4b92366d5f040c317596c01b6 Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 12 Oct 2022 17:48:24 +0800 Subject: [PATCH 3/7] Support strict path installation --- packages/astro/package.json | 1 + packages/astro/src/vite-plugin-jsx/index.ts | 7 ++++++- packages/astro/src/vite-plugin-jsx/tag.ts | 15 +++++++++++---- pnpm-lock.yaml | 4 ++++ 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/packages/astro/package.json b/packages/astro/package.json index f135854b196f..252a169f6ef3 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -126,6 +126,7 @@ "gray-matter": "^4.0.3", "html-entities": "^2.3.3", "html-escaper": "^3.0.3", + "import-meta-resolve": "^2.1.0", "kleur": "^4.1.4", "magic-string": "^0.25.9", "mime": "^3.0.0", diff --git a/packages/astro/src/vite-plugin-jsx/index.ts b/packages/astro/src/vite-plugin-jsx/index.ts index 5c84ec512332..357e441f6c7a 100644 --- a/packages/astro/src/vite-plugin-jsx/index.ts +++ b/packages/astro/src/vite-plugin-jsx/index.ts @@ -98,6 +98,7 @@ interface TransformJSXOptions { mode: string; renderer: AstroRenderer; ssr: boolean; + root: URL; } async function transformJSX({ @@ -106,12 +107,13 @@ async function transformJSX({ id, ssr, renderer, + root, }: TransformJSXOptions): Promise { const { jsxTransformOptions } = renderer; const options = await jsxTransformOptions!({ mode, ssr }); const plugins = [...(options.plugins || [])]; if (ssr) { - plugins.push(tagExportsPlugin({ rendererName: renderer.name })); + plugins.push(await tagExportsPlugin({ rendererName: renderer.name, root })); } const result = await babel.transformAsync(code, { presets: options.presets, @@ -204,6 +206,7 @@ export default function jsx({ settings, logging }: AstroPluginJSXOptions): Plugi renderer: astroJSXRenderer, mode, ssr, + root: settings.config.root, }); } if (defaultJSXRendererEntry && jsxRenderersIntegrationOnly.size === 1) { @@ -220,6 +223,7 @@ export default function jsx({ settings, logging }: AstroPluginJSXOptions): Plugi renderer: defaultJSXRendererEntry[1], mode, ssr, + root: settings.config.root, }); } @@ -286,6 +290,7 @@ https://docs.astro.build/en/core-concepts/framework-components/#installing-integ renderer: selectedJsxRenderer, mode, ssr, + root: settings.config.root, }); }, }; diff --git a/packages/astro/src/vite-plugin-jsx/tag.ts b/packages/astro/src/vite-plugin-jsx/tag.ts index 23e9e41a5a90..1b957b58d283 100644 --- a/packages/astro/src/vite-plugin-jsx/tag.ts +++ b/packages/astro/src/vite-plugin-jsx/tag.ts @@ -1,3 +1,5 @@ +import { fileURLToPath } from 'url'; +import { resolve as importMetaResolve } from 'import-meta-resolve'; import type { PluginObj } from '@babel/core'; import * as t from '@babel/types'; @@ -9,11 +11,16 @@ import * as t from '@babel/types'; * This plugin crawls each export in the file and "tags" each export with a given `rendererName`. * This allows us to automatically match a component to a renderer and skip the usual `check()` calls. */ -export default function tagExportsWithRenderer({ +export default async function tagExportsWithRenderer({ rendererName, + root, }: { rendererName: string; -}): PluginObj { + root: URL; +}): Promise { + const astroServerPath = fileURLToPath( + await importMetaResolve('astro/server/index.js', root.toString()) + ); return { visitor: { Program: { @@ -29,7 +36,7 @@ export default function tagExportsWithRenderer({ t.identifier('__astro_tag_component__') ), ], - t.stringLiteral('astro/server/index.js') + t.stringLiteral(astroServerPath) ) ); }, @@ -104,7 +111,7 @@ export default function tagExportsWithRenderer({ addTag(property.key.name); } }); - } else if (t.isExportNamedDeclaration(node)) { + } else if (t.isExportNamedDeclaration(node) && !node.source) { node.specifiers.forEach((specifier) => { if (t.isExportSpecifier(specifier) && t.isIdentifier(specifier.exported)) { addTag(specifier.local.name); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c4990eb94234..e6562981dd03 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -413,6 +413,7 @@ importers: gray-matter: ^4.0.3 html-entities: ^2.3.3 html-escaper: ^3.0.3 + import-meta-resolve: ^2.1.0 kleur: ^4.1.4 magic-string: ^0.25.9 mime: ^3.0.0 @@ -482,6 +483,7 @@ importers: gray-matter: 4.0.3 html-entities: 2.3.3 html-escaper: 3.0.3 + import-meta-resolve: 2.1.0 kleur: 4.1.5 magic-string: 0.25.9 mime: 3.0.0 @@ -3043,9 +3045,11 @@ importers: astro: workspace:* astro-scripts: workspace:* babel-preset-solid: ^1.4.2 + import-meta-resolve: ^2.1.0 solid-js: ^1.5.1 dependencies: babel-preset-solid: 1.5.7 + import-meta-resolve: 2.1.0 devDependencies: astro: link:../../astro astro-scripts: link:../../../scripts From 3a05819a2a0f7398aa0e293bea68a8c778a99d7a Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 12 Oct 2022 17:49:56 +0800 Subject: [PATCH 4/7] Add changeset --- .changeset/ten-phones-drop.md | 5 +++++ .changeset/thin-parents-breathe.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/ten-phones-drop.md create mode 100644 .changeset/thin-parents-breathe.md diff --git a/.changeset/ten-phones-drop.md b/.changeset/ten-phones-drop.md new file mode 100644 index 000000000000..4233ec43300a --- /dev/null +++ b/.changeset/ten-phones-drop.md @@ -0,0 +1,5 @@ +--- +'@astrojs/solid-js': minor +--- + +Auto ssr.noExternal solidjs dependencies diff --git a/.changeset/thin-parents-breathe.md b/.changeset/thin-parents-breathe.md new file mode 100644 index 000000000000..2867ab3b62f7 --- /dev/null +++ b/.changeset/thin-parents-breathe.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Support strict dependency install for libraries with JSX From d67dc4426572055c3b9193030537f95e9562faa2 Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 12 Oct 2022 17:52:28 +0800 Subject: [PATCH 5/7] Add fork license --- packages/integrations/solid/src/dependencies.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/integrations/solid/src/dependencies.ts b/packages/integrations/solid/src/dependencies.ts index cf694997cf84..d73db1d4f7e2 100644 --- a/packages/integrations/solid/src/dependencies.ts +++ b/packages/integrations/solid/src/dependencies.ts @@ -1,3 +1,7 @@ +// This file is a fork of vite-plugin-solid. +// Original: https://github.com/solidjs/vite-plugin-solid/blob/03130c8a0a2ceaab9a07e16f1e1df832b996e1b8/src/index.ts#L251-L297 +// License: MIT (https://github.com/solidjs/vite-plugin-solid/blob/03130c8a0a2ceaab9a07e16f1e1df832b996e1b8/package.json#L38) + import fs from 'fs'; import path from 'path'; import { createRequire } from 'module'; From 3373f899194d14c3f46b658eb233cec15399f3ec Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 12 Oct 2022 20:11:41 +0800 Subject: [PATCH 6/7] Fix lockfile --- pnpm-lock.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e6562981dd03..be786c46949c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3045,11 +3045,9 @@ importers: astro: workspace:* astro-scripts: workspace:* babel-preset-solid: ^1.4.2 - import-meta-resolve: ^2.1.0 solid-js: ^1.5.1 dependencies: babel-preset-solid: 1.5.7 - import-meta-resolve: 2.1.0 devDependencies: astro: link:../../astro astro-scripts: link:../../../scripts From 6be0b03e5740fa24157bdd6a7b49969fbe2f833e Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 12 Oct 2022 20:38:34 +0800 Subject: [PATCH 7/7] Fix lint --- packages/integrations/solid/src/dependencies.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/integrations/solid/src/dependencies.ts b/packages/integrations/solid/src/dependencies.ts index d73db1d4f7e2..bdcfb4c8f562 100644 --- a/packages/integrations/solid/src/dependencies.ts +++ b/packages/integrations/solid/src/dependencies.ts @@ -20,6 +20,7 @@ function containsSolidField(fields: Record) { export function getSolidDeps(root: URL) { const pkgPath = path.join(fileURLToPath(root), 'package.json'); if (!fs.existsSync(pkgPath)) { + // eslint-disable-next-line no-console console.log('No package.json found at project root'); return []; } @@ -29,14 +30,14 @@ export function getSolidDeps(root: URL) { const pkgs = deps.map((dep) => { try { return require(`${dep}/package.json`); - } catch (e) { + } catch { try { let dir = path.dirname(require.resolve(dep)); while (dir) { - const pkgPath = path.join(dir, 'package.json'); - if (fs.existsSync(pkgPath)) { - const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); - if (pkg && pkg.name === dep) return pkg; + const subPkgPath = path.join(dir, 'package.json'); + if (fs.existsSync(subPkgPath)) { + const subPkg = JSON.parse(fs.readFileSync(subPkgPath, 'utf-8')); + if (subPkg && subPkg.name === dep) return subPkg; } const parent = path.dirname(dir); if (parent === dir) { @@ -45,7 +46,7 @@ export function getSolidDeps(root: URL) { dir = parent; } } catch (e) { - console.log("Couldn't find package.json for", dep, e); + console.warn("Couldn't find package.json for", dep, e); } } });