@solidjs/vite-plugin 3.0.0-next.37 → 3.0.0-next.38
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/README.md +47 -8
- package/dist/cjs/index.cjs +390 -74
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.mjs +392 -76
- package/dist/esm/index.mjs.map +1 -1
- package/dist/types/src/diagnostics/index.d.ts +14 -1
- package/dist/types/src/index.d.ts +16 -8
- package/dist/types/src/server-functions/compile.d.ts +2 -0
- package/dist/types/src/server-functions/index.d.ts +17 -10
- package/dist/types/src/ssr/index.d.ts +6 -5
- package/dist/types/src/tsrx.d.ts +11 -0
- package/package.json +3 -3
package/dist/esm/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as babel from '@babel/core';
|
|
2
2
|
import remapping from '@ampproject/remapping';
|
|
3
3
|
import solid from '@solidjs/babel-plugin';
|
|
4
|
-
import { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync } from 'fs';
|
|
4
|
+
import fs, { existsSync, readFileSync, mkdirSync, writeFileSync, rmSync } from 'fs';
|
|
5
5
|
import { mergeAndConcat } from 'merge-anything';
|
|
6
6
|
import { createRequire } from 'module';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { Readable } from 'node:stream';
|
|
9
|
-
import { createFilter, normalizePath, loadEnv, runnerImport, defaultClientConditions, defaultServerConditions, defaultExternalConditions } from 'vite';
|
|
9
|
+
import { createFilter, normalizePath, loadEnv, runnerImport, transformWithOxc, defaultClientConditions, defaultServerConditions, defaultExternalConditions } from 'vite';
|
|
10
10
|
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
11
11
|
import { crawlFrameworkPkgs } from 'vitefu';
|
|
12
12
|
|
|
@@ -146,6 +146,75 @@ function joinBase(base, pathname) {
|
|
|
146
146
|
return (base.endsWith('/') ? base.slice(0, -1) : base) + pathname;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
const TSRX_CSS_QUERY = '?solid-tsrx-css&lang.css';
|
|
150
|
+
const NULL_BYTE_PLACEHOLDER$1 = '/@id/__x00__';
|
|
151
|
+
function cleanModuleId(id) {
|
|
152
|
+
const query = id.indexOf('?');
|
|
153
|
+
return query === -1 ? id : id.slice(0, query);
|
|
154
|
+
}
|
|
155
|
+
function isTsrxModule(id) {
|
|
156
|
+
return cleanModuleId(id).toLowerCase().endsWith('.tsrx');
|
|
157
|
+
}
|
|
158
|
+
function isTsrxCssModule(id) {
|
|
159
|
+
const unwrapped = id.startsWith('\0') ? id.slice(1) : id.startsWith(NULL_BYTE_PLACEHOLDER$1) ? id.slice(NULL_BYTE_PLACEHOLDER$1.length) : id;
|
|
160
|
+
const queryIndex = unwrapped.indexOf('?');
|
|
161
|
+
if (queryIndex === -1 || !unwrapped.slice(0, queryIndex).toLowerCase().endsWith('.tsrx')) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
const params = unwrapped.slice(queryIndex + 1).split('&');
|
|
165
|
+
return params.includes('solid-tsrx-css') && params.includes('lang.css');
|
|
166
|
+
}
|
|
167
|
+
function resolveTsrxCssModule(id) {
|
|
168
|
+
if (!isTsrxCssModule(id)) return null;
|
|
169
|
+
if (id.startsWith('\0')) return id;
|
|
170
|
+
if (id.startsWith(NULL_BYTE_PLACEHOLDER$1)) {
|
|
171
|
+
return '\0' + id.slice(NULL_BYTE_PLACEHOLDER$1.length);
|
|
172
|
+
}
|
|
173
|
+
return '\0' + id;
|
|
174
|
+
}
|
|
175
|
+
function tsrxCssModuleId(id) {
|
|
176
|
+
return cleanModuleId(id) + TSRX_CSS_QUERY;
|
|
177
|
+
}
|
|
178
|
+
function resolvedTsrxCssModuleId(id) {
|
|
179
|
+
return '\0' + tsrxCssModuleId(id);
|
|
180
|
+
}
|
|
181
|
+
function tsrxCssSourceId(id) {
|
|
182
|
+
if (!id.startsWith('\0') || !isTsrxCssModule(id)) return null;
|
|
183
|
+
return cleanModuleId(id.slice(1));
|
|
184
|
+
}
|
|
185
|
+
function updateTsrxCss(cache, id, css) {
|
|
186
|
+
const key = cleanModuleId(id);
|
|
187
|
+
if (css) {
|
|
188
|
+
cache.set(key, css);
|
|
189
|
+
} else {
|
|
190
|
+
cache.delete(key);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function prependTsrxCssImport(code, id) {
|
|
194
|
+
return `import ${JSON.stringify(tsrxCssModuleId(id))};\n${code}`;
|
|
195
|
+
}
|
|
196
|
+
function offsetSourceMapLine(map) {
|
|
197
|
+
if (map && typeof map === 'object' && 'mappings' in map && typeof map.mappings === 'string') {
|
|
198
|
+
return {
|
|
199
|
+
...map,
|
|
200
|
+
mappings: ';' + map.mappings
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
if (map && typeof map === 'object' && 'sections' in map && Array.isArray(map.sections)) {
|
|
204
|
+
return {
|
|
205
|
+
...map,
|
|
206
|
+
sections: map.sections.map(section => ({
|
|
207
|
+
...section,
|
|
208
|
+
offset: {
|
|
209
|
+
...section.offset,
|
|
210
|
+
line: section.offset.line + 1
|
|
211
|
+
}
|
|
212
|
+
}))
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return map;
|
|
216
|
+
}
|
|
217
|
+
|
|
149
218
|
/**
|
|
150
219
|
* Dev-mode asset resolution: the `virtual:solid-manifest` module exports a
|
|
151
220
|
* resolver function in dev (instead of the static object a build produces),
|
|
@@ -255,6 +324,9 @@ const cssFileRegExp = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)$/;
|
|
|
255
324
|
// importer controls them — so they must not be SSR'd as style tags.
|
|
256
325
|
const nonAmbientQueryRegExp = /[?&](url|inline|raw)\b/;
|
|
257
326
|
const NULL_BYTE_PLACEHOLDER = '/@id/__x00__';
|
|
327
|
+
function isCssModuleUrl(url) {
|
|
328
|
+
return cssFileRegExp.test(url.split('?')[0]) || isTsrxCssModule(url);
|
|
329
|
+
}
|
|
258
330
|
|
|
259
331
|
// Per Vite's convention virtual module ids are prefixed with `\0`, which
|
|
260
332
|
// cannot appear in an HTML attribute (the parser replaces it). Serialize the
|
|
@@ -311,7 +383,7 @@ async function collectModuleDeps(env, file, deps, crawled, filter, onFile, impor
|
|
|
311
383
|
const node = await getModuleNode(env, file, importer);
|
|
312
384
|
if (!node?.id || deps.has(node)) return;
|
|
313
385
|
deps.add(node);
|
|
314
|
-
const isCss =
|
|
386
|
+
const isCss = isCssModuleUrl(node.url);
|
|
315
387
|
if (!isCss && node.file && !node.id.startsWith('\0') && !filter(node.file)) return;
|
|
316
388
|
if (node.file) onFile?.(node.file);
|
|
317
389
|
if (isCss) return;
|
|
@@ -343,8 +415,7 @@ async function collectDevStyleSources(env, files, onFile, filter = defaultStyleF
|
|
|
343
415
|
const seen = new Set();
|
|
344
416
|
for (const node of deps) {
|
|
345
417
|
if (!node.id) continue;
|
|
346
|
-
|
|
347
|
-
if (!cssFileRegExp.test(cleanUrl) || nonAmbientQueryRegExp.test(node.url)) continue;
|
|
418
|
+
if (!isCssModuleUrl(node.url) || nonAmbientQueryRegExp.test(node.url)) continue;
|
|
348
419
|
const id = wrapId(node.id);
|
|
349
420
|
if (seen.has(id)) continue;
|
|
350
421
|
seen.add(id);
|
|
@@ -558,7 +629,11 @@ function boundaryModules() {
|
|
|
558
629
|
}
|
|
559
630
|
|
|
560
631
|
/**
|
|
561
|
-
* Agent diagnostics surface (
|
|
632
|
+
* Agent diagnostics surface (dev serve only).
|
|
633
|
+
*
|
|
634
|
+
* Enabled automatically when the app declares `@solidjs/diagnostics` in
|
|
635
|
+
* its package.json (the `diagnostics` option overrides: `true` forces it
|
|
636
|
+
* on and errors if the package is missing, `false` opts out entirely).
|
|
562
637
|
*
|
|
563
638
|
* Three pieces:
|
|
564
639
|
* - an injected client module (virtual, imported by index.html or the
|
|
@@ -586,6 +661,36 @@ const METHODS = ['begin', 'end', 'active', 'whyDidRun', 'costs'];
|
|
|
586
661
|
|
|
587
662
|
/** How long the endpoint waits for a page to answer before failing the call. */
|
|
588
663
|
const RESPONSE_TIMEOUT_MS = 10_000;
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Whether the app *declares* `@solidjs/diagnostics` — the auto-enable
|
|
667
|
+
* signal. Declaration in the nearest package.json (walking up from the
|
|
668
|
+
* Vite root, so a `client/` root still finds the app manifest) rather
|
|
669
|
+
* than node_modules presence: presence-based detection escapes the app
|
|
670
|
+
* into ancestor installs, which surprise-enables the surface for every
|
|
671
|
+
* fixture app inside a monorepo that happens to have the package
|
|
672
|
+
* somewhere above it (this broke the plugin's own example suites). A
|
|
673
|
+
* declared dependency is unambiguous intent, and resolution then works
|
|
674
|
+
* regardless of hoisting. `diagnostics: true` remains the override for
|
|
675
|
+
* setups the heuristic can't see.
|
|
676
|
+
*/
|
|
677
|
+
function detectDiagnosticsPackage(root) {
|
|
678
|
+
let dir = path.resolve(root);
|
|
679
|
+
while (true) {
|
|
680
|
+
const manifestPath = path.join(dir, 'package.json');
|
|
681
|
+
if (fs.existsSync(manifestPath)) {
|
|
682
|
+
try {
|
|
683
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
684
|
+
return !!(manifest.dependencies?.[DIAGNOSTICS_PACKAGE] ?? manifest.devDependencies?.[DIAGNOSTICS_PACKAGE] ?? manifest.optionalDependencies?.[DIAGNOSTICS_PACKAGE]);
|
|
685
|
+
} catch {
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
const parent = path.dirname(dir);
|
|
690
|
+
if (parent === dir) return false;
|
|
691
|
+
dir = parent;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
589
694
|
function diagnosticsClientModuleCode() {
|
|
590
695
|
// Runtime imports resolve to the APP's diagnostics package (see the
|
|
591
696
|
// resolveId assist below) — the page speaks its own package's protocol.
|
|
@@ -612,18 +717,26 @@ function readJsonBody(req) {
|
|
|
612
717
|
req.on('error', reject);
|
|
613
718
|
});
|
|
614
719
|
}
|
|
615
|
-
function solidDiagnostics() {
|
|
720
|
+
function solidDiagnostics(mode = 'auto') {
|
|
616
721
|
let root = process.cwd();
|
|
617
722
|
let base = '/';
|
|
723
|
+
// Resolved at configResolved: explicit `true` is unconditional (missing
|
|
724
|
+
// package becomes a hard error at bridge resolution); `'auto'` enables
|
|
725
|
+
// only when the app has the package installed.
|
|
726
|
+
let enabled = mode === true;
|
|
618
727
|
return {
|
|
619
728
|
name: 'solid:diagnostics',
|
|
620
729
|
// Dev-serve only: the channels this fronts exist in dev builds only.
|
|
730
|
+
// Test mode excluded — vitest (including browser mode) runs a dev
|
|
731
|
+
// serve, and injecting the bridge into test pages perturbs suites
|
|
732
|
+
// that never asked for it.
|
|
621
733
|
apply(_config, env) {
|
|
622
|
-
return env.command === 'serve' && !env.isPreview;
|
|
734
|
+
return env.command === 'serve' && !env.isPreview && env.mode !== 'test';
|
|
623
735
|
},
|
|
624
736
|
configResolved(config) {
|
|
625
737
|
root = config.root;
|
|
626
738
|
base = config.base;
|
|
739
|
+
if (mode === 'auto') enabled = detectDiagnosticsPackage(root);
|
|
627
740
|
},
|
|
628
741
|
async resolveId(source, importer) {
|
|
629
742
|
if (source === DIAGNOSTICS_CLIENT_ID) {
|
|
@@ -639,7 +752,7 @@ function solidDiagnostics() {
|
|
|
639
752
|
skipSelf: true
|
|
640
753
|
});
|
|
641
754
|
if (!resolved || resolved.id.startsWith('__vite-optional-peer-dep:')) {
|
|
642
|
-
this.error(`[@solidjs/vite-plugin] the diagnostics
|
|
755
|
+
this.error(`[@solidjs/vite-plugin] the diagnostics surface requires ${DIAGNOSTICS_PACKAGE} ` + 'installed in the app (it provides the in-page bridge). Install it as a ' + 'development dependency, or set `diagnostics: false` to opt out.');
|
|
643
756
|
}
|
|
644
757
|
return resolved;
|
|
645
758
|
}
|
|
@@ -652,6 +765,7 @@ function solidDiagnostics() {
|
|
|
652
765
|
// Plain (index.html) apps get the client module injected here;
|
|
653
766
|
// start-mode apps import it from the generated client entry instead.
|
|
654
767
|
transformIndexHtml() {
|
|
768
|
+
if (!enabled) return undefined;
|
|
655
769
|
return [{
|
|
656
770
|
tag: 'script',
|
|
657
771
|
attrs: {
|
|
@@ -662,6 +776,11 @@ function solidDiagnostics() {
|
|
|
662
776
|
}];
|
|
663
777
|
},
|
|
664
778
|
configureServer(server) {
|
|
779
|
+
// The whole surface (announcement, middleware, bridge injection) only
|
|
780
|
+
// exists when enabled, so the discovery breadcrumb never lies about
|
|
781
|
+
// a dead endpoint.
|
|
782
|
+
if (!enabled) return;
|
|
783
|
+
|
|
665
784
|
// Announce the surface in the startup block. This is a discovery
|
|
666
785
|
// channel: agents watching dev-server output learn the endpoint and
|
|
667
786
|
// the skill documents without any project-level pointer (AGENTS.md).
|
|
@@ -670,7 +789,7 @@ function solidDiagnostics() {
|
|
|
670
789
|
originalPrintUrls();
|
|
671
790
|
const local = server.resolvedUrls?.local[0];
|
|
672
791
|
const endpoint = local ? new URL(DIAGNOSTICS_ENDPOINT, local).href : DIAGNOSTICS_ENDPOINT;
|
|
673
|
-
server.config.logger.info(` ➜ Solid diagnostics: ${endpoint} ` + `(GET status; POST {"method":"begin"|"end"|"whyDidRun"|"costs"})
|
|
792
|
+
server.config.logger.info(` ➜ Solid diagnostics: ${endpoint} ` + `(GET status; POST {"method":"begin"|"end"|"whyDidRun"|"costs"})` + (mode === 'auto' ? ' — auto-enabled; `diagnostics: false` opts out' : '') + `\n ➜ Agent skills: node_modules/${DIAGNOSTICS_PACKAGE}/skills/agent-loops/SKILL.md, ` + `node_modules/solid-js/skills/reactivity-diagnostics/SKILL.md`);
|
|
674
793
|
};
|
|
675
794
|
const pending = new Map();
|
|
676
795
|
let nextId = 1;
|
|
@@ -681,6 +800,11 @@ function solidDiagnostics() {
|
|
|
681
800
|
clearTimeout(entry.timer);
|
|
682
801
|
entry.resolve(data);
|
|
683
802
|
});
|
|
803
|
+
|
|
804
|
+
// No host/origin validation here: on all supported Vite versions
|
|
805
|
+
// (peer range ^8) Vite's own DNS-rebinding host check runs ahead of
|
|
806
|
+
// plugin middleware — verified: requests with a disallowed Host
|
|
807
|
+
// header get Vite's 403 before reaching this handler.
|
|
684
808
|
server.middlewares.use(DIAGNOSTICS_ENDPOINT, async (req, res) => {
|
|
685
809
|
// The middleware mounts on the exact path; anything deeper is 404.
|
|
686
810
|
if (req.url && req.url !== '/' && req.url !== '') {
|
|
@@ -803,7 +927,7 @@ async function compile(id, code, options) {
|
|
|
803
927
|
mode: options.mode,
|
|
804
928
|
env: options.env,
|
|
805
929
|
directive: options.directive,
|
|
806
|
-
sourceMap:
|
|
930
|
+
sourceMap: options.sourceMap !== false,
|
|
807
931
|
register: options.definitions.register,
|
|
808
932
|
create: options.definitions.create
|
|
809
933
|
});
|
|
@@ -929,11 +1053,11 @@ function xxHash32(buffer, seed = 0) {
|
|
|
929
1053
|
* root — not the invocation directory — so running `vite` from outside the
|
|
930
1054
|
* project keeps compiling the same files. Absolute patterns are used as-is.
|
|
931
1055
|
*
|
|
932
|
-
* @default include "src/**\/*.{jsx,tsx,ts,js,mjs,cjs}", exclude "node_modules/**\/*.{jsx,tsx,ts,js,mjs,cjs}"
|
|
1056
|
+
* @default include "src/**\/*.{jsx,tsx,tsrx,ts,js,mjs,cjs}", exclude "node_modules/**\/*.{jsx,tsx,tsrx,ts,js,mjs,cjs}"
|
|
933
1057
|
*/
|
|
934
1058
|
|
|
935
|
-
const DEFAULT_INCLUDE = 'src/**/*.{jsx,tsx,ts,js,mjs,cjs}';
|
|
936
|
-
const DEFAULT_EXCLUDE = 'node_modules/**/*.{jsx,tsx,ts,js,mjs,cjs}';
|
|
1059
|
+
const DEFAULT_INCLUDE = 'src/**/*.{jsx,tsx,tsrx,ts,js,mjs,cjs}';
|
|
1060
|
+
const DEFAULT_EXCLUDE = 'node_modules/**/*.{jsx,tsx,tsrx,ts,js,mjs,cjs}';
|
|
937
1061
|
const DEFAULT_MANIFEST = 'virtual:solid-server-function-manifest';
|
|
938
1062
|
const DEFAULT_DIRECTIVE = 'use server';
|
|
939
1063
|
const DEFAULT_RUNTIME = '@solidjs/web/server-functions';
|
|
@@ -1298,6 +1422,46 @@ function serverFunctions(options = {}, internal = {}) {
|
|
|
1298
1422
|
}
|
|
1299
1423
|
});
|
|
1300
1424
|
}
|
|
1425
|
+
async function transformModule(ctx, code, fileId, opts, tsrx) {
|
|
1426
|
+
const mode = getEnvironmentConsumer(ctx.environment, opts);
|
|
1427
|
+
const [id] = fileId.split('?');
|
|
1428
|
+
if (!id || !filter(id) || isTsrxModule(id) !== tsrx) return null;
|
|
1429
|
+
|
|
1430
|
+
// The directive has to appear literally, so anything without the
|
|
1431
|
+
// substring can skip the native parse entirely.
|
|
1432
|
+
if (!code.includes(directive)) return null;
|
|
1433
|
+
const result = await compile(id, code, {
|
|
1434
|
+
...(mode === 'server' ? serverOptions : clientOptions),
|
|
1435
|
+
mode,
|
|
1436
|
+
env,
|
|
1437
|
+
root,
|
|
1438
|
+
sourceMap: !tsrx || !!internal.tsrxSourceMap
|
|
1439
|
+
});
|
|
1440
|
+
if (!result.valid) return null;
|
|
1441
|
+
const preloader = preload[mode];
|
|
1442
|
+
if (preloader) preloader.defer();
|
|
1443
|
+
invalidateModules(currentServer, mergeManifestRecord(manifest.server, new Set([id])), manifestId);
|
|
1444
|
+
return {
|
|
1445
|
+
// Appended (not prepended) so the source map for the compiled module
|
|
1446
|
+
// stays valid; imports hoist and the endpoint is only read at call time.
|
|
1447
|
+
code: (result.code || '') + endpointConfigureSnippet(mode),
|
|
1448
|
+
map: result.map
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
const compilerPlugin = {
|
|
1452
|
+
name: 'solid:server-functions/compiler',
|
|
1453
|
+
enforce: 'pre',
|
|
1454
|
+
transform(code, fileId, opts) {
|
|
1455
|
+
return transformModule(this, code, fileId, opts, false);
|
|
1456
|
+
}
|
|
1457
|
+
};
|
|
1458
|
+
const tsrxCompilerPlugin = {
|
|
1459
|
+
name: 'solid:server-functions/tsrx-compiler',
|
|
1460
|
+
enforce: 'pre',
|
|
1461
|
+
transform(code, fileId, opts) {
|
|
1462
|
+
return transformModule(this, code, fileId, opts, true);
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1301
1465
|
return [{
|
|
1302
1466
|
name: 'solid:server-functions/setup',
|
|
1303
1467
|
enforce: 'pre',
|
|
@@ -1374,44 +1538,7 @@ function serverFunctions(options = {}, internal = {}) {
|
|
|
1374
1538
|
}
|
|
1375
1539
|
return null;
|
|
1376
1540
|
}
|
|
1377
|
-
},
|
|
1378
|
-
name: 'solid:server-functions/compiler',
|
|
1379
|
-
enforce: 'pre',
|
|
1380
|
-
async transform(code, fileId, opts) {
|
|
1381
|
-
const mode = getEnvironmentConsumer(this.environment, opts);
|
|
1382
|
-
const [id] = fileId.split('?');
|
|
1383
|
-
if (!filter(id)) {
|
|
1384
|
-
return null;
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
// Fast path: the directive has to appear literally, so anything
|
|
1388
|
-
// without the substring can skip the native parse entirely.
|
|
1389
|
-
if (!code.includes(directive)) {
|
|
1390
|
-
return null;
|
|
1391
|
-
}
|
|
1392
|
-
const result = await compile(id, code, {
|
|
1393
|
-
...(mode === 'server' ? serverOptions : clientOptions),
|
|
1394
|
-
mode,
|
|
1395
|
-
env,
|
|
1396
|
-
root
|
|
1397
|
-
});
|
|
1398
|
-
if (result.valid) {
|
|
1399
|
-
const preloader = preload[mode];
|
|
1400
|
-
if (preloader) {
|
|
1401
|
-
preloader.defer();
|
|
1402
|
-
}
|
|
1403
|
-
invalidateModules(currentServer, mergeManifestRecord(manifest.server, new Set([id])), manifestId);
|
|
1404
|
-
return {
|
|
1405
|
-
// Appended (not prepended) so the source map for the compiled
|
|
1406
|
-
// module stays valid; imports hoist and the endpoint is only
|
|
1407
|
-
// read at call time, never during module evaluation.
|
|
1408
|
-
code: (result.code || '') + endpointConfigureSnippet(mode),
|
|
1409
|
-
map: result.map
|
|
1410
|
-
};
|
|
1411
|
-
}
|
|
1412
|
-
return null;
|
|
1413
|
-
}
|
|
1414
|
-
}, ...startPlugins];
|
|
1541
|
+
}, compilerPlugin, ...(internal.tsrxAfterSolid ? [tsrxCompilerPlugin] : []), ...startPlugins];
|
|
1415
1542
|
}
|
|
1416
1543
|
|
|
1417
1544
|
const DEVTOOLS_PACKAGE = '@solidjs/start-devtools';
|
|
@@ -1506,9 +1633,9 @@ const ERROR_BOUNDARY_ID = 'virtual:solid-ssr-error-boundary.tsx';
|
|
|
1506
1633
|
const MANIFEST_ID = 'virtual:solid-manifest';
|
|
1507
1634
|
const SERVER_FUNCTION_HANDLER_ID = 'virtual:solid-server-function-handler';
|
|
1508
1635
|
const STORAGE_SOURCE = '@solidjs/web/storage';
|
|
1509
|
-
const ENTRY_EXTENSIONS = ['.tsx', '.jsx', '.ts', '.js', '.mjs'];
|
|
1510
|
-
const APP_EXTENSIONS = ['.tsx', '.jsx', '.ts', '.js'];
|
|
1511
|
-
const DOCUMENT_EXTENSIONS = ['.tsx', '.jsx'];
|
|
1636
|
+
const ENTRY_EXTENSIONS = ['.tsx', '.jsx', '.ts', '.js', '.mjs', '.tsrx'];
|
|
1637
|
+
const APP_EXTENSIONS = ['.tsx', '.jsx', '.ts', '.js', '.tsrx'];
|
|
1638
|
+
const DOCUMENT_EXTENSIONS = ['.tsx', '.jsx', '.tsrx'];
|
|
1512
1639
|
function probe(root, stem, extensions) {
|
|
1513
1640
|
for (const ext of extensions) {
|
|
1514
1641
|
if (existsSync(path.resolve(root, stem + ext))) return stem + ext;
|
|
@@ -1616,7 +1743,9 @@ function startServe(options, internal = {}) {
|
|
|
1616
1743
|
const serverComponents = !!internal.serverComponents;
|
|
1617
1744
|
const errorBoundary = options.errorBoundary !== false;
|
|
1618
1745
|
const styleFilter = internal.styleFilter;
|
|
1619
|
-
|
|
1746
|
+
// `'auto'` resolves against the project root in configResolved, before
|
|
1747
|
+
// any of the (lazy) uses in entry codegen and the entry transform.
|
|
1748
|
+
let diagnostics = internal.diagnostics === true;
|
|
1620
1749
|
let devtoolsEnabled = false;
|
|
1621
1750
|
let devtoolsResolutions = {};
|
|
1622
1751
|
let devtoolsIds = {};
|
|
@@ -2126,6 +2255,12 @@ function startServe(options, internal = {}) {
|
|
|
2126
2255
|
root = config.root;
|
|
2127
2256
|
base = config.base;
|
|
2128
2257
|
isBuild = config.command === 'build';
|
|
2258
|
+
// Test mode excluded for the same reason as the surface plugin's
|
|
2259
|
+
// `apply`: vitest runs a dev serve, and test pages should not get
|
|
2260
|
+
// the bridge import injected into their client entries.
|
|
2261
|
+
if (internal.diagnostics === 'auto' && !isBuild && config.mode !== 'test') {
|
|
2262
|
+
diagnostics = detectDiagnosticsPackage(root);
|
|
2263
|
+
}
|
|
2129
2264
|
},
|
|
2130
2265
|
resolveId(source, importer, opts) {
|
|
2131
2266
|
if (source === HANDLER_ID) {
|
|
@@ -3242,7 +3377,8 @@ function solidPlugin(options = {}) {
|
|
|
3242
3377
|
// resolve against the Vite root, not process.cwd() — running `vite` from
|
|
3243
3378
|
// outside the project would otherwise change what the filter matches.
|
|
3244
3379
|
let filter = createFilter(options.include, options.exclude);
|
|
3245
|
-
const
|
|
3380
|
+
const serverComponentsOption = typeof options.serverFunctions === 'object' ? options.serverFunctions.components : undefined;
|
|
3381
|
+
const serverComponents = !!serverComponentsOption;
|
|
3246
3382
|
// `start: true` is sugar for the empty options bag — one start mode,
|
|
3247
3383
|
// two spellings — so normalize here and let everything downstream see a
|
|
3248
3384
|
// single shape (`false` behaves exactly like omission).
|
|
@@ -3292,6 +3428,7 @@ function solidPlugin(options = {}) {
|
|
|
3292
3428
|
let base = '/';
|
|
3293
3429
|
let clientOutDir = null;
|
|
3294
3430
|
let solidPkgsConfig;
|
|
3431
|
+
const tsrxCss = new Map();
|
|
3295
3432
|
|
|
3296
3433
|
// The client build's manifest, read back by SSR builds. In builder-mode
|
|
3297
3434
|
// (single process, e.g. SolidStart's nitro plugin) the client build runs
|
|
@@ -3386,6 +3523,44 @@ function solidPlugin(options = {}) {
|
|
|
3386
3523
|
const relativeId = path.relative(projectRoot, file).split(path.sep).join('/') + query;
|
|
3387
3524
|
return code + `\nexport const $$moduleUrl = ${JSON.stringify(relativeId)};\n`;
|
|
3388
3525
|
}
|
|
3526
|
+
function nativeTsrxCss(result) {
|
|
3527
|
+
const css = result.css;
|
|
3528
|
+
return typeof css === 'string' ? css : '';
|
|
3529
|
+
}
|
|
3530
|
+
function babelTsrxCss(result) {
|
|
3531
|
+
const css = result.metadata?.css;
|
|
3532
|
+
return typeof css === 'string' ? css : '';
|
|
3533
|
+
}
|
|
3534
|
+
async function compileTsrxCss(source, id) {
|
|
3535
|
+
const solidOptions = getSolidOptions(options, false, replaceDev, isTestMode);
|
|
3536
|
+
if (options.compiler === 'babel') {
|
|
3537
|
+
const babelUserOptions = await getBabelUserOptions(options, source, id, false);
|
|
3538
|
+
const babelOptions = mergeAndConcat(babelUserOptions, {
|
|
3539
|
+
root: projectRoot,
|
|
3540
|
+
// Keep .tsrx: the Babel plugin uses it to select its TSRX parser.
|
|
3541
|
+
filename: id,
|
|
3542
|
+
sourceFileName: id,
|
|
3543
|
+
ast: false,
|
|
3544
|
+
code: false,
|
|
3545
|
+
sourceMaps: false,
|
|
3546
|
+
configFile: false,
|
|
3547
|
+
babelrc: false,
|
|
3548
|
+
parserOpts: {
|
|
3549
|
+
plugins: ['jsx', 'decorators', 'typescript']
|
|
3550
|
+
},
|
|
3551
|
+
plugins: [[solid, solidOptions]]
|
|
3552
|
+
});
|
|
3553
|
+
const result = await babel.transformAsync(source, babelOptions);
|
|
3554
|
+
return result ? babelTsrxCss(result) : '';
|
|
3555
|
+
}
|
|
3556
|
+
const compiler = await loadNativeCompiler();
|
|
3557
|
+
const result = await compiler.transformAsync(source, {
|
|
3558
|
+
...solidOptions,
|
|
3559
|
+
filename: id,
|
|
3560
|
+
sourceMap: false
|
|
3561
|
+
});
|
|
3562
|
+
return nativeTsrxCss(result);
|
|
3563
|
+
}
|
|
3389
3564
|
const mainPlugin = {
|
|
3390
3565
|
name: 'solid',
|
|
3391
3566
|
enforce: 'pre',
|
|
@@ -3476,6 +3651,7 @@ function solidPlugin(options = {}) {
|
|
|
3476
3651
|
dedupe: nestedDeps
|
|
3477
3652
|
},
|
|
3478
3653
|
optimizeDeps: {
|
|
3654
|
+
extensions: ['.tsrx'],
|
|
3479
3655
|
include: [...nestedDeps,
|
|
3480
3656
|
// Dev refresh wrappers import the solid-js/refresh runtime in
|
|
3481
3657
|
// every mode; pre-bundle it up front so its discovery doesn't
|
|
@@ -3496,7 +3672,28 @@ function solidPlugin(options = {}) {
|
|
|
3496
3672
|
jsx: {
|
|
3497
3673
|
runtime: 'classic'
|
|
3498
3674
|
}
|
|
3499
|
-
}
|
|
3675
|
+
},
|
|
3676
|
+
plugins: [{
|
|
3677
|
+
name: 'solid:tsrx-dep-scan',
|
|
3678
|
+
async transform(source, id) {
|
|
3679
|
+
if (!isTsrxModule(id) || isTsrxCssModule(id)) return null;
|
|
3680
|
+
const compiler = await loadNativeCompiler();
|
|
3681
|
+
const result = await compiler.transformAsync(source, {
|
|
3682
|
+
...getSolidOptions(options, false, replaceDev, isTestMode),
|
|
3683
|
+
filename: cleanModuleId(id),
|
|
3684
|
+
sourceMap: false
|
|
3685
|
+
});
|
|
3686
|
+
const stripped = await transformWithOxc(result.code, cleanModuleId(id) + '.tsx', {
|
|
3687
|
+
lang: 'tsx',
|
|
3688
|
+
sourcemap: false,
|
|
3689
|
+
target: 'esnext'
|
|
3690
|
+
});
|
|
3691
|
+
return {
|
|
3692
|
+
code: stripped.code,
|
|
3693
|
+
map: null
|
|
3694
|
+
};
|
|
3695
|
+
}
|
|
3696
|
+
}]
|
|
3500
3697
|
}
|
|
3501
3698
|
},
|
|
3502
3699
|
...(Object.keys(test).length ? {
|
|
@@ -3555,8 +3752,13 @@ function solidPlugin(options = {}) {
|
|
|
3555
3752
|
resolve: projectRoot
|
|
3556
3753
|
});
|
|
3557
3754
|
styleFilter = createStyleFilter(projectRoot);
|
|
3558
|
-
|
|
3559
|
-
|
|
3755
|
+
// `components: 'external'` is the acknowledgement that a composing
|
|
3756
|
+
// host (e.g. the Astro adapter or TanStack Start's Solid integration)
|
|
3757
|
+
// owns the document wiring itself — behavior is identical to `true`,
|
|
3758
|
+
// only this warning is skipped. Under SSR start mode it's redundant
|
|
3759
|
+
// but harmless (treated exactly as `true`).
|
|
3760
|
+
if (serverComponents && serverComponentsOption !== 'external' && !(options.start && options.ssr)) {
|
|
3761
|
+
config.logger.warn('[@solidjs/vite-plugin] serverFunctions.components is set without SSR start mode (the `start` ' + 'option with `ssr: true`), so the plugin only installs the endpoint response transform ' + '(server functions returning components stream correctly). The document wiring — the ' + 'render plugin (with the direct-call transform) and the client-side ' + "installServerComponents() call — is emitted by SSR start mode's generated entries; " + 'without it, server components only mount from post-boot streams and your client code ' + 'must call installServerComponents() itself. If a composing host owns that wiring, set ' + "`components: 'external'` to acknowledge it and silence this warning.");
|
|
3560
3762
|
}
|
|
3561
3763
|
needHmr = config.command === 'serve' && config.mode !== 'production' && options.hot !== false && !options.refresh?.disabled;
|
|
3562
3764
|
},
|
|
@@ -3594,10 +3796,21 @@ function solidPlugin(options = {}) {
|
|
|
3594
3796
|
return origSend(...args);
|
|
3595
3797
|
};
|
|
3596
3798
|
},
|
|
3597
|
-
hotUpdate({
|
|
3799
|
+
async hotUpdate({
|
|
3800
|
+
file,
|
|
3598
3801
|
modules,
|
|
3599
|
-
|
|
3802
|
+
read
|
|
3600
3803
|
}) {
|
|
3804
|
+
if (isTsrxModule(file) && this.environment.name === 'client') {
|
|
3805
|
+
updateTsrxCss(tsrxCss, file, await compileTsrxCss(await read(), file));
|
|
3806
|
+
const cssModule = this.environment.moduleGraph.getModuleById(resolvedTsrxCssModuleId(file));
|
|
3807
|
+
if (cssModule) {
|
|
3808
|
+
this.environment.moduleGraph.invalidateModule(cssModule);
|
|
3809
|
+
if (!modules.includes(cssModule)) modules = [...modules, cssModule];
|
|
3810
|
+
return modules;
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3813
|
+
|
|
3601
3814
|
// solid-refresh only injects HMR boundaries into client modules, so
|
|
3602
3815
|
// non-client environments have no accept handlers. Without this, Vite
|
|
3603
3816
|
// would see no boundaries and send full-reload messages that race with
|
|
@@ -3634,6 +3847,8 @@ function solidPlugin(options = {}) {
|
|
|
3634
3847
|
}
|
|
3635
3848
|
},
|
|
3636
3849
|
resolveId(id) {
|
|
3850
|
+
const tsrxCssId = resolveTsrxCssModule(id);
|
|
3851
|
+
if (tsrxCssId) return tsrxCssId;
|
|
3637
3852
|
if (id === VIRTUAL_MANIFEST_ID) return RESOLVED_VIRTUAL_MANIFEST_ID;
|
|
3638
3853
|
},
|
|
3639
3854
|
moduleParsed(info) {
|
|
@@ -3646,7 +3861,7 @@ function solidPlugin(options = {}) {
|
|
|
3646
3861
|
for (const depId of info.dynamicallyImportedIds || []) {
|
|
3647
3862
|
const cleanId = depId.split('?')[0];
|
|
3648
3863
|
if (/node_modules/.test(cleanId) || cleanId.startsWith('\0')) continue;
|
|
3649
|
-
if (
|
|
3864
|
+
if (!(/\.[mc]?[tj]sx?$/i.test(cleanId) || isTsrxModule(cleanId))) continue;
|
|
3650
3865
|
if (emittedLazyChunks.has(depId)) continue;
|
|
3651
3866
|
emittedLazyChunks.add(depId);
|
|
3652
3867
|
emittedLazyChunkRefs.push(this.emitFile({
|
|
@@ -3657,6 +3872,8 @@ function solidPlugin(options = {}) {
|
|
|
3657
3872
|
}
|
|
3658
3873
|
},
|
|
3659
3874
|
load(id) {
|
|
3875
|
+
const tsrxSource = tsrxCssSourceId(id);
|
|
3876
|
+
if (tsrxSource) return tsrxCss.get(tsrxSource) ?? '';
|
|
3660
3877
|
if (id === RESOLVED_VIRTUAL_MANIFEST_ID) {
|
|
3661
3878
|
if (!isBuild) {
|
|
3662
3879
|
return devManifestCode(projectRoot, base, devServer ? devManifestBridgeUrl(devServer) : null);
|
|
@@ -3698,6 +3915,7 @@ function solidPlugin(options = {}) {
|
|
|
3698
3915
|
}
|
|
3699
3916
|
},
|
|
3700
3917
|
async transform(source, id, transformOptions) {
|
|
3918
|
+
if (isTsrxCssModule(id)) return null;
|
|
3701
3919
|
const isSsr = getEnvironmentConsumer(this.environment, transformOptions) === 'server';
|
|
3702
3920
|
const currentFileExtension = getExtension(id);
|
|
3703
3921
|
const extensionsToWatch = options.extensions || [];
|
|
@@ -3713,14 +3931,15 @@ function solidPlugin(options = {}) {
|
|
|
3713
3931
|
// while the transform pipeline below works on the clean file path.
|
|
3714
3932
|
const moduleId = id;
|
|
3715
3933
|
id = id.replace(/\?.*$/, '');
|
|
3716
|
-
|
|
3934
|
+
const isTsrx = isTsrxModule(id);
|
|
3935
|
+
if (!(/\.[mc]?[tj]sx$/i.test(id) || isTsrx || allExtensions.includes(currentFileExtension))) {
|
|
3717
3936
|
return null;
|
|
3718
3937
|
}
|
|
3719
3938
|
const inNodeModules = /node_modules/.test(id);
|
|
3720
3939
|
const solidOptions = getSolidOptions(options, !!isSsr, replaceDev, isTestMode);
|
|
3721
3940
|
|
|
3722
3941
|
// We need to know if the current file extension has a typescript options tied to it
|
|
3723
|
-
const shouldBeProcessedWithTypescript = /\.[mc]?tsx$/i.test(id) || extensionsToWatch.some(extension => {
|
|
3942
|
+
const shouldBeProcessedWithTypescript = /\.[mc]?tsx$/i.test(id) || isTsrx || extensionsToWatch.some(extension => {
|
|
3724
3943
|
if (typeof extension === 'string') {
|
|
3725
3944
|
return extension.includes('tsx');
|
|
3726
3945
|
}
|
|
@@ -3744,7 +3963,7 @@ function solidPlugin(options = {}) {
|
|
|
3744
3963
|
// extension; custom extensions registered through `options.extensions`
|
|
3745
3964
|
// are unknown to it, so borrow a standard one matching the configured
|
|
3746
3965
|
// TypeScript-ness.
|
|
3747
|
-
const nativeFilename = /\.(?:[mc]?[jt]s|[jt]sx)$/i.test(id) ? id : id + (shouldBeProcessedWithTypescript ? '.tsx' : '.jsx');
|
|
3966
|
+
const nativeFilename = isTsrx || /\.(?:[mc]?[jt]s|[jt]sx)$/i.test(id) ? id : id + (shouldBeProcessedWithTypescript ? '.tsx' : '.jsx');
|
|
3748
3967
|
|
|
3749
3968
|
// Shared native prelude for every mode: the lazy() module-URL pass,
|
|
3750
3969
|
// then (dev/client/non-node_modules) the solid-refresh HMR pass, both
|
|
@@ -3754,6 +3973,97 @@ function solidPlugin(options = {}) {
|
|
|
3754
3973
|
const compiler = await loadNativeCompiler();
|
|
3755
3974
|
let code = source;
|
|
3756
3975
|
const maps = [];
|
|
3976
|
+
if (isTsrx) {
|
|
3977
|
+
// Solid lowering preserves authored TypeScript annotations; secondary
|
|
3978
|
+
// passes therefore parse the generated module as TSX even though no
|
|
3979
|
+
// template syntax remains.
|
|
3980
|
+
const generatedFilename = id + '.tsx';
|
|
3981
|
+
const babelBaseOptions = {
|
|
3982
|
+
root: projectRoot,
|
|
3983
|
+
filename: id,
|
|
3984
|
+
sourceFileName: id,
|
|
3985
|
+
ast: false,
|
|
3986
|
+
sourceMaps: true,
|
|
3987
|
+
configFile: false,
|
|
3988
|
+
babelrc: false,
|
|
3989
|
+
parserOpts: {
|
|
3990
|
+
plugins
|
|
3991
|
+
}
|
|
3992
|
+
};
|
|
3993
|
+
let css = '';
|
|
3994
|
+
if (options.compiler !== 'babel') {
|
|
3995
|
+
const result = await compiler.transformAsync(code, {
|
|
3996
|
+
...solidOptions,
|
|
3997
|
+
filename: id,
|
|
3998
|
+
sourceMap: true
|
|
3999
|
+
});
|
|
4000
|
+
code = result.code || '';
|
|
4001
|
+
css = nativeTsrxCss(result);
|
|
4002
|
+
maps.push(result.map);
|
|
4003
|
+
if (options.babel) {
|
|
4004
|
+
// The support pass cannot parse authored TSRX. On this route it
|
|
4005
|
+
// intentionally sees the lowered ordinary JavaScript instead.
|
|
4006
|
+
const supportOptions = mergeAndConcat(babelUserOptions, babelBaseOptions);
|
|
4007
|
+
// This pass sees native-lowered ordinary JavaScript, so do not
|
|
4008
|
+
// route it back through Babel's TSRX parser.
|
|
4009
|
+
supportOptions.filename = generatedFilename;
|
|
4010
|
+
const supportResult = await babel.transformAsync(code, supportOptions);
|
|
4011
|
+
if (!supportResult) return undefined;
|
|
4012
|
+
code = supportResult.code || '';
|
|
4013
|
+
maps.push(supportResult.map);
|
|
4014
|
+
}
|
|
4015
|
+
} else {
|
|
4016
|
+
const babelOptions = mergeAndConcat(babelUserOptions, {
|
|
4017
|
+
...babelBaseOptions,
|
|
4018
|
+
plugins: [[solid, solidOptions]]
|
|
4019
|
+
});
|
|
4020
|
+
const result = await babel.transformAsync(code, babelOptions);
|
|
4021
|
+
if (!result) return undefined;
|
|
4022
|
+
code = result.code || '';
|
|
4023
|
+
css = babelTsrxCss(result);
|
|
4024
|
+
maps.push(result.map);
|
|
4025
|
+
}
|
|
4026
|
+
const lazyResult = await compiler.transformLazyAsync(code, {
|
|
4027
|
+
filename: generatedFilename,
|
|
4028
|
+
sourceMap: true
|
|
4029
|
+
});
|
|
4030
|
+
code = lazyResult.code;
|
|
4031
|
+
maps.push(lazyResult.map);
|
|
4032
|
+
if (needRefresh) {
|
|
4033
|
+
const refreshResult = await compiler.transformRefreshAsync(code, {
|
|
4034
|
+
filename: generatedFilename,
|
|
4035
|
+
bundler: 'vite',
|
|
4036
|
+
fixRender: true,
|
|
4037
|
+
...(typeof options.refresh?.granular === 'boolean' ? {
|
|
4038
|
+
granular: options.refresh.granular
|
|
4039
|
+
} : {}),
|
|
4040
|
+
jsx: false,
|
|
4041
|
+
importSource: REFRESH_RUNTIME_SOURCE,
|
|
4042
|
+
sourceMap: true
|
|
4043
|
+
});
|
|
4044
|
+
code = refreshResult.code;
|
|
4045
|
+
maps.push(refreshResult.map);
|
|
4046
|
+
}
|
|
4047
|
+
code = injectSsrModuleId(await resolveLazyModuleUrls(this, code, id), moduleId, !!isSsr);
|
|
4048
|
+
let map = options.compiler === 'babel' ? combineSourcemaps(maps) : null;
|
|
4049
|
+
updateTsrxCss(tsrxCss, id, css);
|
|
4050
|
+
if (css) {
|
|
4051
|
+
code = prependTsrxCssImport(code, id);
|
|
4052
|
+
map = offsetSourceMapLine(map);
|
|
4053
|
+
}
|
|
4054
|
+
// Vite selects its TypeScript stripping by file extension. Since the
|
|
4055
|
+
// real module identity remains `.tsrx`, strip the annotations here
|
|
4056
|
+
// after Solid lowering instead of handing typed JavaScript to Rollup.
|
|
4057
|
+
const stripped = await transformWithOxc(code, generatedFilename, {
|
|
4058
|
+
lang: 'tsx',
|
|
4059
|
+
sourcemap: map != null,
|
|
4060
|
+
target: 'esnext'
|
|
4061
|
+
}, map ?? undefined);
|
|
4062
|
+
return {
|
|
4063
|
+
code: stripped.code,
|
|
4064
|
+
map: map == null ? null : stripped.map
|
|
4065
|
+
};
|
|
4066
|
+
}
|
|
3757
4067
|
const lazyResult = await compiler.transformLazyAsync(code, {
|
|
3758
4068
|
filename: nativeFilename,
|
|
3759
4069
|
sourceMap: true
|
|
@@ -3836,20 +4146,24 @@ function solidPlugin(options = {}) {
|
|
|
3836
4146
|
}
|
|
3837
4147
|
};
|
|
3838
4148
|
|
|
3839
|
-
//
|
|
3840
|
-
//
|
|
3841
|
-
//
|
|
3842
|
-
//
|
|
3843
|
-
const
|
|
4149
|
+
// Ordinary modules need the directive transform before JSX. Authored TSRX
|
|
4150
|
+
// cannot be parsed by that standalone pass, so its companion compiler runs
|
|
4151
|
+
// after mainPlugin has lowered the file to ordinary JavaScript while keeping
|
|
4152
|
+
// the original .tsrx id for stable server-function hashes.
|
|
4153
|
+
const serverFunctionPlugins = options.serverFunctions ? serverFunctions(options.serverFunctions === true ? {} : options.serverFunctions, {
|
|
3844
4154
|
devMiddleware: true,
|
|
3845
4155
|
externalDevServer,
|
|
4156
|
+
tsrxAfterSolid: true,
|
|
4157
|
+
tsrxSourceMap: options.compiler === 'babel',
|
|
3846
4158
|
// With start mode on (either variant), the dev middleware dispatches
|
|
3847
4159
|
// the endpoint through the SSR handler so user middleware and the
|
|
3848
4160
|
// stub-backed request event front it exactly like page SSR.
|
|
3849
4161
|
...(startOptions ? {
|
|
3850
4162
|
ssrHandler: SSR_HANDLER_ID
|
|
3851
4163
|
} : {})
|
|
3852
|
-
})
|
|
4164
|
+
}) : [];
|
|
4165
|
+
const tsrxServerFunctionPlugin = serverFunctionPlugins.find(plugin => plugin.name === 'solid:server-functions/tsrx-compiler');
|
|
4166
|
+
const plugins = [boundaryModules(), ...serverFunctionPlugins.filter(plugin => plugin !== tsrxServerFunctionPlugin), mainPlugin, ...(tsrxServerFunctionPlugin ? [tsrxServerFunctionPlugin] : [])];
|
|
3853
4167
|
|
|
3854
4168
|
// The `start` option opts into start-mode serving on top of the transforms;
|
|
3855
4169
|
// the `ssr` boolean picks the mode (a bare `ssr: true` keeps the
|
|
@@ -3864,7 +4178,7 @@ function solidPlugin(options = {}) {
|
|
|
3864
4178
|
serverComponents,
|
|
3865
4179
|
ssr: !!options.ssr,
|
|
3866
4180
|
styleFilter: filterDevStyles,
|
|
3867
|
-
diagnostics:
|
|
4181
|
+
diagnostics: options.diagnostics ?? 'auto',
|
|
3868
4182
|
onDocumentResolved(documentPath) {
|
|
3869
4183
|
// Normalize to forward slashes to match Vite's transform ids.
|
|
3870
4184
|
documentModuleId = documentPath ? documentPath.split(path.sep).join('/') : null;
|
|
@@ -3873,9 +4187,11 @@ function solidPlugin(options = {}) {
|
|
|
3873
4187
|
}
|
|
3874
4188
|
|
|
3875
4189
|
// Agent diagnostics endpoint + injected bridge (dev serve only — the
|
|
3876
|
-
// plugin no-ops itself for builds and preview via `apply
|
|
3877
|
-
|
|
3878
|
-
|
|
4190
|
+
// plugin no-ops itself for builds and preview via `apply`, and in the
|
|
4191
|
+
// default auto mode additionally disables itself unless the app has
|
|
4192
|
+
// `@solidjs/diagnostics` installed).
|
|
4193
|
+
if (options.diagnostics !== false) {
|
|
4194
|
+
plugins.push(solidDiagnostics(options.diagnostics === true ? true : 'auto'));
|
|
3879
4195
|
}
|
|
3880
4196
|
|
|
3881
4197
|
// Builder-mode (environments API) client-before-server build ordering.
|