@solidjs/start 2.0.0-beta.0 → 2.0.0-beta.2

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.
Files changed (91) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/config/dev-server.js +3 -1
  3. package/dist/config/fs-router.d.ts +1 -1
  4. package/dist/http/index.d.ts +4 -4
  5. package/package.json +11 -5
  6. package/scripts/build.js +0 -15
  7. package/scripts/validate-imports.js +0 -316
  8. package/src/client/StartClient.tsx +0 -34
  9. package/src/client/index.tsx +0 -2
  10. package/src/client/mount.ts +0 -1
  11. package/src/client/spa/index.tsx +0 -9
  12. package/src/config/constants.ts +0 -19
  13. package/src/config/dev-server.ts +0 -157
  14. package/src/config/env.ts +0 -105
  15. package/src/config/fs-router.ts +0 -162
  16. package/src/config/fs-routes/fs-watcher.ts +0 -66
  17. package/src/config/fs-routes/index.ts +0 -136
  18. package/src/config/fs-routes/router.ts +0 -184
  19. package/src/config/fs-routes/tree-shake.ts +0 -324
  20. package/src/config/index.ts +0 -239
  21. package/src/config/lazy.ts +0 -132
  22. package/src/config/manifest.ts +0 -120
  23. package/src/config/utils.ts +0 -5
  24. package/src/config/vite-utils.ts +0 -113
  25. package/src/directives/bubble-function-declaration.ts +0 -33
  26. package/src/directives/compile.ts +0 -54
  27. package/src/directives/generate-unique-name.ts +0 -22
  28. package/src/directives/get-descriptive-name.ts +0 -39
  29. package/src/directives/get-import-identifier.ts +0 -34
  30. package/src/directives/get-root-statement-path.ts +0 -14
  31. package/src/directives/index.ts +0 -233
  32. package/src/directives/is-statement-top-level.ts +0 -13
  33. package/src/directives/paths.ts +0 -63
  34. package/src/directives/plugin.ts +0 -389
  35. package/src/directives/remove-unused-variables.ts +0 -70
  36. package/src/directives/types.ts +0 -12
  37. package/src/directives/xxhash32.ts +0 -214
  38. package/src/env.d.ts +0 -17
  39. package/src/fns/client.ts +0 -141
  40. package/src/fns/handler.spec.ts +0 -85
  41. package/src/fns/handler.ts +0 -287
  42. package/src/fns/registration.ts +0 -19
  43. package/src/fns/serialization.ts +0 -250
  44. package/src/fns/server.ts +0 -46
  45. package/src/fns/shared.ts +0 -116
  46. package/src/http/index.ts +0 -216
  47. package/src/index.tsx +0 -7
  48. package/src/internal.d.ts +0 -14
  49. package/src/middleware/index.ts +0 -92
  50. package/src/router.tsx +0 -37
  51. package/src/server/StartServer.tsx +0 -58
  52. package/src/server/assets/PatchVirtualDevStyles.tsx +0 -31
  53. package/src/server/assets/index.ts +0 -70
  54. package/src/server/assets/render.tsx +0 -46
  55. package/src/server/collect-styles.ts +0 -70
  56. package/src/server/fetchEvent.spec.ts +0 -85
  57. package/src/server/fetchEvent.ts +0 -36
  58. package/src/server/handler.ts +0 -261
  59. package/src/server/index.tsx +0 -29
  60. package/src/server/manifest/client-manifest.ts +0 -8
  61. package/src/server/manifest/dev-client-manifest.ts +0 -21
  62. package/src/server/manifest/dev-ssr-manifest.ts +0 -23
  63. package/src/server/manifest/prod-client-manifest.ts +0 -21
  64. package/src/server/manifest/prod-ssr-manifest.ts +0 -109
  65. package/src/server/manifest/ssr-manifest.ts +0 -10
  66. package/src/server/routes.ts +0 -126
  67. package/src/server/spa/StartServer.tsx +0 -42
  68. package/src/server/spa/handler.ts +0 -29
  69. package/src/server/spa/index.tsx +0 -5
  70. package/src/server/types.ts +0 -82
  71. package/src/server/util.ts +0 -12
  72. package/src/shared/ErrorBoundary.tsx +0 -52
  73. package/src/shared/GET.ts +0 -8
  74. package/src/shared/HttpHeader.tsx +0 -42
  75. package/src/shared/HttpStatusCode.ts +0 -27
  76. package/src/shared/clientOnly.ts +0 -44
  77. package/src/shared/dev-overlay/CodeView.tsx +0 -90
  78. package/src/shared/dev-overlay/DevOverlayDialog.tsx +0 -316
  79. package/src/shared/dev-overlay/createStackFrame.ts +0 -74
  80. package/src/shared/dev-overlay/download.ts +0 -6
  81. package/src/shared/dev-overlay/env.d.ts +0 -4
  82. package/src/shared/dev-overlay/get-source-map.ts +0 -33
  83. package/src/shared/dev-overlay/icons.tsx +0 -456
  84. package/src/shared/dev-overlay/index.tsx +0 -63
  85. package/src/shared/dev-overlay/styles.css +0 -292
  86. package/src/shared/lazy.ts +0 -52
  87. package/src/shared/serverFunction.ts +0 -10
  88. package/src/utils/debounce.ts +0 -10
  89. package/src/virtual.d.ts +0 -27
  90. package/tsconfig.json +0 -24
  91. package/vitest.config.ts +0 -9
