Define `__SOLID_SERVER_COMPONENTS__` at build time so libraries can drop server-component-only client code
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 新手友好度
- 55/100
- Issue 类型
- 功能
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- rollup, typescript, vite
- 领域
- build-system
调研方向
Start in the main plugin's config() hook, next to the existing optimizeDeps.rolldownOptions.transform.jsx, and trace how serverFunctions.components and user define values are resolved. Add the constant in both requested define locations and cover the true, false, and user-provided cases; update the RFC 11 integration surface and server-components skill docs. Done when the checklist is covered and plugin tests pass.
由索引模型根据 Issue 内容生成。
描述
Problem
@solidjs/router ships a client fallback for server-component forms. These forms arrive as URLs in the HTML with no client reference. When no action() handler is installed, the router intercepts POSTs under actionBase and lazily imports its action layer.
Only server-component apps need this, but every router app pays for it. In a minimal router app with no server functions (Vite 8, gzip):
- about 0.85 KB eager (up to 1.4 KB when it's the app's only dynamic import);
- a 16.8 KB lazy chain: the
serverFormschunk (8.6 KB) plus the decode chunk (7.0 KB) and a server chunk (1.2 KB) behind it.
The router's flat build inlines all of it eagerly (about 8 KB).
Proposal
The plugin defines a global constant __SOLID_SERVER_COMPONENTS__. Core owns and documents the name, with the meaning "server components are enabled for this build".
- Value:
truewhenserverFunctions.componentsis truthy (including'external'), otherwisefalse. It must always be defined: if it's left undefined, nothing can be removed. - Set it in both top-level
define(build, and dev source via/@vite/env) andoptimizeDeps.rolldownOptions.transform.define(dev pre-bundled dependencies; the optimizer ignores top-leveldefine). - Respect a user-provided
define[__SOLID_SERVER_COMPONENTS__]. - Applying it to all environments is fine; it's harmless on the server.
Why a define
Whether a check folds away depends on the form:
| Form | Rollup | Rolldown 1.2.6 | esbuild |
|---|---|---|---|
Imported, never-written let flag |
folds | doesn't fold | doesn't fold |
| Literal define | folds | folds | folds |
Cost
Zero for apps. One config entry in the plugin.
Router follow-up
declare const __SOLID_SERVER_COMPONENTS__: boolean | undefined;
if (typeof __SOLID_SERVER_COMPONENTS__ !== "undefined" && __SOLID_SERVER_COMPONENTS__) {
/* intercept */ import("./serverForms.js")...
}
Bundler, solid entry |
today, KB gz eager / lazy | with false |
|---|---|---|
| Rolldown | 18.84 / 16.22 | 17.97 / 0 |
| Rollup | 19.74 / 15.22 | 18.94 / 0 |
| esbuild | 22.62 eager, serverForms lazy |
20.95, serverForms gone |
- With
true, output matches today andserverFormsstays lazy, so server-component apps withoutaction()still don't pay for it eagerly. - In the flat build,
falsesaves about 7–8 KB eager. - The router's own build (tsc + Rollup) keeps the guard; no config change is needed.
- Without the plugin, the fallback is off at runtime and the bytes are the same as today. Server-component setups without the plugin define the constant themselves, as documented in core.
Alternatives considered
configureClientsetup modules: too much wiring through start mode.- A runtime flag in server-functions/frames: doesn't fold under Rolldown or esbuild (measured above).
- The router installing the fallback from
serverRouteComponent/action: leaves a coverage gap, because forms can arrive with neither present. - Asking Rolldown upstream to fold imported constants: out of our control.
Implementation sketch
This goes in the main plugin's config() hook, next to the existing optimizeDeps.rolldownOptions.transform.jsx, using the serverFunctions.components value resolved in solidPlugin().
const SC_KEY = "__SOLID_SERVER_COMPONENTS__";
// inside config():
const scDefine = { [SC_KEY]: userConfig.define?.[SC_KEY] ?? JSON.stringify(serverComponents) };
return {
define: scDefine,
optimizeDeps: {
// ...existing
rolldownOptions: { transform: { jsx: { runtime: "classic" }, define: scDefine }, plugins: [/* existing */] }
}
};
Checklist
- Plugin:
defineplusoptimizeDeps.rolldownOptions.transform.define; respect the user's value. - Core docs: RFC 11 integration surface and the server-components skill (cross-link).
- Router: wrapped guard; vitest
definetrue plus an off-path test; changeset.
- 主要语言
- TypeScript
- 星标
- 522
- 派生
- 72
- 平均合并
- 1 天 3 小时
- 30 天内合并 PR
- 38
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
solidjs/solid-vite-plugin 的其他 Issue
-
Test environment detection doesn't consider Vitest workspaces可能已有人在做 @carloitaben 于 48 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
solidjs/solid-vite-plugin#205 · 1 条评论 · 2 个 reaction ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 68/100
solidjs/solid-vite-plugin#369 · 3 条评论 ·
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 35/100
solidjs/solid-vite-plugin#328 ·
维护者通常 1 天内回复
-
Retain $ServerOnly templates while HMR is active可能已有人在做 @brenelz 于 22 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 68/100
solidjs/solid-vite-plugin#308 ·
维护者通常 1 天内回复
-
jsx: 'preserve' in optimizeDeps breaks dependency scan when .tsx files use `import.meta.glob`可能已有人在做 @brenelz 于 22 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 72/100
solidjs/solid-vite-plugin#262 · 2 条评论 ·
维护者通常 1 天内回复
查看 solidjs/solid-vite-plugin 的全部 Issue
相似的 Issue
-
check:passed streams:add
难度 1/5 1-3 小时 新手友好度 72/100
维护者通常 2 天内回复
-
beta technical-medium ui
难度 2/5 1-3 小时 新手友好度 62/100
walletbeat/walletbeat#1625 ·
维护者通常 1 天内回复
-
[Good First Issue]: Add unit tests for NetworkVersionInfo可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭Good First Issue hacktoberfest
难度 2/5 1-3 小时 新手友好度 85/100
hiero-ledger/hiero-sdk-js#4489 ·
维护者通常 1 天内回复
-
[Bug] The clients language filter cannot select the rows the page labels as unknown可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭
难度 2/5 1-3 小时 新手友好度 82/100
apache/rocketmq-dashboard#6103 ·
维护者通常 4 天内回复
-
Bug
难度 2/5 1-3 小时 新手友好度 76/100
payloadcms/payload#18652 ·
维护者通常 1 天内回复