Gesamte Mono-Repo des Baukastens (alle apps/clients, examples/tests und packages)
dh_heyart
vor 4 Std. 7b1747b3214ec3de482f775cede2649c26e836a9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import fs from "node:fs";
import path from "node:path";
import {BuildEnvironmentOptions} from "vite";
 
// The @dh-software/* packages are pnpm-linked. Some link straight into the local
// node_modules/.pnpm store (their realpath still contains "@dh-software"), but the
// dev-linked ones (furnview-components, webui-api, ...) resolve through the global
// store down to source folders like C:/furnview_dev/furnview-components — a realpath
// that does NOT contain "@dh-software". Matching by realpath root catches both.
const dhScopeDir = path.join(process.cwd(), "node_modules", "@dh-software");
 
const wuiRoots: string[] = []; // @dh-software/webui-*
const dhRoots: string[] = [];  // the rest of @dh-software (components + icons)
for (const name of fs.readdirSync(dhScopeDir)) {
    if (name === "vite") continue; // build-time only, never in the client bundle
    try {
        const root = fs.realpathSync(path.join(dhScopeDir, name)).replace(/\\/g, "/");
        (name.startsWith("webui") ? wuiRoots : dhRoots).push(root);
    } catch {
        // broken/dangling link — skip
    }
}
 
const norm = (id: string): string => id.replace(/\\/g, "/");
 
// A module belongs to one of these packages only if it's the package's OWN code
// (under its root, but not inside a nested node_modules). Nested deps such as lit
// or @dh-software/lit-extensions therefore fall through to the "vendor" group —
// which is what keeps the chunk graph acyclic: if a shared lib like lit-extensions
// stayed in "dh", then webui-* (wui) importing it plus furnview-components (dh)
// importing webui-* would form a circular dh <-> wui chunk dependency.
const ownModuleOf = (id: string, roots: string[]): boolean => {
    const n = norm(id);
    return roots.some(root => n.startsWith(root + "/") && !n.slice(root.length).includes("/node_modules/"));
};
 
const isWui = (id: string): boolean => ownModuleOf(id, wuiRoots);
const isDh = (id: string): boolean => ownModuleOf(id, dhRoots);
 
interface CodeSplittingGroup {
    name: string;
    priority?: number;
    test: (id: string) => boolean;
}
 
const groups: CodeSplittingGroup[] = [
    // First-party @dh-software code wins over the generic "vendor" catch-all.
    // webui-* -> wui, the rest (components, icons) -> dh.
    {name: "dh", priority: 2, test: isDh},
    {name: "wui", priority: 2, test: isWui},
    // Everything else in node_modules (lit, lit-extensions, xlsx, ...).
    {name: "vendor", priority: 1, test: (id) => norm(id).includes("/node_modules/")},
];
 
const vendorNames = new Set(groups.map(g => g.name));
 
export const rolldownOptions: BuildEnvironmentOptions["rolldownOptions"] = {
    output: {
        // Vendor chunks go under dist/vendor/<name>.chunk.js; anything else keeps
        // the standard fv.[hash].js entry-style naming at the dist root.
        chunkFileNames: (chunk) =>
            vendorNames.has(chunk.name) ? `vendor/${chunk.name}.chunk.js` : "fv.[hash].js",
        codeSplitting: {
            // Without this, every group also drags in its captured modules' full
            // dependency tree, so the "dh" group would swallow lit before the
            // "vendor" group could claim it.
            includeDependenciesRecursively: false,
            groups,
        },
    },
};