Improve Solid libraries config handling (#5208)

This commit is contained in:
Bjorn Lu 2022-10-28 23:30:54 +08:00 committed by GitHub
parent 7f8987085c
commit c98c5aa0ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 54 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/solid-js': patch
---
Improve third-party solid packages config handling

View file

@ -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:*",

View file

@ -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;
}, []);
}

View file

@ -1,5 +1,5 @@
import type { AstroIntegration, AstroRenderer } from 'astro';
import { getSolidDeps } from './dependencies.js';
import { getSolidPkgsConfig } from './dependencies.js';
function getRenderer(): AstroRenderer {
return {
@ -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.
@ -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],
},
};
}
@ -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) });
},
},
};

View file

@ -3083,8 +3083,10 @@ importers:
astro-scripts: workspace:*
babel-preset-solid: ^1.4.2
solid-js: ^1.5.1
vitefu: ^0.1.0
dependencies:
babel-preset-solid: 1.6.0
vitefu: 0.1.0
devDependencies:
astro: link:../../astro
astro-scripts: link:../../../scripts
@ -18008,6 +18010,17 @@ packages:
fsevents: 2.3.2
dev: false
/vitefu/0.1.0:
resolution: {integrity: sha512-5MQSHP9yr0HIve8q4XNb7QXfO1P4tzZDZP99qH0FM5ClcwYddeGXRDQ4TQYRUeXLjZ+vLecirHtGNpwFFUF7sw==}
peerDependencies:
vite: ^3.0.0
peerDependenciesMeta:
vite:
optional: true
dependencies:
import-meta-resolve: 2.1.0
dev: false
/vitefu/0.1.0_vite@3.2.1:
resolution: {integrity: sha512-5MQSHP9yr0HIve8q4XNb7QXfO1P4tzZDZP99qH0FM5ClcwYddeGXRDQ4TQYRUeXLjZ+vLecirHtGNpwFFUF7sw==}
peerDependencies: