vue-ssr-lite 0.2.12 → 0.2.15

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 CHANGED
@@ -42,12 +42,19 @@ It includes routing, browser hydration, production builds, a managed Node server
42
42
  | `vue-ssr-lite/server` | Managed Node server, config compile, host matching, cookies |
43
43
  | `vue-ssr-lite/vite` | Vite plugin that wires HTML templates and virtual client entries |
44
44
 
45
- CLI binary (auto-discovers `ssr.config.ts|.mts|.js|.mjs` in the project root):
45
+ CLI binary:
46
46
 
47
47
  ```bash
48
48
  vue-ssr-lite <dev|build|start> [--root .] [--config ssr.config.ts] [--server-output dist/server/SsrRuntime.js] [--hmr-port 31001]
49
49
  ```
50
50
 
51
+ - `dev` / `build` auto-discover `ssr.config.ts|.mts|.js|.mjs` in the project root
52
+ (or take `--config`).
53
+ - `start` loads the baked production runtime
54
+ (`dist/server/SsrRuntime.js` or `--server-output`) and does **not** require
55
+ source `ssr.config.*` in the working directory — slim Docker images only need
56
+ `package.json`, production `node_modules`, and `dist/`.
57
+
51
58
  Requires Node.js 20 or newer.
52
59
 
53
60
  Development servers use an operating-system-assigned HMR WebSocket port, so
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Vite 7 `resolveRollupOptions` path-resolves a string `build.ssr` entry against
3
+ * the project root. Virtual ids such as `virtual:vue-ssr-lite/runtime` become
4
+ * filesystem paths like `<root>/virtual:vue-ssr-lite/runtime`, so plugin
5
+ * `resolveId` never matches and Rollup reports `UNRESOLVED_ENTRY`.
6
+ *
7
+ * Pass the virtual module through `rollupOptions.input` with `build.ssr: true`
8
+ * instead — that path is not filesystem-resolved.
9
+ */
10
+ export declare const createSsrProductionViteBuildOptions: (root: string) => {
11
+ root: string;
12
+ build: {
13
+ ssr: true;
14
+ outDir: string;
15
+ emptyOutDir: boolean;
16
+ rollupOptions: {
17
+ input: string;
18
+ output: {
19
+ entryFileNames: string;
20
+ };
21
+ };
22
+ };
23
+ };
24
+ //# sourceMappingURL=SsrCliBuildOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SsrCliBuildOptions.d.ts","sourceRoot":"","sources":["../../src/cli/SsrCliBuildOptions.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,eAAO,MAAM,mCAAmC,GAAI,MAAM,MAAM;;;;;;;;;;;;;CAW9D,CAAA"}
@@ -0,0 +1,22 @@
1
+ export type SsrCliCommand = 'dev' | 'build' | 'start';
2
+ export interface SsrCliOptions {
3
+ command: SsrCliCommand;
4
+ root: string;
5
+ /**
6
+ * Absolute path to `ssr.config.*`. Present for `dev` / `build` only —
7
+ * production `start` loads the baked runtime and never reads source config.
8
+ */
9
+ config?: string;
10
+ serverOutput: string;
11
+ hmrPort?: string;
12
+ }
13
+ /**
14
+ * Parse CLI argv for `vue-ssr-lite <dev|build|start>`.
15
+ *
16
+ * - `dev` / `build` discover (or accept `--config`) source `ssr.config.*`.
17
+ * - `start` only requires the baked server bundle (`--server-output` or
18
+ * `dist/server/SsrRuntime.js`) so slim production images need not COPY
19
+ * source config.
20
+ */
21
+ export declare const parseSsrCliArguments: (args: string[]) => Promise<SsrCliOptions>;
22
+ //# sourceMappingURL=SsrCliOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SsrCliOptions.d.ts","sourceRoot":"","sources":["../../src/cli/SsrCliOptions.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,CAAA;AAErD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAqBD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EAAE,KACb,OAAO,CAAC,aAAa,CAgCvB,CAAA"}
package/dist/cli.mjs CHANGED
@@ -1,98 +1,116 @@
1
1
  #!/usr/bin/env node
2
- import { resolve as c } from "node:path";
3
- import { pathToFileURL as f } from "node:url";
4
- import { r as w, S as u } from "./chunks/SsrHtmlRuntime-BJUxjM2F.mjs";
2
+ import { pathToFileURL as v } from "node:url";
3
+ import { S as m, r as w } from "./chunks/SsrHtmlRuntime-BJUxjM2F.mjs";
5
4
  import { c as S } from "./chunks/SsrServerRuntime-BbWemkgs.mjs";
5
+ import { resolve as d } from "node:path";
6
6
  import { createServer as R } from "node:net";
7
- const i = 1, a = 65535, b = (r) => {
8
- const e = r?.trim();
9
- if (!e) return;
10
- if (!/^\d+$/.test(e))
11
- throw new Error(`HMR port must be an integer between ${i} and ${a}.`);
12
- const t = Number(e);
13
- if (!Number.isInteger(t) || t < i || t > a)
14
- throw new Error(`HMR port must be an integer between ${i} and ${a}.`);
15
- return t;
16
- }, h = () => new Promise((r, e) => {
17
- const t = R();
18
- t.once("error", e), t.listen({ port: 0, exclusive: !0 }, () => {
19
- const o = t.address();
7
+ import { access as h } from "node:fs/promises";
8
+ const b = (r) => ({
9
+ root: r,
10
+ build: {
11
+ ssr: !0,
12
+ outDir: d(r, "dist/server"),
13
+ emptyOutDir: !0,
14
+ rollupOptions: {
15
+ input: m,
16
+ output: { entryFileNames: "SsrRuntime.js" }
17
+ }
18
+ }
19
+ }), a = 1, c = 65535, P = (r) => {
20
+ const t = r?.trim();
21
+ if (!t) return;
22
+ if (!/^\d+$/.test(t))
23
+ throw new Error(`HMR port must be an integer between ${a} and ${c}.`);
24
+ const e = Number(t);
25
+ if (!Number.isInteger(e) || e < a || e > c)
26
+ throw new Error(`HMR port must be an integer between ${a} and ${c}.`);
27
+ return e;
28
+ }, T = () => new Promise((r, t) => {
29
+ const e = R();
30
+ e.once("error", t), e.listen({ port: 0, exclusive: !0 }, () => {
31
+ const o = e.address();
20
32
  if (!o || typeof o == "string") {
21
- t.close(), e(new Error("Unable to allocate an HMR WebSocket port."));
33
+ e.close(), t(new Error("Unable to allocate an HMR WebSocket port."));
22
34
  return;
23
35
  }
24
- t.close((s) => {
25
- s ? e(s) : r(o.port);
36
+ e.close((s) => {
37
+ s ? t(s) : r(o.port);
26
38
  });
27
39
  });
28
- }), P = async (r) => b(r) ?? h(), n = (r, e) => {
29
- const t = r.indexOf(e);
30
- return t >= 0 ? r[t + 1] : void 0;
31
- }, T = async (r) => {
32
- const e = r[0];
33
- if (!["dev", "build", "start"].includes(e))
40
+ }), g = async (r) => P(r) ?? T(), y = "dist/server/SsrRuntime.js", i = (r, t) => {
41
+ const e = r.indexOf(t);
42
+ return e >= 0 ? r[e + 1] : void 0;
43
+ }, E = async (r) => {
44
+ try {
45
+ await h(r);
46
+ } catch {
47
+ throw new Error(
48
+ `vue-ssr-lite start could not find the production SSR runtime at ${r}. Run \`vue-ssr-lite build\` first. Production start loads the baked runtime and does not require ssr.config.* in the working directory.`
49
+ );
50
+ }
51
+ }, _ = async (r) => {
52
+ const t = r[0];
53
+ if (!["dev", "build", "start"].includes(t))
34
54
  throw new Error(
35
55
  "Usage: vue-ssr-lite <dev|build|start> [--root .] [--config ssr.config.ts] [--hmr-port 31001]"
36
56
  );
37
- const t = c(n(r, "--root") || process.cwd()), o = await w(t, n(r, "--config"));
57
+ const e = d(i(r, "--root") || process.cwd()), o = d(
58
+ e,
59
+ i(r, "--server-output") || y
60
+ ), s = i(r, "--hmr-port") || process.env.VUE_SSR_LITE_HMR_PORT;
61
+ if (t === "start")
62
+ return await E(o), {
63
+ command: "start",
64
+ root: e,
65
+ serverOutput: o,
66
+ hmrPort: s
67
+ };
68
+ const n = await w(e, i(r, "--config"));
38
69
  return {
39
- command: e,
40
- root: t,
41
- config: o,
42
- serverOutput: c(
43
- t,
44
- n(r, "--server-output") || "dist/server/SsrRuntime.js"
45
- ),
46
- hmrPort: n(r, "--hmr-port") || process.env.VUE_SSR_LITE_HMR_PORT
70
+ command: t,
71
+ root: e,
72
+ config: n,
73
+ serverOutput: o,
74
+ hmrPort: s
47
75
  };
48
- }, g = async (r, e) => {
49
- const t = e ? void 0 : await P(r.hmrPort), o = e ? void 0 : (await import("vite")).createServer, s = e ? void 0 : await o({
76
+ }, I = async (r, t) => {
77
+ const e = t ? void 0 : await g(r.hmrPort), o = t ? void 0 : (await import("vite")).createServer, s = t ? void 0 : await o({
50
78
  root: r.root,
51
79
  server: {
52
80
  middlewareMode: !0,
53
- hmr: { port: t, clientPort: t }
81
+ hmr: { port: e, clientPort: e }
54
82
  },
55
83
  appType: "custom"
56
- }), l = await S({
57
- production: e,
84
+ }), n = await S({
85
+ production: t,
58
86
  root: r.root,
59
87
  vite: s,
60
- loadRuntime: e ? () => import(f(r.serverOutput).href) : () => s.ssrLoadModule(u)
88
+ loadRuntime: t ? () => import(v(r.serverOutput).href) : () => s.ssrLoadModule(m)
61
89
  });
62
- await l.listen();
63
- let d = !1;
64
- const m = async (p) => {
65
- if (!d) {
66
- d = !0;
90
+ await n.listen();
91
+ let u = !1;
92
+ const l = async (p) => {
93
+ if (!u) {
94
+ u = !0;
67
95
  try {
68
- await l.close(), console.log(`stopped after ${p}`), process.exitCode = 0;
69
- } catch (v) {
70
- console.error("graceful shutdown failed", v), process.exitCode = 1;
96
+ await n.close(), console.log(`stopped after ${p}`), process.exitCode = 0;
97
+ } catch (f) {
98
+ console.error("graceful shutdown failed", f), process.exitCode = 1;
71
99
  }
72
100
  }
73
101
  };
74
102
  process.once("SIGINT", () => {
75
- m("SIGINT");
103
+ l("SIGINT");
76
104
  }), process.once("SIGTERM", () => {
77
- m("SIGTERM");
78
- });
79
- }, I = async (r) => {
80
- const { build: e } = await import("vite");
81
- await e({ root: r.root }), await e({
82
- root: r.root,
83
- build: {
84
- ssr: u,
85
- outDir: c(r.root, "dist/server"),
86
- emptyOutDir: !0,
87
- rollupOptions: {
88
- output: { entryFileNames: "SsrRuntime.js" }
89
- }
90
- }
105
+ l("SIGTERM");
91
106
  });
92
- }, M = async () => {
93
- const r = await T(process.argv.slice(2));
94
- return r.command === "build" ? I(r) : g(r, r.command === "start");
107
+ }, M = async (r) => {
108
+ const { build: t } = await import("vite");
109
+ await t({ root: r.root }), await t(b(r.root));
110
+ }, C = async () => {
111
+ const r = await _(process.argv.slice(2));
112
+ return r.command === "build" ? M(r) : I(r, r.command === "start");
95
113
  };
96
- M().catch((r) => {
114
+ C().catch((r) => {
97
115
  console.error("fatal error", r), process.exitCode = 1;
98
116
  });
@@ -1 +1 @@
1
- {"version":3,"file":"SsrVitePlugin.d.ts","sourceRoot":"","sources":["../../src/vite/SsrVitePlugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AAEjD,OAAO,EAQL,KAAK,uBAAuB,EAE7B,MAAM,4BAA4B,CAAA;AAGnC,YAAY,EAAE,uBAAuB,EAAE,CAAA;AAEvC,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;CACpC;AAuBD,eAAO,MAAM,UAAU,GAAI,UAAS,oBAAyB,KAAG,MAmJ/D,CAAA"}
1
+ {"version":3,"file":"SsrVitePlugin.d.ts","sourceRoot":"","sources":["../../src/vite/SsrVitePlugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AAEjD,OAAO,EAQL,KAAK,uBAAuB,EAE7B,MAAM,4BAA4B,CAAA;AAGnC,YAAY,EAAE,uBAAuB,EAAE,CAAA;AAEvC,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;CACpC;AAgCD,eAAO,MAAM,UAAU,GAAI,UAAS,oBAAyB,KAAG,MAsJ/D,CAAA"}
package/dist/vite.mjs CHANGED
@@ -1,16 +1,16 @@
1
1
  import { resolve as d } from "node:path";
2
- import { normalizePath as S } from "vite";
3
- import { r as R, k as C, a as m, S as _, n as D, h as $, p as O, j as T } from "./chunks/SsrHtmlRuntime-BJUxjM2F.mjs";
2
+ import { normalizePath as g } from "vite";
3
+ import { r as _, k as $, a as m, S, n as D, h as C, p as O, j as T } from "./chunks/SsrHtmlRuntime-BJUxjM2F.mjs";
4
4
  const L = [
5
5
  "@vue/server-renderer",
6
6
  "vue",
7
7
  "vue-router",
8
8
  "vue-ssr-lite"
9
- ], h = `\0${_}`, p = `\0${m}`, f = "dist/client", U = /<script\b(?=[^>]*\btype\s*=\s*["']module["'])(?=[^>]*\bsrc\s*=\s*["'][^"']+["'])[^>]*>\s*<\/script>/gi, b = (a, r) => {
10
- const n = S(a);
11
- return r && n === S(r) ? !0 : /\/ssr\.config\.(ts|mts|js|mjs)$/.test(n);
12
- }, F = (a = {}) => {
13
- let r = d(a.root || process.cwd()), n = "", o = null, E = f;
9
+ ], I = `\0${S}`, p = `\0${m}`, f = "dist/client", U = (r) => r === S || r.endsWith(`/${S}`) || r.endsWith(`\\${S}`), b = /<script\b(?=[^>]*\btype\s*=\s*["']module["'])(?=[^>]*\bsrc\s*=\s*["'][^"']+["'])[^>]*>\s*<\/script>/gi, N = (r, n) => {
10
+ const i = g(r);
11
+ return n && i === g(n) ? !0 : /\/ssr\.config\.(ts|mts|js|mjs)$/.test(i);
12
+ }, P = (r = {}) => {
13
+ let n = d(r.root || process.cwd()), i = "", o = null, E = f;
14
14
  const c = /* @__PURE__ */ new Map(), w = () => {
15
15
  c.clear();
16
16
  for (const t of o?.applications ?? [])
@@ -22,90 +22,93 @@ const L = [
22
22
  o = null, c.clear(), E = f;
23
23
  }, u = async () => {
24
24
  if (o) return o;
25
- n = await R(r, a.config);
26
- const t = await D(r, n);
27
- return o = $(t), E = t.server?.clientOutDir || f, w(), o;
28
- }, I = (t) => {
29
- const e = t.moduleGraph.getModuleById(h);
25
+ i = await _(n, r.config);
26
+ const t = await D(n, i);
27
+ return o = C(t), E = t.server?.clientOutDir || f, w(), o;
28
+ }, R = (t) => {
29
+ const e = t.moduleGraph.getModuleById(I);
30
30
  e && t.moduleGraph.invalidateModule(e);
31
31
  for (const l of o?.applications ?? []) {
32
- const i = `${p}${l.id}`, s = t.moduleGraph.getModuleById(i);
33
- s && t.moduleGraph.invalidateModule(s);
32
+ const s = `${p}${l.id}`, a = t.moduleGraph.getModuleById(s);
33
+ a && t.moduleGraph.invalidateModule(a);
34
34
  }
35
35
  };
36
36
  return {
37
37
  name: "vue-ssr-lite",
38
38
  enforce: "pre",
39
+ // Keep one plugin instance across client/SSR environment config clones so
40
+ // virtual-module state stays consistent during production builds.
41
+ sharedDuringBuild: !0,
39
42
  async config(t, e) {
40
- r = d(a.root || t.root || process.cwd());
41
- const l = await u(), i = Object.fromEntries(
42
- l.applications.map((g) => [
43
- g.id,
44
- d(r, g.template)
43
+ n = d(r.root || t.root || process.cwd());
44
+ const l = await u(), s = Object.fromEntries(
45
+ l.applications.map((h) => [
46
+ h.id,
47
+ d(n, h.template)
45
48
  ])
46
- ), s = t.build?.outDir || E || f;
49
+ ), a = t.build?.outDir || E || f;
47
50
  return {
48
51
  resolve: {
49
- dedupe: [.../* @__PURE__ */ new Set([...L, ...a.dedupe ?? []])]
52
+ dedupe: [.../* @__PURE__ */ new Set([...L, ...r.dedupe ?? []])]
50
53
  },
51
54
  ssr: {
52
55
  external: ["vue-ssr-lite"],
53
- noExternal: [...new Set(a.ssrNoExternal ?? [])]
56
+ noExternal: [...new Set(r.ssrNoExternal ?? [])]
54
57
  },
55
58
  build: e.isSsrBuild ? void 0 : {
56
59
  manifest: !0,
57
- outDir: s,
58
- rollupOptions: { input: i }
60
+ outDir: a,
61
+ rollupOptions: { input: s }
59
62
  }
60
63
  };
61
64
  },
62
65
  configResolved(t) {
63
- r = t.root;
66
+ n = t.root;
64
67
  },
65
68
  configureServer(t) {
66
69
  u().then(() => {
67
- n && t.watcher.add(n);
70
+ i && t.watcher.add(i);
68
71
  });
69
72
  },
70
73
  async handleHotUpdate({ file: t, server: e }) {
71
- if (b(t, n))
72
- return I(e), y(), await u(), n && e.watcher.add(n), I(e), e.ws.send({ type: "full-reload" }), [];
74
+ if (N(t, i))
75
+ return R(e), y(), await u(), i && e.watcher.add(i), R(e), e.ws.send({ type: "full-reload" }), [];
73
76
  },
74
77
  resolveId(t) {
75
- if (t === _) return h;
78
+ if (U(t)) return I;
76
79
  if (c.has(t))
77
80
  return `${p}${t.slice(m.length)}`;
78
81
  },
79
82
  async load(t) {
80
- if (t === h) {
81
- const i = await u(), s = n || await R(r, a.config);
82
- return C(r, s, i.applications);
83
+ if (t === I) {
84
+ const s = await u(), a = i || await _(n, r.config);
85
+ return $(n, a, s.applications);
83
86
  }
84
87
  if (!t.startsWith(p)) return;
85
88
  const e = t.slice(p.length), l = o?.applications.find(
86
- ({ id: i }) => i === e
89
+ ({ id: s }) => s === e
87
90
  );
88
91
  if (l)
89
- return T(r, l);
92
+ return T(n, l);
90
93
  },
91
94
  transformIndexHtml: {
92
95
  order: "pre",
93
96
  handler(t, e) {
94
- const l = S(e.filename), i = o?.applications.find(
95
- (M) => l === S(d(r, M.template))
97
+ const l = g(e.filename), s = o?.applications.find(
98
+ (M) => l === g(d(n, M.template))
96
99
  );
97
- if (!i) return t;
98
- const s = `${m}${i.id}`, v = O(
100
+ if (!s) return t;
101
+ const a = `${m}${s.id}`, v = O(
99
102
  t,
100
- i.mountSelector || "#app"
101
- ).replace(U, "");
102
- return v.includes(`import ${JSON.stringify(s)}`) ? v : {
103
+ s.mountSelector || "#app"
104
+ ).replace(b, "");
105
+ return v.includes(`import ${JSON.stringify(a)}`) ? v : {
103
106
  html: v,
104
107
  tags: [
105
108
  {
106
109
  tag: "script",
107
110
  attrs: { type: "module" },
108
- children: `import ${JSON.stringify(s)}`,
111
+ children: `import ${JSON.stringify(a)}`,
109
112
  injectTo: "body"
110
113
  }
111
114
  ]
@@ -115,5 +118,5 @@ const L = [
115
118
  };
116
119
  };
117
120
  export {
118
- F as vueSsrLite
121
+ P as vueSsrLite
119
122
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue-ssr-lite",
3
- "version": "0.2.12",
3
+ "version": "0.2.15",
4
4
  "description": "Vue 3 SSR runtime with routing, generic plugin hydration, Vite, and Node server lifecycle.",
5
5
  "license": "MIT",
6
6
  "type": "module",