@solidjs/start 2.0.0-rc.8 → 2.0.0
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/CHANGELOG.md +41 -2
- package/dist/config/index.d.ts +13 -1
- package/dist/config/index.js +3 -3
- package/dist/config/lazy.js +7 -2
- package/dist/config/manifest.d.ts +3 -0
- package/dist/config/manifest.js +7 -2
- package/dist/directives/remove-unused-variables.js +13 -1
- package/dist/server/collect-styles.d.ts +3 -1
- package/dist/server/collect-styles.js +8 -5
- package/dist/server/manifest/dev-client-manifest.js +1 -1
- package/dist/server/manifest/dev-ssr-manifest.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @solidjs/start
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Highlights
|
|
6
|
+
|
|
7
|
+
SolidStart v2 is now stable. This release replaces Vinxi with direct use of Vite’s Environment API, providing Solid v1 applications with a simpler Vite 8 and Rolldown-powered foundation, improved compatibility with the Vite ecosystem, and direct integration with deployment plugins.
|
|
8
|
+
|
|
9
|
+
SolidStart v2 requires Node.js 24 or newer and Vite 8. Most SolidStart v1 applications can upgrade by moving their framework configuration from `app.config.ts` to `vite.config.ts` and following the migration guide.
|
|
10
|
+
|
|
11
|
+
- [Read the full SolidStart v2 announcement](https://github.com/solidjs/solid-start/discussions/2281)
|
|
12
|
+
- [Follow the migration guide](https://docs.solidjs.com/solid-start/v2/migrating-from-v1)
|
|
13
|
+
- [View the complete changelog](https://github.com/solidjs/solid-start/blob/main/packages/start/CHANGELOG.md)
|
|
14
|
+
|
|
15
|
+
## 2.0.0-rc.10
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- 3f2b7a7: The file filter logic used for CSS crawling in development can now be configured with the vite plugin option `css.filter` analog to `serverFunctions.filter`:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
solidStart({
|
|
23
|
+
css: {
|
|
24
|
+
filter: {
|
|
25
|
+
// Exclude all node_modules except "my-dependency" with a flat node_modules layout
|
|
26
|
+
exclude: "node_modules/!(my-dependency)/**/*",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- 6581877: Fixed shared chunk css not being server rendered in production (Vite 8 regression).
|
|
35
|
+
- 37d4488: Migrate the built-in Vite configuration from the deprecated `rollupOptions` alias to `rolldownOptions`.
|
|
36
|
+
- 3f2b7a7: Fixed css from files with url sensitive characters such as `+` not being server-rendered.
|
|
37
|
+
|
|
38
|
+
## 2.0.0-rc.9
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- 8eef552: Remove type-only import remnants from client server-function transforms so they do not retain server-only dependency chains.
|
|
43
|
+
|
|
3
44
|
## 2.0.0-rc.8
|
|
4
45
|
|
|
5
46
|
### Patch Changes
|
|
@@ -59,7 +100,6 @@
|
|
|
59
100
|
Route files are imported through an id carrying the picked exports in the query (`routes/api.ts?pick=GET`), which left the id ending in the export name. Plugins whose filter is anchored on the file extension (`/\.[cm]?[jt]sx?$/`, the default for `unplugin-auto-import`, `unplugin-macros` and others) silently skipped every route file. The id now ends with a `lang.<ext>` marker, the same convention Vue SFCs use for `?vue&type=script&lang.ts`. Chunk filenames are unchanged.
|
|
60
101
|
|
|
61
102
|
- d8f1ea8: Apply the configured `nonce` to the two script tags that were still missing it, so a strict `script-src` CSP no longer needs `unsafe-inline`:
|
|
62
|
-
|
|
63
103
|
- The client-side redirect that streaming mode emits after the shell has already flushed (`<script>window.location=...</script>`) now carries the nonce.
|
|
64
104
|
- The SPA entry script tag now carries the nonce, matching the SSR entry script.
|
|
65
105
|
|
|
@@ -239,7 +279,6 @@
|
|
|
239
279
|
- 8256190: Rework `@solidjs/start/env`
|
|
240
280
|
- 6cbba24: Fix multiple Set-Cookie headers being lost on redirect responses
|
|
241
281
|
- d4cc548: ## Bump Seroval
|
|
242
|
-
|
|
243
282
|
- version `1.4.1`
|
|
244
283
|
|
|
245
284
|
- dd40610: Handle base url in api routes
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PluginOption } from "vite";
|
|
1
|
+
import type { PluginOption, FilterPattern } from "vite";
|
|
2
2
|
import { type Options as SolidOptions } from "vite-plugin-solid";
|
|
3
3
|
import { type ServerFunctionsOptions } from "../directives/index.ts";
|
|
4
4
|
import { type EnvPluginOptions } from "./env.ts";
|
|
@@ -14,6 +14,18 @@ export interface SolidStartOptions {
|
|
|
14
14
|
* @default "./src"
|
|
15
15
|
*/
|
|
16
16
|
appRoot?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Options related to the css crawling logic
|
|
19
|
+
*/
|
|
20
|
+
css?: {
|
|
21
|
+
/**
|
|
22
|
+
* Filter files included during css crawling in development.
|
|
23
|
+
*/
|
|
24
|
+
filter?: {
|
|
25
|
+
include?: FilterPattern;
|
|
26
|
+
exclude?: FilterPattern;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
17
29
|
/**
|
|
18
30
|
* Options forwarded to `vite-plugin-solid`.
|
|
19
31
|
*
|
package/dist/config/index.js
CHANGED
|
@@ -82,7 +82,7 @@ export function solidStart(options) {
|
|
|
82
82
|
appType: "custom",
|
|
83
83
|
build: {
|
|
84
84
|
assetsDir: "_build/assets",
|
|
85
|
-
|
|
85
|
+
rolldownOptions: {
|
|
86
86
|
output: {
|
|
87
87
|
// Keeps route chunks named after their file rather than after
|
|
88
88
|
// the `?pick=...` id that addresses them. See toPickId.
|
|
@@ -107,7 +107,7 @@ export function solidStart(options) {
|
|
|
107
107
|
write: true,
|
|
108
108
|
manifest: true,
|
|
109
109
|
outDir: "dist/client",
|
|
110
|
-
|
|
110
|
+
rolldownOptions: {
|
|
111
111
|
input: clientInput,
|
|
112
112
|
treeshake: true,
|
|
113
113
|
preserveEntrySignatures: "exports-only",
|
|
@@ -121,7 +121,7 @@ export function solidStart(options) {
|
|
|
121
121
|
write: true,
|
|
122
122
|
manifest: true,
|
|
123
123
|
copyPublicDir: false,
|
|
124
|
-
|
|
124
|
+
rolldownOptions: {
|
|
125
125
|
input: handlers.server,
|
|
126
126
|
},
|
|
127
127
|
outDir: "dist/server",
|
package/dist/config/lazy.js
CHANGED
|
@@ -58,12 +58,17 @@ const lazy = () => {
|
|
|
58
58
|
if (this.environment.name !== VITE_ENVIRONMENTS.client)
|
|
59
59
|
return;
|
|
60
60
|
for (const chunk of Object.values(bundle)) {
|
|
61
|
-
if (chunk.type !== "chunk" ||
|
|
61
|
+
if (chunk.type !== "chunk" || chunk.facadeModuleId)
|
|
62
|
+
continue;
|
|
63
|
+
if (!chunk.viteMetadata?.importedCss.size)
|
|
64
|
+
continue;
|
|
65
|
+
const moduleIds = chunk.moduleIds.filter(id => !id.endsWith("css"));
|
|
66
|
+
if (moduleIds.length <= 1)
|
|
62
67
|
continue;
|
|
63
68
|
// Has to follow Vites implementation:
|
|
64
69
|
// https://github.com/vitejs/vite/blob/4be37a8389c67873880f826b01fe40137e1c29a7/packages/vite/src/node/plugins/manifest.ts#L179
|
|
65
70
|
const chunkName = `_${basename(chunk.fileName)}`;
|
|
66
|
-
for (const id of
|
|
71
|
+
for (const id of moduleIds) {
|
|
67
72
|
sharedChunkNames[id] = chunkName;
|
|
68
73
|
}
|
|
69
74
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { type PluginOption } from "vite";
|
|
2
2
|
import { type SolidStartOptions } from "./index.ts";
|
|
3
|
+
type StyleFilterOptions = NonNullable<SolidStartOptions["css"]>["filter"];
|
|
4
|
+
export declare function createStyleFilter(options?: StyleFilterOptions): (id: unknown) => boolean;
|
|
3
5
|
export declare function manifest(start: SolidStartOptions): PluginOption;
|
|
6
|
+
export {};
|
package/dist/config/manifest.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { version as viteVersion } from "vite";
|
|
3
|
+
import { createFilter, version as viteVersion } from "vite";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { findStylesInModuleGraph } from "../server/collect-styles.js";
|
|
6
6
|
import { VIRTUAL_MODULES } from "./constants.js";
|
|
7
7
|
import { wrapId } from "./vite-utils.js";
|
|
8
|
+
const DEFAULT_STYLE_EXCLUDE = /node_modules/;
|
|
9
|
+
export function createStyleFilter(options) {
|
|
10
|
+
return createFilter(options?.include || [], options?.exclude || DEFAULT_STYLE_EXCLUDE);
|
|
11
|
+
}
|
|
8
12
|
export function manifest(start) {
|
|
9
13
|
let devServer = undefined;
|
|
14
|
+
const styleFilter = createStyleFilter(start.css?.filter);
|
|
10
15
|
return {
|
|
11
16
|
name: "solid-start:manifest-plugin",
|
|
12
17
|
enforce: "pre",
|
|
@@ -108,7 +113,7 @@ export function manifest(start) {
|
|
|
108
113
|
// Client env does not have css dependencies in mod.transformResult
|
|
109
114
|
// Aalways use ssr env instead, to prevent hydration mismatches
|
|
110
115
|
const env = devServer.environments["ssr"];
|
|
111
|
-
const styles = await findStylesInModuleGraph(env, id);
|
|
116
|
+
const styles = await findStylesInModuleGraph(env, id, styleFilter);
|
|
112
117
|
const cssAssets = Object.entries(styles).map(([key, value]) => `{
|
|
113
118
|
tag: "style",
|
|
114
119
|
attrs: {
|
|
@@ -12,6 +12,18 @@ function isInvalidForRemoval(path) {
|
|
|
12
12
|
}
|
|
13
13
|
return isPathValid(target, t.isObjectPattern) || isPathValid(target, t.isArrayPattern);
|
|
14
14
|
}
|
|
15
|
+
function countValidImport(node) {
|
|
16
|
+
if (node.importKind === "type") {
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
let count = 0;
|
|
20
|
+
for (const specifier of node.specifiers) {
|
|
21
|
+
if (specifier.type !== "ImportSpecifier" || specifier.importKind === "value") {
|
|
22
|
+
count += 1;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return count;
|
|
26
|
+
}
|
|
15
27
|
export function removeUnusedVariables(program) {
|
|
16
28
|
// TODO(Alexis):
|
|
17
29
|
// This implementation is simple but slow
|
|
@@ -34,7 +46,7 @@ export function removeUnusedVariables(program) {
|
|
|
34
46
|
if (binding.references === 0 && !binding.path.removed) {
|
|
35
47
|
const parent = binding.path.parentPath;
|
|
36
48
|
if (isPathValid(parent, t.isImportDeclaration)) {
|
|
37
|
-
if (parent.node
|
|
49
|
+
if (countValidImport(parent.node) <= 1) {
|
|
38
50
|
parent.remove();
|
|
39
51
|
}
|
|
40
52
|
else {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { DevEnvironment } from "vite";
|
|
2
|
+
type StyleFilter = (id: string) => boolean;
|
|
2
3
|
export declare const isCssModulesFile: (file: string) => boolean;
|
|
3
|
-
export declare function findStylesInModuleGraph(vite: DevEnvironment, id: string): Promise<Record<string, any>>;
|
|
4
|
+
export declare function findStylesInModuleGraph(vite: DevEnvironment, id: string, filter: StyleFilter): Promise<Record<string, any>>;
|
|
5
|
+
export {};
|
|
@@ -8,13 +8,16 @@ async function getViteModuleNode(vite, file, importer) {
|
|
|
8
8
|
}
|
|
9
9
|
catch (err) { }
|
|
10
10
|
}
|
|
11
|
-
async function findModuleDependencies(vite, file, deps, crawledFiles = new Set(), importer) {
|
|
11
|
+
async function findModuleDependencies(vite, file, deps, filter, crawledFiles = new Set(), importer) {
|
|
12
12
|
crawledFiles.add(file);
|
|
13
13
|
const module = await getViteModuleNode(vite, file, importer);
|
|
14
14
|
if (!module?.id || deps.has(module))
|
|
15
15
|
return;
|
|
16
16
|
deps.add(module);
|
|
17
|
-
if (module.url.endsWith(".css")
|
|
17
|
+
if (module.url.endsWith(".css"))
|
|
18
|
+
return;
|
|
19
|
+
// Apply user-config file filters only to real files (virtual modules should always be included)
|
|
20
|
+
if (module.file && !module.id.startsWith("\0") && !filter(module.file))
|
|
18
21
|
return;
|
|
19
22
|
if (!module.transformResult) {
|
|
20
23
|
await vite.transformRequest(module.id).catch(() => { });
|
|
@@ -28,7 +31,7 @@ async function findModuleDependencies(vite, file, deps, crawledFiles = new Set()
|
|
|
28
31
|
if (crawledFiles.has(dep)) {
|
|
29
32
|
continue;
|
|
30
33
|
}
|
|
31
|
-
await findModuleDependencies(vite, dep, deps, crawledFiles, module.id);
|
|
34
|
+
await findModuleDependencies(vite, dep, deps, filter, crawledFiles, module.id);
|
|
32
35
|
}
|
|
33
36
|
}
|
|
34
37
|
// Vite doesn't expose these so we just copy the list for now
|
|
@@ -38,11 +41,11 @@ const cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)$/;
|
|
|
38
41
|
const cssModulesRegExp = new RegExp(`\\.module${cssFileRegExp.source}`);
|
|
39
42
|
const isCssFile = (file) => cssFileRegExp.test(file);
|
|
40
43
|
export const isCssModulesFile = (file) => cssModulesRegExp.test(file);
|
|
41
|
-
export async function findStylesInModuleGraph(vite, id) {
|
|
44
|
+
export async function findStylesInModuleGraph(vite, id, filter) {
|
|
42
45
|
const absolute = path.resolve(process.cwd(), id);
|
|
43
46
|
const dependencies = new Set();
|
|
44
47
|
try {
|
|
45
|
-
await findModuleDependencies(vite, absolute, dependencies);
|
|
48
|
+
await findModuleDependencies(vite, absolute, dependencies, filter);
|
|
46
49
|
}
|
|
47
50
|
catch (e) {
|
|
48
51
|
console.error(e);
|
|
@@ -13,7 +13,7 @@ export function getClientDevManifest() {
|
|
|
13
13
|
return import(__rewriteRelativeImportExtension(/* @vite-ignore */ join("/", id), true));
|
|
14
14
|
},
|
|
15
15
|
async getAssets(id) {
|
|
16
|
-
const assetsPath = `/@manifest/client/${Date.now()}/assets?id=${id}`;
|
|
16
|
+
const assetsPath = `/@manifest/client/${Date.now()}/assets?id=${encodeURIComponent(id)}`;
|
|
17
17
|
const assets = (await import(__rewriteRelativeImportExtension(/* @vite-ignore */ assetsPath, true))).default;
|
|
18
18
|
return await Promise.all(assets.map(async (v) => ({
|
|
19
19
|
...v,
|
|
@@ -11,7 +11,7 @@ export function getSsrDevManifest(environment) {
|
|
|
11
11
|
return {
|
|
12
12
|
path: (id) => normalize(join(import.meta.env.BASE_URL, id)),
|
|
13
13
|
async getAssets(id) {
|
|
14
|
-
const assetsPath = `/@manifest/${environment}/${Date.now()}/assets?id=${id}`;
|
|
14
|
+
const assetsPath = `/@manifest/${environment}/${Date.now()}/assets?id=${encodeURIComponent(id)}`;
|
|
15
15
|
const assets = (await import(__rewriteRelativeImportExtension(/* @vite-ignore */ assetsPath, true))).default;
|
|
16
16
|
return await Promise.all(assets.map(async (v) => ({
|
|
17
17
|
...v,
|