@@ -1,324 +0,0 @@
1
- // All credit for this work goes to the amazing Next.js team.
2
- // https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/plugins/next-ssg-transform.ts
3
- // This is adapted to work with routeData functions. It can be run in two modes, one which preserves the routeData and the Component in the same file, and one which creates a
4
-
5
- import type * as Babel from "@babel/core";
6
- import type { NodePath, PluginObj, PluginPass } from "@babel/core";
7
- import type { Binding } from "@babel/traverse";
8
- import { basename } from "pathe";
9
- import type { Plugin } from "vite";
10
-
11
- type State = Omit<PluginPass, "opts"> & {
12
- opts: { pick: string[] };
13
- refs: Set<any>;
14
- done: boolean;
15
- };
16
-
17
- function treeShakeTransform({ types: t }: typeof Babel): PluginObj<State> {
18
- function getIdentifier(path: any) {
19
- const parentPath = path.parentPath;
20
- if (parentPath.type === "VariableDeclarator") {
21
- const pp = parentPath;
22
- const name = pp.get("id");
23
- return name.node.type === "Identifier" ? name : null;
24
- }
25
- if (parentPath.type === "AssignmentExpression") {
26
- const pp = parentPath;
27
- const name = pp.get("left");
28
- return name.node.type === "Identifier" ? name : null;
29
- }
30
- if (path.node.type === "ArrowFunctionExpression") {
31
- return null;
32
- }
33
- return path.node.id && path.node.id.type === "Identifier" ? path.get("id") : null;
34
- }
35
-
36
- function isIdentifierReferenced(ident: any) {
37
- const b: Binding | undefined = ident.scope.getBinding(ident.node.name);
38
- if (b?.referenced) {
39
- if (b.path.type === "FunctionDeclaration") {
40
- return !b.constantViolations
41
- .concat(b.referencePaths)
42
- .every(ref => ref.findParent(p => p === b.path));
43
- }
44
- return true;
45
- }
46
- return false;
47
- }
48
- function markFunction(path: any, state: any) {
49
- const ident = getIdentifier(path);
50
- if (ident && ident.node && isIdentifierReferenced(ident)) {
51
- state.refs.add(ident);
52
- }
53
- }
54
- function markImport(path: any, state: any) {
55
- const local = path.get("local");
56
- if (isIdentifierReferenced(local)) {
57
- state.refs.add(local);
58
- }
59
- }
60
-
61
- return {
62
- visitor: {
63
- Program: {
64
- enter(path, state) {
65
- state.refs = new Set();
66
- state.done = false;
67
- path.traverse(
68
- {
69
- VariableDeclarator(variablePath, variableState: any) {
70
- if (variablePath.node.id.type === "Identifier") {
71
- const local = variablePath.get("id");
72
- if (isIdentifierReferenced(local)) {
73
- variableState.refs.add(local);
74
- }
75
- } else if (variablePath.node.id.type === "ObjectPattern") {
76
- const pattern = variablePath.get("id");
77
- const properties = pattern.get("properties") as Array<NodePath>;
78
- properties.forEach(p => {
79
- const local = p.get(
80
- p.node.type === "ObjectProperty"
81
- ? "value"
82
- : p.node.type === "RestElement"
83
- ? "argument"
84
- : (() => {
85
- throw new Error("invariant");
86
- })(),
87
- );
88
- if (isIdentifierReferenced(local)) {
89
- variableState.refs.add(local);
90
- }
91
- });
92
- } else if (variablePath.node.id.type === "ArrayPattern") {
93
- const pattern = variablePath.get("id");
94
- const elements = pattern.get("elements") as Array<NodePath>;
95
- elements.forEach(e => {
96
- let local: NodePath<any>;
97
- if (e.node && e.node.type === "Identifier") {
98
- local = e;
99
- } else if (e.node && e.node.type === "RestElement") {
100
- local = e.get("argument");
101
- } else {
102
- return;
103
- }
104
- if (isIdentifierReferenced(local)) {
105
- variableState.refs.add(local);
106
- }
107
- });
108
- }
109
- },
110
- ExportDefaultDeclaration(exportNamedPath) {
111
- // if opts.keep is true, we don't remove the routeData export
112
- if (state.opts.pick && !state.opts.pick.includes("default")) {
113
- exportNamedPath.remove();
114
- }
115
- },
116
- ExportNamedDeclaration(exportNamedPath) {
117
- // if opts.keep is false, we don't remove the routeData export
118
- if (!state.opts.pick) {
119
- return;
120
- }
121
- const specifiers = exportNamedPath.get("specifiers");
122
- if (specifiers.length) {
123
- specifiers.forEach(s => {
124
- if (
125
- t.isIdentifier(s.node.exported)
126
- ? s.node.exported.name
127
- : state.opts.pick.includes(s.node.exported.value)
128
- ) {
129
- s.remove();
130
- }
131
- });
132
- if (exportNamedPath.node.specifiers.length < 1) {
133
- exportNamedPath.remove();
134
- }
135
- return;
136
- }
137
- const decl = exportNamedPath.get("declaration");
138
- if (decl == null || decl.node == null) {
139
- return;
140
- }
141
- switch (decl.node.type) {
142
- case "FunctionDeclaration": {
143
- const name = decl.node.id?.name;
144
- if (name && state.opts.pick && !state.opts.pick.includes(name)) {
145
- exportNamedPath.remove();
146
- }
147
- break;
148
- }
149
- case "VariableDeclaration": {
150
- const inner = decl.get("declarations") as Array<NodePath<any>>;
151
- inner.forEach(d => {
152
- if (d.node.id.type !== "Identifier") {
153
- return;
154
- }
155
- const name = d.node.id.name;
156
- if (state.opts.pick && !state.opts.pick.includes(name)) {
157
- d.remove();
158
- }
159
- });
160
- break;
161
- }
162
- default: {
163
- break;
164
- }
165
- }
166
- },
167
- FunctionDeclaration: markFunction,
168
- FunctionExpression: markFunction,
169
- ArrowFunctionExpression: markFunction,
170
- ImportSpecifier: markImport,
171
- ImportDefaultSpecifier: markImport,
172
- ImportNamespaceSpecifier: markImport,
173
- ImportDeclaration: (path, state) => {
174
- if (
175
- path.node.source.value.endsWith(".css") &&
176
- state.opts.pick &&
177
- !state.opts.pick.includes("$css")
178
- ) {
179
- path.remove();
180
- }
181
- },
182
- },
183
- state,
184
- );
185
-
186
- const refs = state.refs;
187
- let count = 0;
188
- const sweepFunction = (sweepPath: any) => {
189
- const ident = getIdentifier(sweepPath);
190
- if (ident && ident.node && refs.has(ident) && !isIdentifierReferenced(ident)) {
191
- ++count;
192
- if (
193
- t.isAssignmentExpression(sweepPath.parentPath) ||
194
- t.isVariableDeclarator(sweepPath.parentPath)
195
- ) {
196
- sweepPath.parentPath.remove();
197
- } else {
198
- sweepPath.remove();
199
- }
200
- }
201
- };
202
- function sweepImport(sweepPath: any) {
203
- const local = sweepPath.get("local");
204
- if (refs.has(local) && !isIdentifierReferenced(local)) {
205
- ++count;
206
- sweepPath.remove();
207
- if (sweepPath.parent.specifiers.length === 0) {
208
- sweepPath.parentPath.remove();
209
- }
210
- }
211
- }
212
- do {
213
- path.scope.crawl();
214
- count = 0;
215
- path.traverse({
216
- VariableDeclarator(variablePath) {
217
- if (variablePath.node.id.type === "Identifier") {
218
- const local = variablePath.get("id");
219
- if (refs.has(local) && !isIdentifierReferenced(local)) {
220
- ++count;
221
- variablePath.remove();
222
- }
223
- } else if (variablePath.node.id.type === "ObjectPattern") {
224
- const pattern = variablePath.get("id");
225
- const beforeCount = count;
226
- const properties = pattern.get("properties");
227
- properties.forEach(p => {
228
- const local = p.get(
229
- p.node.type === "ObjectProperty"
230
- ? "value"
231
- : p.node.type === "RestElement"
232
- ? "argument"
233
- : (() => {
234
- throw new Error("invariant");
235
- })(),
236
- );
237
- if (refs.has(local) && !isIdentifierReferenced(local)) {
238
- ++count;
239
- p.remove();
240
- }
241
- });
242
- if (beforeCount !== count && pattern.get("properties").length < 1) {
243
- variablePath.remove();
244
- }
245
- } else if (variablePath.node.id.type === "ArrayPattern") {
246
- const pattern = variablePath.get("id");
247
- const beforeCount = count;
248
- const elements = pattern.get("elements");
249
- elements.forEach(e => {
250
- let local: NodePath<any> | undefined;
251
- if (e.node && e.node.type === "Identifier") {
252
- local = e;
253
- } else if (e.node && e.node.type === "RestElement") {
254
- local = e.get("argument");
255
- } else {
256
- return;
257
- }
258
- if (refs.has(local) && !isIdentifierReferenced(local)) {
259
- ++count;
260
- e.remove();
261
- }
262
- });
263
- if (beforeCount !== count && pattern.get("elements").length < 1) {
264
- variablePath.remove();
265
- }
266
- }
267
- },
268
- FunctionDeclaration: sweepFunction,
269
- FunctionExpression: sweepFunction,
270
- ArrowFunctionExpression: sweepFunction,
271
- ImportSpecifier: sweepImport,
272
- ImportDefaultSpecifier: sweepImport,
273
- ImportNamespaceSpecifier: sweepImport,
274
- });
275
- } while (count);
276
- },
277
- },
278
- },
279
- };
280
- }
281
-
282
- export function treeShake(): Plugin {
283
- async function transform(id: string, code: string) {
284
- const [path, queryString] = id.split("?");
285
- const query = new URLSearchParams(queryString);
286
- if (query.has("pick")) {
287
- const babel = await import("@babel/core");
288
- const transformed = await babel.transformAsync(code, {
289
- plugins: [[treeShakeTransform, { pick: query.getAll("pick") }]],
290
- parserOpts: {
291
- plugins: ["jsx", "typescript"],
292
- },
293
- filename: basename(id),
294
- ast: false,
295
- sourceMaps: true,
296
- configFile: false,
297
- babelrc: false,
298
- sourceFileName: id,
299
- });
300
-
301
- return transformed;
302
- }
303
- }
304
- return {
305
- name: "tree-shake",
306
- enforce: "pre",
307
- async transform(code, id) {
308
- const [path, queryString] = id.split("?");
309
- if (!path) return;
310
- const query = new URLSearchParams(queryString);
311
- const ext = path.split(".").pop();
312
- if (!ext) return;
313
- if (query.has("pick") && ["js", "jsx", "ts", "tsx"].includes(ext)) {
314
- const transformed = await transform(id, code);
315
- if (!transformed?.code) return;
316
-
317
- return {
318
- code: transformed.code,
319
- map: transformed.map,
320
- };
321
- }
322
- },
323
- };
324
- }
@@ -1,239 +0,0 @@
1
- import { defu } from "defu";
2
- import { globSync } from "node:fs";
3
- import { extname, isAbsolute, join } from "node:path";
4
- import type { PluginOption } from "vite";
5
- import solid, { type Options as SolidOptions } from "vite-plugin-solid";
6
- import { type ServerFunctionsOptions, serverFunctionsPlugin } from "../directives/index.ts";
7
- import { DEFAULT_EXTENSIONS, VIRTUAL_MODULES, VITE_ENVIRONMENTS } from "./constants.ts";
8
- import { devServer } from "./dev-server.ts";
9
- import { envPlugin, type EnvPluginOptions } from "./env.ts";
10
- import { SolidStartClientFileRouter, SolidStartServerFileRouter } from "./fs-router.ts";
11
- import { fsRoutes } from "./fs-routes/index.ts";
12
- import type { BaseFileSystemRouter } from "./fs-routes/router.ts";
13
- import lazy from "./lazy.ts";
14
- import { manifest } from "./manifest.ts";
15
- import { parseIdQuery } from "./utils.ts";
16
-
17
- export interface SolidStartOptions {
18
- solid?: Partial<SolidOptions>;
19
- ssr?: boolean;
20
- routeDir?: string;
21
- extensions?: string[];
22
- middleware?: string;
23
- serialization?: {
24
- /**
25
- * The serialization mode to use for server functions/actions.
26
- * The "js" mode uses a custom binary format that is more efficient than JSON, but requires a custom deserializer (with `eval()`) on the client.
27
- * A strong CSP should block `eval()` executions, which would prevent the "js" mode from working.
28
- * The "json" mode uses JSON for serialization, which is less efficient but can be deserialized with `JSON.parse` on the client.
29
- *
30
- * @default "json"
31
- */
32
- mode?: "js" | "json";
33
- };
34
- env?: EnvPluginOptions;
35
- serverFunctions?: Pick<ServerFunctionsOptions, "filter">;
36
- }
37
-
38
- const absolute = (path: string, root: string) =>
39
- path ? (isAbsolute(path) ? path : join(root, path)) : path;
40
-
41
- export function solidStart(options?: SolidStartOptions): Array<PluginOption> {
42
- const start = defu(options ?? {}, {
43
- appRoot: "./src",
44
- routeDir: "./routes",
45
- ssr: true,
46
- devOverlay: true,
47
- experimental: {
48
- islands: false,
49
- },
50
- solid: {},
51
- extensions: [],
52
- });
53
- const extensions = [...DEFAULT_EXTENSIONS, ...(start.extensions || [])];
54
- const routeDir = join(start.appRoot, start.routeDir);
55
- const root = process.cwd();
56
- const appEntryPath = globSync(join(root, start.appRoot, "app.{j,t}sx"))[0];
57
- if (!appEntryPath) {
58
- throw new Error(`Could not find an app jsx/tsx entry in ${start.appRoot}.`);
59
- }
60
- const entryExtension = extname(appEntryPath);
61
- const handlers = {
62
- client: `${start.appRoot}/entry-client${entryExtension}`,
63
- server: `${start.appRoot}/entry-server${entryExtension}`,
64
- };
65
- return [
66
- // TODO (Alexis): check if the comment below is still relevant
67
- //
68
- // Must be placed after fsRoutes, as treeShake will remove the
69
- // server fn exports added in by this plugin
70
- serverFunctionsPlugin({
71
- manifest: VIRTUAL_MODULES.serverFnManifest,
72
- runtime: {
73
- server: '@solidjs/start/fns/server',
74
- client: '@solidjs/start/fns/client',
75
- },
76
- filter: options?.serverFunctions?.filter,
77
- }),
78
- {
79
- name: "solid-start:config",
80
- enforce: "pre",
81
- configEnvironment(name) {
82
- return {
83
- resolve: {
84
- // remove when https://github.com/solidjs/vite-plugin-solid/pull/228 is released
85
- externalConditions: ["solid", "node"],
86
- },
87
- };
88
- },
89
- async config(_, env) {
90
- const clientInput = [handlers.client];
91
- if (env.command === "build") {
92
- const clientRouter: BaseFileSystemRouter = (globalThis as any).ROUTERS.client;
93
- for (const route of await clientRouter.getRoutes()) {
94
- for (const [key, value] of Object.entries(route)) {
95
- if (value && key.startsWith("$") && !key.startsWith("$$")) {
96
- function toRouteId(route: any) {
97
- return `${route.src}?${route.pick.map((p: string) => `pick=${p}`).join("&")}`;
98
- }
99
- clientInput.push(toRouteId(value));
100
- }
101
- }
102
- }
103
- }
104
- return {
105
- appType: "custom",
106
- build: { assetsDir: "_build/assets" },
107
- optimizeDeps: {
108
- // Suppress TS errors from Vite 7 types when configuring Vite 8's Rolldown
109
- ...({
110
- rolldownOptions: {
111
- transform: {
112
- jsx: "react",
113
- },
114
- },
115
- } as any),
116
- },
117
- environments: {
118
- [VITE_ENVIRONMENTS.client]: {
119
- consumer: "client",
120
- build: {
121
- write: true,
122
- manifest: true,
123
- outDir: "dist/client",
124
- rollupOptions: {
125
- input: clientInput,
126
- treeshake: true,
127
- preserveEntrySignatures: "exports-only",
128
- },
129
- },
130
- },
131
- [VITE_ENVIRONMENTS.server]: {
132
- consumer: "server",
133
- build: {
134
- ssr: true,
135
- write: true,
136
- manifest: true,
137
- copyPublicDir: false,
138
- rollupOptions: {
139
- input: "~/entry-server.tsx",
140
- },
141
- outDir: "dist/server",
142
- commonjsOptions: {
143
- include: [/node_modules/],
144
- },
145
- },
146
- },
147
- },
148
- resolve: {
149
- alias: {
150
- "@solidjs/start/server/entry": handlers.server,
151
- "~": join(process.cwd(), start.appRoot),
152
- ...(!start.ssr
153
- ? {
154
- "@solidjs/start/server": "@solidjs/start/server/spa",
155
- "@solidjs/start/client": "@solidjs/start/client/spa",
156
- }
157
- : {}),
158
- },
159
- // Depending on the package manager and dependency structure Vite externalizes @solidjs/start
160
- // This makes sure that @solidjs/start goes through the Vite build process
161
- noExternal: ["@solidjs/start"],
162
- },
163
- define: {
164
- "import.meta.env.MANIFEST": `globalThis.MANIFEST`,
165
- "import.meta.env.START_SSR": JSON.stringify(start.ssr),
166
- // Use JSON.stringify so backslashes on Windows are escaped and
167
- // esbuild receives a valid JS string literal for the define value
168
- "import.meta.env.START_APP_ENTRY": JSON.stringify(appEntryPath),
169
- "import.meta.env.START_CLIENT_ENTRY": JSON.stringify(handlers.client),
170
- "import.meta.env.START_DEV_OVERLAY": JSON.stringify(start.devOverlay),
171
- "import.meta.env.SEROVAL_MODE": JSON.stringify(start.serialization?.mode || "json"),
172
- },
173
- builder: {
174
- sharedPlugins: true,
175
- async buildApp(builder) {
176
- const client = builder.environments[VITE_ENVIRONMENTS.client];
177
- const server = builder.environments[VITE_ENVIRONMENTS.server];
178
-
179
- if (!client) throw new Error("Client environment not found");
180
- if (!server) throw new Error("SSR environment not found");
181
-
182
- if (!client.isBuilt) await builder.build(client);
183
- if (!server.isBuilt) await builder.build(server);
184
- },
185
- },
186
- };
187
- },
188
- },
189
- manifest(start),
190
- fsRoutes({
191
- routers: {
192
- client: new SolidStartClientFileRouter({
193
- dir: absolute(routeDir, root),
194
- extensions,
195
- }),
196
- ssr: new SolidStartServerFileRouter({
197
- dir: absolute(routeDir, root),
198
- extensions,
199
- dataOnly: !start.ssr,
200
- }),
201
- },
202
- }),
203
- lazy(),
204
- envPlugin(options?.env),
205
- {
206
- name: "solid-start:virtual-modules",
207
- async resolveId(id) {
208
- const { filename, query } = parseIdQuery(id);
209
-
210
- let base;
211
- if (filename === VIRTUAL_MODULES.clientEntry) base = handlers.client;
212
- if (filename === VIRTUAL_MODULES.serverEntry) base = handlers.server;
213
- if (filename === VIRTUAL_MODULES.app) base = appEntryPath;
214
-
215
- if (base) {
216
- let id = (await this.resolve(base))?.id;
217
- if (!id) return;
218
-
219
- if (query.size > 0) id += `?${query.toString()}`;
220
- return id;
221
- }
222
- },
223
- },
224
- {
225
- name: "solid-start:capture-client-bundle",
226
- enforce: "post",
227
- generateBundle(options, bundle) {
228
- globalThis.START_CLIENT_BUNDLE = bundle;
229
- (globalThis as any).START_CLIENT_OUT_DIR = options.dir;
230
- },
231
- },
232
- devServer(),
233
- solid({
234
- ...start.solid,
235
- ssr: true,
236
- extensions: extensions.map(ext => `.${ext}`),
237
- }),
238
- ];
239
- }
@@ -1,132 +0,0 @@
1
- import type { PluginItem } from "@babel/core";
2
- import babel from "@babel/core";
3
- import * as t from "@babel/types";
4
- import { sep as osSep } from "node:path";
5
- import { basename, relative, sep } from "node:path/posix";
6
- import type { PluginOption } from "vite";
7
- import { VITE_ENVIRONMENTS } from "./constants.ts";
8
-
9
- const idTransform = (id: string): PluginItem => {
10
- return {
11
- visitor: {
12
- Program(path) {
13
- path.node.body.unshift(
14
- t.exportNamedDeclaration(
15
- t.variableDeclaration("const", [
16
- t.variableDeclarator(t.identifier("id$$"), t.stringLiteral(id)),
17
- ]),
18
- ),
19
- );
20
- },
21
- },
22
- };
23
- };
24
-
25
- const importTransform = (): PluginItem => {
26
- return {
27
- visitor: {
28
- ImportDeclaration(path) {
29
- if (path.node.source.value !== "solid-js") return;
30
- path.traverse({
31
- ImportSpecifier(subPath) {
32
- if (subPath.node.local.name !== "lazy") return;
33
- subPath.remove();
34
- path.insertAfter(
35
- t.importDeclaration(
36
- [t.importSpecifier(t.identifier("lazy"), t.identifier("lazy"))],
37
- t.stringLiteral("@solidjs/start/server"),
38
- ),
39
- );
40
- },
41
- });
42
- },
43
- },
44
- };
45
- };
46
-
47
- const fileEndingRegex = /(ts|js)x(\?.*)?$/;
48
-
49
- const lazy = (): PluginOption => {
50
- const cwd = process.cwd().replaceAll(osSep, sep);
51
-
52
- /**
53
- * Maps module ids to their client-specific shared chunk names.
54
- * Modules in shared chunks need to find their assets via the chunk name, instead of their module id.
55
- *
56
- * Vite includes assets of such modules in the manifest via the chunk name:
57
- * https://github.com/vitejs/vite/blob/4be37a8389c67873880f826b01fe40137e1c29a7/packages/vite/src/node/plugins/manifest.ts#L179
58
- * https://github.com/vitejs/vite/blob/4be37a8389c67873880f826b01fe40137e1c29a7/packages/vite/src/node/plugins/manifest.ts#L319
59
- *
60
- * Rollup occassionally creates shared chunks automatically,
61
- * but they can also be manually created by the user via:
62
- * https://rollupjs.org/configuration-options/#output-manualchunks
63
- *
64
- * More infos on Rollup's logic:
65
- * https://github.com/rollup/rollup/issues/3772#issuecomment-689955168
66
- */
67
- const sharedChunkNames: Record<string, string> = {};
68
-
69
- return {
70
- name: "solid-lazy-css",
71
- enforce: "pre",
72
- generateBundle(_, bundle) {
73
- if (this.environment.name !== VITE_ENVIRONMENTS.client) return;
74
-
75
- for (const chunk of Object.values(bundle)) {
76
- if (chunk.type !== "chunk" || !chunk.isDynamicEntry || chunk.facadeModuleId) continue;
77
-
78
- // Has to follow Vites implementation:
79
- // https://github.com/vitejs/vite/blob/4be37a8389c67873880f826b01fe40137e1c29a7/packages/vite/src/node/plugins/manifest.ts#L179
80
- const chunkName = `_${basename(chunk.fileName)}`;
81
- for (const id of chunk.moduleIds) {
82
- sharedChunkNames[id] = chunkName;
83
- }
84
- }
85
- },
86
- async transform(src, id) {
87
- if (this.environment.name !== VITE_ENVIRONMENTS.server) return;
88
- if (!id.match(fileEndingRegex)) return;
89
-
90
- // The transformed files either import "lazy" or css files
91
- // Therefore we skip, if the src doesn't have any import
92
- if (src.indexOf("import") === -1) return;
93
- if (id.includes("entry-server")) return;
94
-
95
- const plugins: PluginItem[] = [];
96
-
97
- const hasDefaultExport = src.indexOf("export default") !== -1;
98
- if (hasDefaultExport) {
99
- const localId = relative(cwd, id);
100
- const chunkName = sharedChunkNames[id];
101
- plugins.push(idTransform(chunkName ?? localId));
102
- }
103
-
104
- const hasLazy = src.indexOf("lazy(") !== -1;
105
- if (hasLazy) plugins.push(importTransform());
106
-
107
- if (!plugins.length) {
108
- return;
109
- }
110
-
111
- const transformed = await babel.transformAsync(src, {
112
- plugins,
113
- parserOpts: {
114
- plugins: ["jsx", "typescript"],
115
- },
116
- filename: basename(id),
117
- ast: false,
118
- sourceMaps: true,
119
- configFile: false,
120
- babelrc: false,
121
- sourceFileName: id,
122
- });
123
-
124
- if (!transformed?.code) return;
125
-
126
- const { code, map } = transformed;
127
- return { code, map };
128
- },
129
- };
130
- };
131
-
132
- export default lazy;