@lovable.dev/vite-tanstack-config 2.25.2 → 2.26.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/README.md +4 -0
- package/dist/{devModulePreload-Dz3PBhzO.js → devModulePreload-BOSHEX8Y.js} +31 -6
- package/dist/{devModulePreload-BwVYdLe9.cjs → devModulePreload-D7H42V_N.cjs} +31 -6
- package/dist/index.cjs +3 -2
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,10 @@ Vite config wrapper for Lovable TanStack Start projects.
|
|
|
13
13
|
|
|
14
14
|
Apps can pass through Vite options and adjust the React, TanStack Start, Nitro, HMR gate, and error-logging behavior when they need to.
|
|
15
15
|
|
|
16
|
+
## Server bundle
|
|
17
|
+
|
|
18
|
+
Inside a Lovable build the Nitro server bundle is minified, for both the Cloudflare and the portable fetch-bundle targets (Nitro's Cloudflare preset leaves it unminified). The `LOVABLE_SERVER_MINIFY=0` environment variable restores the preset default. Outside a Lovable build the preset decides.
|
|
19
|
+
|
|
16
20
|
## Build exit watchdog
|
|
17
21
|
|
|
18
22
|
Inside a Lovable build with prerender enabled, the build process is forced to exit if it is still alive 60 seconds after the last build hook has returned, and a `[lovable-build-exit-report]` block naming the open handle types is written to stderr. Adjust it with `defineConfig({ buildExitWatchdog: { graceMs, enabled } })`; the grace is clamped to 5 s–10 min. The `LOVABLE_PRERENDER_EXIT_GRACE_MS` and `LOVABLE_PRERENDER_EXIT_WATCHDOG=off` environment variables override the config.
|
|
@@ -12,14 +12,15 @@ function devModulePreloadPlugin(options = {}) {
|
|
|
12
12
|
return {
|
|
13
13
|
name: "lovable:dev-module-preload",
|
|
14
14
|
apply: "serve",
|
|
15
|
-
configureServer(server) {
|
|
15
|
+
async configureServer(server) {
|
|
16
16
|
if (process.env["LOVABLE_DEV_MODULE_PRELOAD"] !== "1") return;
|
|
17
17
|
if (server.config.experimental?.bundledDev) return;
|
|
18
18
|
const client = server.environments?.client;
|
|
19
19
|
if (!client) return;
|
|
20
|
+
const staticImports = staticImportReader((await import("vite")).parseAst);
|
|
20
21
|
let crawl;
|
|
21
22
|
const recrawl = () => {
|
|
22
|
-
crawl ??= crawlModuleGraph(client, entry).finally(() => {
|
|
23
|
+
crawl ??= crawlModuleGraph(client, entry, server.config.base, staticImports).finally(() => {
|
|
23
24
|
crawl = void 0;
|
|
24
25
|
});
|
|
25
26
|
};
|
|
@@ -27,14 +28,14 @@ function devModulePreloadPlugin(options = {}) {
|
|
|
27
28
|
server.middlewares.use((req, res, next) => {
|
|
28
29
|
if (req.method === "GET" && (req.headers.accept ?? "").includes("text/html")) {
|
|
29
30
|
recrawl();
|
|
30
|
-
injectAfterHead(res, () => modulePreloadTags(preloadUrls(client, entry, server.config.base)));
|
|
31
|
+
injectAfterHead(res, () => modulePreloadTags(preloadUrls(client, entry, server.config.base, staticImports)));
|
|
31
32
|
}
|
|
32
33
|
next();
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
|
-
async function crawlModuleGraph(env, entry) {
|
|
38
|
+
async function crawlModuleGraph(env, entry, base, staticImports) {
|
|
38
39
|
const queued = /* @__PURE__ */ new Set([entry]);
|
|
39
40
|
let level = [entry];
|
|
40
41
|
while (level.length > 0) {
|
|
@@ -43,8 +44,10 @@ async function crawlModuleGraph(env, entry) {
|
|
|
43
44
|
try {
|
|
44
45
|
await env.transformRequest(url);
|
|
45
46
|
const mod = await env.moduleGraph.getModuleByUrl(url);
|
|
46
|
-
|
|
47
|
+
if (!mod) return;
|
|
48
|
+
for (const dep of mod.importedModules) {
|
|
47
49
|
if (dep.id === null || queued.has(dep.url) || queued.size >= MAX_PRELOADED_MODULES) continue;
|
|
50
|
+
if (isLazyDependencyChunk(env, mod, browserImportUrl(dep, base), staticImports)) continue;
|
|
48
51
|
queued.add(dep.url);
|
|
49
52
|
next.push(dep.url);
|
|
50
53
|
}
|
|
@@ -53,7 +56,7 @@ async function crawlModuleGraph(env, entry) {
|
|
|
53
56
|
level = next;
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
function preloadUrls(env, entry, base) {
|
|
59
|
+
function preloadUrls(env, entry, base, staticImports) {
|
|
57
60
|
const root = env.moduleGraph.urlToModuleMap.get(entry);
|
|
58
61
|
const queue = root ? [root] : [];
|
|
59
62
|
const seen = new Set(queue);
|
|
@@ -64,6 +67,7 @@ function preloadUrls(env, entry, base) {
|
|
|
64
67
|
if (seen.has(dep) || !dep.transformResult) continue;
|
|
65
68
|
const url = browserImportUrl(dep, base);
|
|
66
69
|
if (!code.includes(`"${url}"`) && !code.includes(`'${url}'`)) continue;
|
|
70
|
+
if (isLazyDependencyChunk(env, mod, url, staticImports)) continue;
|
|
67
71
|
if (urls.length === MAX_PRELOADED_MODULES) return urls;
|
|
68
72
|
seen.add(dep);
|
|
69
73
|
queue.push(dep);
|
|
@@ -72,6 +76,27 @@ function preloadUrls(env, entry, base) {
|
|
|
72
76
|
}
|
|
73
77
|
return urls;
|
|
74
78
|
}
|
|
79
|
+
/** A chunk a pre-bundled dependency imports dynamically, such as one of a highlighter's hundreds of grammars. */
|
|
80
|
+
function isLazyDependencyChunk(env, importer, url, staticImports) {
|
|
81
|
+
if (!env.depsOptimizer?.isOptimizedDepUrl(importer.url)) return false;
|
|
82
|
+
return !staticImports(importer).has(url);
|
|
83
|
+
}
|
|
84
|
+
/** Reads the specifiers a module's served code imports statically; unparseable code yields none. */
|
|
85
|
+
function staticImportReader(parse) {
|
|
86
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
87
|
+
return (mod) => {
|
|
88
|
+
const result = mod.transformResult;
|
|
89
|
+
if (!result) return /* @__PURE__ */ new Set();
|
|
90
|
+
let imports = cache.get(result);
|
|
91
|
+
if (imports) return imports;
|
|
92
|
+
imports = /* @__PURE__ */ new Set();
|
|
93
|
+
try {
|
|
94
|
+
for (const node of parse(result.code).body) if ((node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && typeof node.source?.value === "string") imports.add(node.source.value);
|
|
95
|
+
} catch {}
|
|
96
|
+
cache.set(result, imports);
|
|
97
|
+
return imports;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
75
100
|
function browserImportUrl(mod, base) {
|
|
76
101
|
let url = mod.url.startsWith("/") ? mod.url : `/@id/${mod.url.replace("\0", "__x00__")}`;
|
|
77
102
|
if (mod.lastHMRTimestamp > 0) url = injectQuery(url, `t=${mod.lastHMRTimestamp}`);
|
|
@@ -12,14 +12,15 @@ function devModulePreloadPlugin(options = {}) {
|
|
|
12
12
|
return {
|
|
13
13
|
name: "lovable:dev-module-preload",
|
|
14
14
|
apply: "serve",
|
|
15
|
-
configureServer(server) {
|
|
15
|
+
async configureServer(server) {
|
|
16
16
|
if (process.env["LOVABLE_DEV_MODULE_PRELOAD"] !== "1") return;
|
|
17
17
|
if (server.config.experimental?.bundledDev) return;
|
|
18
18
|
const client = server.environments?.client;
|
|
19
19
|
if (!client) return;
|
|
20
|
+
const staticImports = staticImportReader((await import("vite")).parseAst);
|
|
20
21
|
let crawl;
|
|
21
22
|
const recrawl = () => {
|
|
22
|
-
crawl ??= crawlModuleGraph(client, entry).finally(() => {
|
|
23
|
+
crawl ??= crawlModuleGraph(client, entry, server.config.base, staticImports).finally(() => {
|
|
23
24
|
crawl = void 0;
|
|
24
25
|
});
|
|
25
26
|
};
|
|
@@ -27,14 +28,14 @@ function devModulePreloadPlugin(options = {}) {
|
|
|
27
28
|
server.middlewares.use((req, res, next) => {
|
|
28
29
|
if (req.method === "GET" && (req.headers.accept ?? "").includes("text/html")) {
|
|
29
30
|
recrawl();
|
|
30
|
-
injectAfterHead(res, () => modulePreloadTags(preloadUrls(client, entry, server.config.base)));
|
|
31
|
+
injectAfterHead(res, () => modulePreloadTags(preloadUrls(client, entry, server.config.base, staticImports)));
|
|
31
32
|
}
|
|
32
33
|
next();
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
|
-
async function crawlModuleGraph(env, entry) {
|
|
38
|
+
async function crawlModuleGraph(env, entry, base, staticImports) {
|
|
38
39
|
const queued = /* @__PURE__ */ new Set([entry]);
|
|
39
40
|
let level = [entry];
|
|
40
41
|
while (level.length > 0) {
|
|
@@ -43,8 +44,10 @@ async function crawlModuleGraph(env, entry) {
|
|
|
43
44
|
try {
|
|
44
45
|
await env.transformRequest(url);
|
|
45
46
|
const mod = await env.moduleGraph.getModuleByUrl(url);
|
|
46
|
-
|
|
47
|
+
if (!mod) return;
|
|
48
|
+
for (const dep of mod.importedModules) {
|
|
47
49
|
if (dep.id === null || queued.has(dep.url) || queued.size >= MAX_PRELOADED_MODULES) continue;
|
|
50
|
+
if (isLazyDependencyChunk(env, mod, browserImportUrl(dep, base), staticImports)) continue;
|
|
48
51
|
queued.add(dep.url);
|
|
49
52
|
next.push(dep.url);
|
|
50
53
|
}
|
|
@@ -53,7 +56,7 @@ async function crawlModuleGraph(env, entry) {
|
|
|
53
56
|
level = next;
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
|
-
function preloadUrls(env, entry, base) {
|
|
59
|
+
function preloadUrls(env, entry, base, staticImports) {
|
|
57
60
|
const root = env.moduleGraph.urlToModuleMap.get(entry);
|
|
58
61
|
const queue = root ? [root] : [];
|
|
59
62
|
const seen = new Set(queue);
|
|
@@ -64,6 +67,7 @@ function preloadUrls(env, entry, base) {
|
|
|
64
67
|
if (seen.has(dep) || !dep.transformResult) continue;
|
|
65
68
|
const url = browserImportUrl(dep, base);
|
|
66
69
|
if (!code.includes(`"${url}"`) && !code.includes(`'${url}'`)) continue;
|
|
70
|
+
if (isLazyDependencyChunk(env, mod, url, staticImports)) continue;
|
|
67
71
|
if (urls.length === MAX_PRELOADED_MODULES) return urls;
|
|
68
72
|
seen.add(dep);
|
|
69
73
|
queue.push(dep);
|
|
@@ -72,6 +76,27 @@ function preloadUrls(env, entry, base) {
|
|
|
72
76
|
}
|
|
73
77
|
return urls;
|
|
74
78
|
}
|
|
79
|
+
/** A chunk a pre-bundled dependency imports dynamically, such as one of a highlighter's hundreds of grammars. */
|
|
80
|
+
function isLazyDependencyChunk(env, importer, url, staticImports) {
|
|
81
|
+
if (!env.depsOptimizer?.isOptimizedDepUrl(importer.url)) return false;
|
|
82
|
+
return !staticImports(importer).has(url);
|
|
83
|
+
}
|
|
84
|
+
/** Reads the specifiers a module's served code imports statically; unparseable code yields none. */
|
|
85
|
+
function staticImportReader(parse) {
|
|
86
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
87
|
+
return (mod) => {
|
|
88
|
+
const result = mod.transformResult;
|
|
89
|
+
if (!result) return /* @__PURE__ */ new Set();
|
|
90
|
+
let imports = cache.get(result);
|
|
91
|
+
if (imports) return imports;
|
|
92
|
+
imports = /* @__PURE__ */ new Set();
|
|
93
|
+
try {
|
|
94
|
+
for (const node of parse(result.code).body) if ((node.type === "ImportDeclaration" || node.type === "ExportNamedDeclaration" || node.type === "ExportAllDeclaration") && typeof node.source?.value === "string") imports.add(node.source.value);
|
|
95
|
+
} catch {}
|
|
96
|
+
cache.set(result, imports);
|
|
97
|
+
return imports;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
75
100
|
function browserImportUrl(mod, base) {
|
|
76
101
|
let url = mod.url.startsWith("/") ? mod.url : `/@id/${mod.url.replace("\0", "__x00__")}`;
|
|
77
102
|
if (mod.lastHMRTimestamp > 0) url = injectQuery(url, `t=${mod.lastHMRTimestamp}`);
|
package/dist/index.cjs
CHANGED
|
@@ -105,7 +105,7 @@ function lovableAssetsProxyPlugin() {
|
|
|
105
105
|
//#endregion
|
|
106
106
|
//#region package.json
|
|
107
107
|
var name = "@lovable.dev/vite-tanstack-config";
|
|
108
|
-
var version = "2.
|
|
108
|
+
var version = "2.26.0";
|
|
109
109
|
//#endregion
|
|
110
110
|
//#region src/logging.ts
|
|
111
111
|
const PACKAGE_NAME = "@lovable.dev/vite-tanstack-config";
|
|
@@ -1823,6 +1823,7 @@ function defineConfig(configOrOptions = {}) {
|
|
|
1823
1823
|
...userNitroOpts.cloudflare
|
|
1824
1824
|
};
|
|
1825
1825
|
}
|
|
1826
|
+
nitroOpts.minify = process.env.LOVABLE_SERVER_MINIFY !== "0";
|
|
1826
1827
|
} else if (!nitroOpts.preset && !await nitroSupportsDefaultPreset()) logWarning("The installed `nitro` predates the `defaultPreset` option (3.0.260603-beta), so the Cloudflare fallback is ignored and a zero-config build may target Node instead. Upgrade nitro to >=3.0.260603-beta, or set an explicit `nitro: { preset: \"cloudflare-module\" }`.");
|
|
1827
1828
|
const nitroDirs = prerenderEnabled || isSandbox ? prerenderShimDirs(options.vite, nitroOpts) : void 0;
|
|
1828
1829
|
internalPlugins.push(nitro(nitroOpts));
|
|
@@ -1851,7 +1852,7 @@ function defineConfig(configOrOptions = {}) {
|
|
|
1851
1852
|
internalPlugins.push(linkedDependenciesPlugin());
|
|
1852
1853
|
const { devServerBridgePlugin } = await Promise.resolve().then(() => require("./dev-server-bridge.cjs"));
|
|
1853
1854
|
internalPlugins.push(devServerBridgePlugin());
|
|
1854
|
-
const { devModulePreloadPlugin } = await Promise.resolve().then(() => require("./devModulePreload-
|
|
1855
|
+
const { devModulePreloadPlugin } = await Promise.resolve().then(() => require("./devModulePreload-D7H42V_N.cjs"));
|
|
1855
1856
|
internalPlugins.push(devModulePreloadPlugin());
|
|
1856
1857
|
}
|
|
1857
1858
|
if (command === "serve") internalPlugins.push(lovableAssetsProxyPlugin());
|
package/dist/index.d.cts
CHANGED
|
@@ -57,7 +57,8 @@ interface LovableViteTanstackOptions {
|
|
|
57
57
|
* - **`false`**: skip nitro entirely.
|
|
58
58
|
*
|
|
59
59
|
* Inside a Lovable build `LOVABLE_NITRO_PRESET` (Cloudflare by default) pins
|
|
60
|
-
* the preset and output layout
|
|
60
|
+
* the preset and output layout and the server bundle is minified unless
|
|
61
|
+
* `LOVABLE_SERVER_MINIFY=0`; overrides here apply only outside it.
|
|
61
62
|
*
|
|
62
63
|
* The option surface is narrow on purpose — Nitro v3 is still pre-RC, so
|
|
63
64
|
* we only expose stable build-time knobs to reduce churn if
|
package/dist/index.d.ts
CHANGED
|
@@ -57,7 +57,8 @@ interface LovableViteTanstackOptions {
|
|
|
57
57
|
* - **`false`**: skip nitro entirely.
|
|
58
58
|
*
|
|
59
59
|
* Inside a Lovable build `LOVABLE_NITRO_PRESET` (Cloudflare by default) pins
|
|
60
|
-
* the preset and output layout
|
|
60
|
+
* the preset and output layout and the server bundle is minified unless
|
|
61
|
+
* `LOVABLE_SERVER_MINIFY=0`; overrides here apply only outside it.
|
|
61
62
|
*
|
|
62
63
|
* The option surface is narrow on purpose — Nitro v3 is still pre-RC, so
|
|
63
64
|
* we only expose stable build-time knobs to reduce churn if
|
package/dist/index.js
CHANGED
|
@@ -81,7 +81,7 @@ function lovableAssetsProxyPlugin() {
|
|
|
81
81
|
//#endregion
|
|
82
82
|
//#region package.json
|
|
83
83
|
var name = "@lovable.dev/vite-tanstack-config";
|
|
84
|
-
var version = "2.
|
|
84
|
+
var version = "2.26.0";
|
|
85
85
|
//#endregion
|
|
86
86
|
//#region src/logging.ts
|
|
87
87
|
const PACKAGE_NAME = "@lovable.dev/vite-tanstack-config";
|
|
@@ -1799,6 +1799,7 @@ function defineConfig(configOrOptions = {}) {
|
|
|
1799
1799
|
...userNitroOpts.cloudflare
|
|
1800
1800
|
};
|
|
1801
1801
|
}
|
|
1802
|
+
nitroOpts.minify = process.env.LOVABLE_SERVER_MINIFY !== "0";
|
|
1802
1803
|
} else if (!nitroOpts.preset && !await nitroSupportsDefaultPreset()) logWarning("The installed `nitro` predates the `defaultPreset` option (3.0.260603-beta), so the Cloudflare fallback is ignored and a zero-config build may target Node instead. Upgrade nitro to >=3.0.260603-beta, or set an explicit `nitro: { preset: \"cloudflare-module\" }`.");
|
|
1803
1804
|
const nitroDirs = prerenderEnabled || isSandbox ? prerenderShimDirs(options.vite, nitroOpts) : void 0;
|
|
1804
1805
|
internalPlugins.push(nitro(nitroOpts));
|
|
@@ -1827,7 +1828,7 @@ function defineConfig(configOrOptions = {}) {
|
|
|
1827
1828
|
internalPlugins.push(linkedDependenciesPlugin());
|
|
1828
1829
|
const { devServerBridgePlugin } = await import("./dev-server-bridge.js");
|
|
1829
1830
|
internalPlugins.push(devServerBridgePlugin());
|
|
1830
|
-
const { devModulePreloadPlugin } = await import("./devModulePreload-
|
|
1831
|
+
const { devModulePreloadPlugin } = await import("./devModulePreload-BOSHEX8Y.js");
|
|
1831
1832
|
internalPlugins.push(devModulePreloadPlugin());
|
|
1832
1833
|
}
|
|
1833
1834
|
if (command === "serve") internalPlugins.push(lovableAssetsProxyPlugin());
|