@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/cjs/index.cjs
CHANGED
|
@@ -2119,9 +2119,13 @@ function startServe(options, internal = {}) {
|
|
|
2119
2119
|
if (isBuild) {
|
|
2120
2120
|
lines.push(`import manifest from ${JSON.stringify(MANIFEST_ID)};`);
|
|
2121
2121
|
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;`,
|
|
2122
|
-
// The plugin's manifest module
|
|
2123
|
-
// (
|
|
2124
|
-
|
|
2122
|
+
// The plugin's manifest module names the client entry it injected
|
|
2123
|
+
// into the build (`_entry`): every configured input is a genuine
|
|
2124
|
+
// `isEntry` record (a filesystem router's `buildInputs` lists every
|
|
2125
|
+
// route module), so scanning for the first flagged record would pick
|
|
2126
|
+
// whichever sorts first (#353). The scan stays as the fallback for
|
|
2127
|
+
// hand-rolled manifests without the stamp.
|
|
2128
|
+
` 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;`, `}`);
|
|
2125
2129
|
} else {
|
|
2126
2130
|
const devHead = `<script>${devStylePatch}</script>` + `<script type="module" src="${joinBase(base, '/@vite/client')}"></script>`;
|
|
2127
2131
|
lines.push(``, `const DEV_HEAD = ${JSON.stringify(devHead)};`);
|
|
@@ -2345,6 +2349,7 @@ function startServe(options, internal = {}) {
|
|
|
2345
2349
|
}
|
|
2346
2350
|
const build = env.command === 'build';
|
|
2347
2351
|
const clientInput = entries.generated ? ENTRY_CLIENT_ID : path.resolve(root, entries.entryClient);
|
|
2352
|
+
internal.onClientEntryResolved?.(clientInput);
|
|
2348
2353
|
// Real files only — the dep scanner can't crawl virtual modules.
|
|
2349
2354
|
// (In client mode the resolved document joins the scan/style roots
|
|
2350
2355
|
// even with an authored client entry; in SSR mode authored entries
|
|
@@ -3450,6 +3455,23 @@ function getExtension(filename) {
|
|
|
3450
3455
|
const index = filename.lastIndexOf('.');
|
|
3451
3456
|
return index < 0 ? '' : filename.substring(index).replace(/\?.+$/, '');
|
|
3452
3457
|
}
|
|
3458
|
+
// The packages whose dev/production server builds are selected by the
|
|
3459
|
+
// `development` export condition. A dependency on either means the package
|
|
3460
|
+
// consumes the runtime and must resolve it through Vite in dev.
|
|
3461
|
+
const SOLID_RUNTIME_PKGS = ['solid-js', '@solidjs/web'];
|
|
3462
|
+
|
|
3463
|
+
// Tooling that declares solid-js as a peer but never runs inside the SSR
|
|
3464
|
+
// module runner. Kept out of the crawl entirely: classifying them as
|
|
3465
|
+
// semi-framework would also crawl THEIR dependencies, which vitefu deep-
|
|
3466
|
+
// includes in the client optimizer (`@solidjs/vite-plugin > @babel/core`
|
|
3467
|
+
// pre-bundled for the browser — ~2.6 MB of dead weight per cold start).
|
|
3468
|
+
// Mirrors vite-plugin-svelte's isCommonDepWithoutSvelteField list.
|
|
3469
|
+
const NON_RUNTIME_SOLID_PKGS = ['@solidjs/vite-plugin', 'vite', 'vitest', 'eslint-plugin-solid'];
|
|
3470
|
+
const NON_RUNTIME_SOLID_PREFIXES = ['vite-plugin-', 'eslint-plugin-', 'prettier-plugin-', '@types/'];
|
|
3471
|
+
function isNonRuntimeSolidPkg(name) {
|
|
3472
|
+
const bare = name.slice(name.lastIndexOf('/') + 1);
|
|
3473
|
+
return NON_RUNTIME_SOLID_PKGS.includes(name) || NON_RUNTIME_SOLID_PREFIXES.some(p => (p.startsWith('@') ? name : bare).startsWith(p));
|
|
3474
|
+
}
|
|
3453
3475
|
function containsSolidField(fields) {
|
|
3454
3476
|
const keys = Object.keys(fields);
|
|
3455
3477
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -3676,6 +3698,66 @@ function normalizeEmittedLazyEntries(manifest, {
|
|
|
3676
3698
|
}
|
|
3677
3699
|
}
|
|
3678
3700
|
}
|
|
3701
|
+
|
|
3702
|
+
/**
|
|
3703
|
+
* The manifest key of THE client entry — the chunk whose `<script
|
|
3704
|
+
* type="module">` boots the page and whose static import graph carries the
|
|
3705
|
+
* global CSS. `isEntry` cannot answer this: every configured build input is
|
|
3706
|
+
* a genuine entry (#347 keeps them flagged), and plugins routinely add more
|
|
3707
|
+
* inputs than the application entry (filesystem-routing's `buildInputs`
|
|
3708
|
+
* lists every route module, and route keys sort ahead of the plugin's own
|
|
3709
|
+
* `virtual:` entry). So the identity comes from configuration instead: the
|
|
3710
|
+
* entry start mode injected itself, or — outside start mode — the single
|
|
3711
|
+
* configured input when there is exactly one (including Vite's default
|
|
3712
|
+
* `index.html`). Several inputs and no start entry: no answer (null), and
|
|
3713
|
+
* consumers keep their first-`isEntry` scan.
|
|
3714
|
+
*
|
|
3715
|
+
* Matched by key or `src`, the same two spellings `isConfiguredEntry` uses.
|
|
3716
|
+
*/
|
|
3717
|
+
function resolveClientEntryKey(manifest, startClientEntryId, clientBuild, root) {
|
|
3718
|
+
let entryId = startClientEntryId;
|
|
3719
|
+
if (!entryId) {
|
|
3720
|
+
const input = configuredBuildInput(clientBuild);
|
|
3721
|
+
const raw = input == null ? ['index.html'] : typeof input === 'string' ? [input] : Array.isArray(input) ? input : Object.values(input);
|
|
3722
|
+
if (raw.length !== 1 || typeof raw[0] !== 'string') return null;
|
|
3723
|
+
entryId = raw[0];
|
|
3724
|
+
}
|
|
3725
|
+
const {
|
|
3726
|
+
manifestKeys
|
|
3727
|
+
} = resolveConfiguredEntries(entryId, root);
|
|
3728
|
+
for (const key in manifest) {
|
|
3729
|
+
const record = manifest[key];
|
|
3730
|
+
if (!record || typeof record !== 'object' || !record.file) continue;
|
|
3731
|
+
if (manifestKeys.has(key) || typeof record.src === 'string' && manifestKeys.has(record.src)) {
|
|
3732
|
+
return key;
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
return null;
|
|
3736
|
+
}
|
|
3737
|
+
|
|
3738
|
+
/**
|
|
3739
|
+
* Serializes the plugin's manifest module with the client entry made
|
|
3740
|
+
* explicit: `_entry` names its key (the generated handler reads it before
|
|
3741
|
+
* falling back to scanning for `isEntry`), and its record is moved to the
|
|
3742
|
+
* front. The ordering matters for consumers that still identify the entry
|
|
3743
|
+
* by the first `isEntry` record — `@solidjs/web`'s `registerEntryAssets`,
|
|
3744
|
+
* which links the entry graph's stylesheets and modulepreloads into
|
|
3745
|
+
* `<head>`, and hand-rolled server entries — so they and `_entry` agree on
|
|
3746
|
+
* the same chunk. Other configured inputs keep `isEntry`; they are genuine
|
|
3747
|
+
* entries, just not the one the document boots.
|
|
3748
|
+
*/
|
|
3749
|
+
function stampClientEntry(manifest, entryKey, base) {
|
|
3750
|
+
const ordered = {};
|
|
3751
|
+
if (entryKey && manifest[entryKey]) {
|
|
3752
|
+
ordered[entryKey] = manifest[entryKey];
|
|
3753
|
+
}
|
|
3754
|
+
for (const key in manifest) {
|
|
3755
|
+
if (key !== entryKey) ordered[key] = manifest[key];
|
|
3756
|
+
}
|
|
3757
|
+
ordered._base = base;
|
|
3758
|
+
if (entryKey && manifest[entryKey]) ordered._entry = entryKey;
|
|
3759
|
+
return ordered;
|
|
3760
|
+
}
|
|
3679
3761
|
function solidPlugin(options = {}) {
|
|
3680
3762
|
if (typeof options.ssr === 'object') {
|
|
3681
3763
|
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 })`.');
|
|
@@ -3739,6 +3821,11 @@ function solidPlugin(options = {}) {
|
|
|
3739
3821
|
// two-invocation build (`vite build --ssr`) still knows the client's
|
|
3740
3822
|
// entries when it bakes the client manifest in.
|
|
3741
3823
|
let clientBuildConfig = null;
|
|
3824
|
+
// The client entry start mode injects into the client build's input
|
|
3825
|
+
// (reported by startServe): the one input that IS the application entry,
|
|
3826
|
+
// as opposed to further inputs other plugins add (e.g. filesystem-routing's
|
|
3827
|
+
// `buildInputs`, which lists every route module). Null outside start mode.
|
|
3828
|
+
let startClientEntryId = null;
|
|
3742
3829
|
let solidPkgsConfig;
|
|
3743
3830
|
const tsrxCss = new Map();
|
|
3744
3831
|
|
|
@@ -3900,6 +3987,28 @@ function solidPlugin(options = {}) {
|
|
|
3900
3987
|
isBuild: command === 'build',
|
|
3901
3988
|
isFrameworkPkgByJson(pkgJson) {
|
|
3902
3989
|
return containsSolidField(pkgJson.exports || {});
|
|
3990
|
+
},
|
|
3991
|
+
// `false` = neither framework nor semi-framework, and don't crawl
|
|
3992
|
+
// its deps; `undefined` = unknown, fall through to the json checks.
|
|
3993
|
+
isFrameworkPkgByName(name) {
|
|
3994
|
+
return isNonRuntimeSolidPkg(name) ? false : undefined;
|
|
3995
|
+
},
|
|
3996
|
+
// Under `vite dev` the runtime must not be split in two. Inlined
|
|
3997
|
+
// modules resolve `solid-js` through Vite with `development` (its dev
|
|
3998
|
+
// server build); an externalized package's own imports are resolved by
|
|
3999
|
+
// Node, which has no `development` condition, so it loads the
|
|
4000
|
+
// production build instead. Both then run, each with its own
|
|
4001
|
+
// `sharedConfig` — the manifest `renderToStream` sets lands on one and
|
|
4002
|
+
// `lazy()` reads the other. `resolve.externalConditions` below only
|
|
4003
|
+
// fixes the external's own entry, not what it imports, so every
|
|
4004
|
+
// package that consumes the runtime has to go through Vite as well.
|
|
4005
|
+
// Semi-framework is the right class: `ssr.noExternal` without
|
|
4006
|
+
// `optimizeDeps.exclude`, since these hold no raw Solid components.
|
|
4007
|
+
isSemiFrameworkPkgByJson(pkgJson) {
|
|
4008
|
+
// Same gate as the core inlining in configEnvironment: dev serve
|
|
4009
|
+
// only, never vitest (it manages inlining via test.server.deps).
|
|
4010
|
+
if (!replaceDev || isTestMode) return false;
|
|
4011
|
+
return SOLID_RUNTIME_PKGS.some(name => pkgJson.dependencies?.[name] || pkgJson.peerDependencies?.[name]);
|
|
3903
4012
|
}
|
|
3904
4013
|
});
|
|
3905
4014
|
|
|
@@ -4073,8 +4182,16 @@ function solidPlugin(options = {}) {
|
|
|
4073
4182
|
// Only set resolve.external if noExternal is not true (to avoid conflicts with plugins like Cloudflare)
|
|
4074
4183
|
if (name === 'ssr' && solidPkgsConfig) {
|
|
4075
4184
|
if (config.resolve.noExternal !== true) {
|
|
4076
|
-
|
|
4077
|
-
config.resolve.
|
|
4185
|
+
const noExternal = [...(Array.isArray(config.resolve.noExternal) ? config.resolve.noExternal : []), ...solidPkgsConfig.ssr.noExternal];
|
|
4186
|
+
config.resolve.noExternal = noExternal;
|
|
4187
|
+
// vitefu externalizes the non-framework deps of every framework
|
|
4188
|
+
// package in dev, and Vite gives `external` precedence over
|
|
4189
|
+
// `noExternal`. A framework package that lists solid-js or
|
|
4190
|
+
// @solidjs/web under `dependencies` (not peer — e.g.
|
|
4191
|
+
// @tanstack/solid-router 2.0.0-rc.7 → @solidjs/web) would therefore
|
|
4192
|
+
// re-externalize a core inlined above and split the runtime again.
|
|
4193
|
+
// Nothing inlined may appear in `external`.
|
|
4194
|
+
config.resolve.external = [...(Array.isArray(config.resolve.external) ? config.resolve.external : []), ...solidPkgsConfig.ssr.external.filter(dep => !noExternal.includes(dep))];
|
|
4078
4195
|
}
|
|
4079
4196
|
}
|
|
4080
4197
|
},
|
|
@@ -4234,8 +4351,7 @@ function solidPlugin(options = {}) {
|
|
|
4234
4351
|
warn: message => this.warn(message),
|
|
4235
4352
|
repairDynamicEntries: true
|
|
4236
4353
|
});
|
|
4237
|
-
manifest
|
|
4238
|
-
return `export default ${JSON.stringify(manifest)};`;
|
|
4354
|
+
return `export default ${JSON.stringify(stampClientEntry(manifest, resolveClientEntryKey(manifest, startClientEntryId, clientBuildConfig, projectRoot), base))};`;
|
|
4239
4355
|
}
|
|
4240
4356
|
// SSR build before the client build produced a manifest: bake in the
|
|
4241
4357
|
// dev-shaped fallback (registry miss degrades to js-only resolution).
|
|
@@ -4547,6 +4663,9 @@ function solidPlugin(options = {}) {
|
|
|
4547
4663
|
onDocumentResolved(documentPath) {
|
|
4548
4664
|
// Normalize to forward slashes to match Vite's transform ids.
|
|
4549
4665
|
documentModuleId = documentPath ? documentPath.split(path.sep).join('/') : null;
|
|
4666
|
+
},
|
|
4667
|
+
onClientEntryResolved(entryId) {
|
|
4668
|
+
startClientEntryId = entryId;
|
|
4550
4669
|
}
|
|
4551
4670
|
}));
|
|
4552
4671
|
}
|