@solidjs/vite-plugin 3.0.0-next.40 → 3.0.0-next.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +126 -7
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.mjs +126 -7
- package/dist/esm/index.mjs.map +1 -1
- package/dist/types/src/index.d.ts +8 -0
- package/dist/types/src/ssr/index.d.ts +8 -0
- package/package.json +1 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -2095,9 +2095,13 @@ function startServe(options, internal = {}) {
|
|
|
2095
2095
|
if (isBuild) {
|
|
2096
2096
|
lines.push(`import manifest from ${JSON.stringify(MANIFEST_ID)};`);
|
|
2097
2097
|
lines.push(``, `function joinAssetPath(base, file) {`, ` if (typeof base !== 'string' || !base) base = '/';`, ` if (base[base.length - 1] !== '/') base += '/';`, ` return base + (file[0] === '/' ? file.slice(1) : file);`, `}`, ``, `let clientEntryUrl;`, `function resolveClientEntry() {`, ` if (clientEntryUrl !== undefined) return clientEntryUrl;`, ` clientEntryUrl = null;`,
|
|
2098
|
-
// The plugin's manifest module
|
|
2099
|
-
// (
|
|
2100
|
-
|
|
2098
|
+
// The plugin's manifest module names the client entry it injected
|
|
2099
|
+
// into the build (`_entry`): every configured input is a genuine
|
|
2100
|
+
// `isEntry` record (a filesystem router's `buildInputs` lists every
|
|
2101
|
+
// route module), so scanning for the first flagged record would pick
|
|
2102
|
+
// whichever sorts first (#353). The scan stays as the fallback for
|
|
2103
|
+
// hand-rolled manifests without the stamp.
|
|
2104
|
+
` const stamped = manifest._entry && manifest[manifest._entry];`, ` if (stamped && stamped.file) {`, ` return (clientEntryUrl = joinAssetPath(manifest._base, stamped.file));`, ` }`, ` for (const key in manifest) {`, ` const chunk = manifest[key];`, ` if (chunk && chunk.isEntry && chunk.file) {`, ` clientEntryUrl = joinAssetPath(manifest._base, chunk.file);`, ` break;`, ` }`, ` }`, ` return clientEntryUrl;`, `}`);
|
|
2101
2105
|
} else {
|
|
2102
2106
|
const devHead = `<script>${devStylePatch}</script>` + `<script type="module" src="${joinBase(base, '/@vite/client')}"></script>`;
|
|
2103
2107
|
lines.push(``, `const DEV_HEAD = ${JSON.stringify(devHead)};`);
|
|
@@ -2321,6 +2325,7 @@ function startServe(options, internal = {}) {
|
|
|
2321
2325
|
}
|
|
2322
2326
|
const build = env.command === 'build';
|
|
2323
2327
|
const clientInput = entries.generated ? ENTRY_CLIENT_ID : path.resolve(root, entries.entryClient);
|
|
2328
|
+
internal.onClientEntryResolved?.(clientInput);
|
|
2324
2329
|
// Real files only — the dep scanner can't crawl virtual modules.
|
|
2325
2330
|
// (In client mode the resolved document joins the scan/style roots
|
|
2326
2331
|
// even with an authored client entry; in SSR mode authored entries
|
|
@@ -3426,6 +3431,23 @@ function getExtension(filename) {
|
|
|
3426
3431
|
const index = filename.lastIndexOf('.');
|
|
3427
3432
|
return index < 0 ? '' : filename.substring(index).replace(/\?.+$/, '');
|
|
3428
3433
|
}
|
|
3434
|
+
// The packages whose dev/production server builds are selected by the
|
|
3435
|
+
// `development` export condition. A dependency on either means the package
|
|
3436
|
+
// consumes the runtime and must resolve it through Vite in dev.
|
|
3437
|
+
const SOLID_RUNTIME_PKGS = ['solid-js', '@solidjs/web'];
|
|
3438
|
+
|
|
3439
|
+
// Tooling that declares solid-js as a peer but never runs inside the SSR
|
|
3440
|
+
// module runner. Kept out of the crawl entirely: classifying them as
|
|
3441
|
+
// semi-framework would also crawl THEIR dependencies, which vitefu deep-
|
|
3442
|
+
// includes in the client optimizer (`@solidjs/vite-plugin > @babel/core`
|
|
3443
|
+
// pre-bundled for the browser — ~2.6 MB of dead weight per cold start).
|
|
3444
|
+
// Mirrors vite-plugin-svelte's isCommonDepWithoutSvelteField list.
|
|
3445
|
+
const NON_RUNTIME_SOLID_PKGS = ['@solidjs/vite-plugin', 'vite', 'vitest', 'eslint-plugin-solid'];
|
|
3446
|
+
const NON_RUNTIME_SOLID_PREFIXES = ['vite-plugin-', 'eslint-plugin-', 'prettier-plugin-', '@types/'];
|
|
3447
|
+
function isNonRuntimeSolidPkg(name) {
|
|
3448
|
+
const bare = name.slice(name.lastIndexOf('/') + 1);
|
|
3449
|
+
return NON_RUNTIME_SOLID_PKGS.includes(name) || NON_RUNTIME_SOLID_PREFIXES.some(p => (p.startsWith('@') ? name : bare).startsWith(p));
|
|
3450
|
+
}
|
|
3429
3451
|
function containsSolidField(fields) {
|
|
3430
3452
|
const keys = Object.keys(fields);
|
|
3431
3453
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -3652,6 +3674,66 @@ function normalizeEmittedLazyEntries(manifest, {
|
|
|
3652
3674
|
}
|
|
3653
3675
|
}
|
|
3654
3676
|
}
|
|
3677
|
+
|
|
3678
|
+
/**
|
|
3679
|
+
* The manifest key of THE client entry — the chunk whose `<script
|
|
3680
|
+
* type="module">` boots the page and whose static import graph carries the
|
|
3681
|
+
* global CSS. `isEntry` cannot answer this: every configured build input is
|
|
3682
|
+
* a genuine entry (#347 keeps them flagged), and plugins routinely add more
|
|
3683
|
+
* inputs than the application entry (filesystem-routing's `buildInputs`
|
|
3684
|
+
* lists every route module, and route keys sort ahead of the plugin's own
|
|
3685
|
+
* `virtual:` entry). So the identity comes from configuration instead: the
|
|
3686
|
+
* entry start mode injected itself, or — outside start mode — the single
|
|
3687
|
+
* configured input when there is exactly one (including Vite's default
|
|
3688
|
+
* `index.html`). Several inputs and no start entry: no answer (null), and
|
|
3689
|
+
* consumers keep their first-`isEntry` scan.
|
|
3690
|
+
*
|
|
3691
|
+
* Matched by key or `src`, the same two spellings `isConfiguredEntry` uses.
|
|
3692
|
+
*/
|
|
3693
|
+
function resolveClientEntryKey(manifest, startClientEntryId, clientBuild, root) {
|
|
3694
|
+
let entryId = startClientEntryId;
|
|
3695
|
+
if (!entryId) {
|
|
3696
|
+
const input = configuredBuildInput(clientBuild);
|
|
3697
|
+
const raw = input == null ? ['index.html'] : typeof input === 'string' ? [input] : Array.isArray(input) ? input : Object.values(input);
|
|
3698
|
+
if (raw.length !== 1 || typeof raw[0] !== 'string') return null;
|
|
3699
|
+
entryId = raw[0];
|
|
3700
|
+
}
|
|
3701
|
+
const {
|
|
3702
|
+
manifestKeys
|
|
3703
|
+
} = resolveConfiguredEntries(entryId, root);
|
|
3704
|
+
for (const key in manifest) {
|
|
3705
|
+
const record = manifest[key];
|
|
3706
|
+
if (!record || typeof record !== 'object' || !record.file) continue;
|
|
3707
|
+
if (manifestKeys.has(key) || typeof record.src === 'string' && manifestKeys.has(record.src)) {
|
|
3708
|
+
return key;
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3711
|
+
return null;
|
|
3712
|
+
}
|
|
3713
|
+
|
|
3714
|
+
/**
|
|
3715
|
+
* Serializes the plugin's manifest module with the client entry made
|
|
3716
|
+
* explicit: `_entry` names its key (the generated handler reads it before
|
|
3717
|
+
* falling back to scanning for `isEntry`), and its record is moved to the
|
|
3718
|
+
* front. The ordering matters for consumers that still identify the entry
|
|
3719
|
+
* by the first `isEntry` record — `@solidjs/web`'s `registerEntryAssets`,
|
|
3720
|
+
* which links the entry graph's stylesheets and modulepreloads into
|
|
3721
|
+
* `<head>`, and hand-rolled server entries — so they and `_entry` agree on
|
|
3722
|
+
* the same chunk. Other configured inputs keep `isEntry`; they are genuine
|
|
3723
|
+
* entries, just not the one the document boots.
|
|
3724
|
+
*/
|
|
3725
|
+
function stampClientEntry(manifest, entryKey, base) {
|
|
3726
|
+
const ordered = {};
|
|
3727
|
+
if (entryKey && manifest[entryKey]) {
|
|
3728
|
+
ordered[entryKey] = manifest[entryKey];
|
|
3729
|
+
}
|
|
3730
|
+
for (const key in manifest) {
|
|
3731
|
+
if (key !== entryKey) ordered[key] = manifest[key];
|
|
3732
|
+
}
|
|
3733
|
+
ordered._base = base;
|
|
3734
|
+
if (entryKey && manifest[entryKey]) ordered._entry = entryKey;
|
|
3735
|
+
return ordered;
|
|
3736
|
+
}
|
|
3655
3737
|
function solidPlugin(options = {}) {
|
|
3656
3738
|
if (typeof options.ssr === 'object') {
|
|
3657
3739
|
throw new Error('[@solidjs/vite-plugin] `ssr` now only accepts a boolean ("is the app server-rendered"); ' + 'move start-mode options to `start: {}` and set `ssr: true`. Example: ' + '`solid({ ssr: { document: … } })` becomes `solid({ start: { document: … }, ssr: true })`.');
|
|
@@ -3715,6 +3797,11 @@ function solidPlugin(options = {}) {
|
|
|
3715
3797
|
// two-invocation build (`vite build --ssr`) still knows the client's
|
|
3716
3798
|
// entries when it bakes the client manifest in.
|
|
3717
3799
|
let clientBuildConfig = null;
|
|
3800
|
+
// The client entry start mode injects into the client build's input
|
|
3801
|
+
// (reported by startServe): the one input that IS the application entry,
|
|
3802
|
+
// as opposed to further inputs other plugins add (e.g. filesystem-routing's
|
|
3803
|
+
// `buildInputs`, which lists every route module). Null outside start mode.
|
|
3804
|
+
let startClientEntryId = null;
|
|
3718
3805
|
let solidPkgsConfig;
|
|
3719
3806
|
const tsrxCss = new Map();
|
|
3720
3807
|
|
|
@@ -3876,6 +3963,28 @@ function solidPlugin(options = {}) {
|
|
|
3876
3963
|
isBuild: command === 'build',
|
|
3877
3964
|
isFrameworkPkgByJson(pkgJson) {
|
|
3878
3965
|
return containsSolidField(pkgJson.exports || {});
|
|
3966
|
+
},
|
|
3967
|
+
// `false` = neither framework nor semi-framework, and don't crawl
|
|
3968
|
+
// its deps; `undefined` = unknown, fall through to the json checks.
|
|
3969
|
+
isFrameworkPkgByName(name) {
|
|
3970
|
+
return isNonRuntimeSolidPkg(name) ? false : undefined;
|
|
3971
|
+
},
|
|
3972
|
+
// Under `vite dev` the runtime must not be split in two. Inlined
|
|
3973
|
+
// modules resolve `solid-js` through Vite with `development` (its dev
|
|
3974
|
+
// server build); an externalized package's own imports are resolved by
|
|
3975
|
+
// Node, which has no `development` condition, so it loads the
|
|
3976
|
+
// production build instead. Both then run, each with its own
|
|
3977
|
+
// `sharedConfig` — the manifest `renderToStream` sets lands on one and
|
|
3978
|
+
// `lazy()` reads the other. `resolve.externalConditions` below only
|
|
3979
|
+
// fixes the external's own entry, not what it imports, so every
|
|
3980
|
+
// package that consumes the runtime has to go through Vite as well.
|
|
3981
|
+
// Semi-framework is the right class: `ssr.noExternal` without
|
|
3982
|
+
// `optimizeDeps.exclude`, since these hold no raw Solid components.
|
|
3983
|
+
isSemiFrameworkPkgByJson(pkgJson) {
|
|
3984
|
+
// Same gate as the core inlining in configEnvironment: dev serve
|
|
3985
|
+
// only, never vitest (it manages inlining via test.server.deps).
|
|
3986
|
+
if (!replaceDev || isTestMode) return false;
|
|
3987
|
+
return SOLID_RUNTIME_PKGS.some(name => pkgJson.dependencies?.[name] || pkgJson.peerDependencies?.[name]);
|
|
3879
3988
|
}
|
|
3880
3989
|
});
|
|
3881
3990
|
|
|
@@ -4049,8 +4158,16 @@ function solidPlugin(options = {}) {
|
|
|
4049
4158
|
// Only set resolve.external if noExternal is not true (to avoid conflicts with plugins like Cloudflare)
|
|
4050
4159
|
if (name === 'ssr' && solidPkgsConfig) {
|
|
4051
4160
|
if (config.resolve.noExternal !== true) {
|
|
4052
|
-
|
|
4053
|
-
config.resolve.
|
|
4161
|
+
const noExternal = [...(Array.isArray(config.resolve.noExternal) ? config.resolve.noExternal : []), ...solidPkgsConfig.ssr.noExternal];
|
|
4162
|
+
config.resolve.noExternal = noExternal;
|
|
4163
|
+
// vitefu externalizes the non-framework deps of every framework
|
|
4164
|
+
// package in dev, and Vite gives `external` precedence over
|
|
4165
|
+
// `noExternal`. A framework package that lists solid-js or
|
|
4166
|
+
// @solidjs/web under `dependencies` (not peer — e.g.
|
|
4167
|
+
// @tanstack/solid-router 2.0.0-rc.7 → @solidjs/web) would therefore
|
|
4168
|
+
// re-externalize a core inlined above and split the runtime again.
|
|
4169
|
+
// Nothing inlined may appear in `external`.
|
|
4170
|
+
config.resolve.external = [...(Array.isArray(config.resolve.external) ? config.resolve.external : []), ...solidPkgsConfig.ssr.external.filter(dep => !noExternal.includes(dep))];
|
|
4054
4171
|
}
|
|
4055
4172
|
}
|
|
4056
4173
|
},
|
|
@@ -4210,8 +4327,7 @@ function solidPlugin(options = {}) {
|
|
|
4210
4327
|
warn: message => this.warn(message),
|
|
4211
4328
|
repairDynamicEntries: true
|
|
4212
4329
|
});
|
|
4213
|
-
manifest
|
|
4214
|
-
return `export default ${JSON.stringify(manifest)};`;
|
|
4330
|
+
return `export default ${JSON.stringify(stampClientEntry(manifest, resolveClientEntryKey(manifest, startClientEntryId, clientBuildConfig, projectRoot), base))};`;
|
|
4215
4331
|
}
|
|
4216
4332
|
// SSR build before the client build produced a manifest: bake in the
|
|
4217
4333
|
// dev-shaped fallback (registry miss degrades to js-only resolution).
|
|
@@ -4523,6 +4639,9 @@ function solidPlugin(options = {}) {
|
|
|
4523
4639
|
onDocumentResolved(documentPath) {
|
|
4524
4640
|
// Normalize to forward slashes to match Vite's transform ids.
|
|
4525
4641
|
documentModuleId = documentPath ? documentPath.split(path.sep).join('/') : null;
|
|
4642
|
+
},
|
|
4643
|
+
onClientEntryResolved(entryId) {
|
|
4644
|
+
startClientEntryId = entryId;
|
|
4526
4645
|
}
|
|
4527
4646
|
}));
|
|
4528
4647
|
}
|