Skip to content

Commit

Permalink
Improve Solid libraries config handling (#5208)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluwy committed Oct 28, 2022
1 parent 7f89870 commit c98c5aa
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 54 deletions.
5 changes: 5 additions & 0 deletions .changeset/dull-moles-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/solid-js': patch
---

Improve third-party solid packages config handling
3 changes: 2 additions & 1 deletion packages/integrations/solid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"dev": "astro-scripts dev \"src/**/*.ts\""
},
"dependencies": {
"babel-preset-solid": "^1.4.2"
"babel-preset-solid": "^1.4.2",
"vitefu": "^0.1.0"
},
"devDependencies": {
"astro": "workspace:*",
Expand Down
61 changes: 16 additions & 45 deletions packages/integrations/solid/src/dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,26 @@
// 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 { createRequire } from 'module';
import path from 'path';
import { fileURLToPath } from 'url';
import { crawlFrameworkPkgs } from 'vitefu';

export async function getSolidPkgsConfig(root: URL, isBuild: boolean) {
return await crawlFrameworkPkgs({
root: fileURLToPath(root),
isBuild,
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 (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;
if (typeof fields[key] === 'object' && fields[key] != null && containsSolidField(fields[key]))
return true;
}
return false;
}

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 [];
}
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 {
try {
let dir = path.dirname(require.resolve(dep));
while (dir) {
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) {
break;
}
dir = parent;
}
} catch {}
}
});
return deps.reduce<string[]>((acc, dep, i) => {
if (pkgs[i] && pkgs[i].exports && containsSolidField(pkgs[i].exports)) acc.push(dep);
return acc;
}, []);
}
17 changes: 9 additions & 8 deletions packages/integrations/solid/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AstroIntegration, AstroRenderer } from 'astro';
import { getSolidDeps } from './dependencies.js';
import { getSolidPkgsConfig } from './dependencies.js';

function getRenderer(): AstroRenderer {
return {
Expand All @@ -24,10 +24,11 @@ function getRenderer(): AstroRenderer {
};
}

function getViteConfiguration(isDev: boolean, root: URL) {
async 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'];
const solidPkgsConfig = await getSolidPkgsConfig(root, !isDev);
return {
/**
* We only need esbuild on .ts or .js files.
Expand All @@ -40,13 +41,13 @@ function getViteConfiguration(isDev: boolean, root: URL) {
alias: [{ find: /^solid-refresh$/, replacement: '/@solid-refresh' }],
},
optimizeDeps: {
include: nestedDeps,
exclude: ['@astrojs/solid-js/server.js'],
include: [...nestedDeps, ...solidPkgsConfig.optimizeDeps.include],
exclude: ['@astrojs/solid-js/server.js', ...solidPkgsConfig.optimizeDeps.exclude],
},
ssr: {
external: ['babel-preset-solid'],
target: 'node',
noExternal: ['solid-js', ...getSolidDeps(root)],
external: ['babel-preset-solid', ...solidPkgsConfig.ssr.external],
noExternal: ['solid-js', ...solidPkgsConfig.ssr.noExternal],
},
};
}
Expand All @@ -55,9 +56,9 @@ export default function (): AstroIntegration {
return {
name: '@astrojs/solid-js',
hooks: {
'astro:config:setup': ({ command, addRenderer, updateConfig, config }) => {
'astro:config:setup': async ({ command, addRenderer, updateConfig, config }) => {
addRenderer(getRenderer());
updateConfig({ vite: getViteConfiguration(command === 'dev', config.root) });
updateConfig({ vite: await getViteConfiguration(command === 'dev', config.root) });
},
},
};
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c98c5aa

Please sign in to comment.