waku 0.13.0 → 0.14.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.
Files changed (55) hide show
  1. package/README.md +4 -9
  2. package/dist/cjs/lib/builder.js +20 -22
  3. package/dist/cjs/lib/config.js +26 -4
  4. package/dist/cjs/lib/middleware/devServer.js +5 -2
  5. package/dist/cjs/lib/middleware/rsc/worker-api.js +16 -0
  6. package/dist/cjs/lib/middleware/rsc/worker-impl.js +69 -41
  7. package/dist/cjs/lib/middleware/ssr.js +1 -1
  8. package/dist/cjs/lib/vite-plugin/rsc-analyze-plugin.js +1 -1
  9. package/dist/cjs/lib/vite-plugin/rsc-delegate-plugin.js +98 -0
  10. package/dist/cjs/lib/vite-plugin/rsc-hmr-plugin.js +70 -0
  11. package/dist/cjs/lib/vite-plugin/rsc-index-plugin.js +13 -2
  12. package/dist/cjs/lib/vite-plugin/rsc-reload-plugin.js +1 -1
  13. package/dist/cjs/node-loader.js +24 -0
  14. package/dist/lib/builder.js +20 -22
  15. package/dist/lib/config.d.ts +2 -2
  16. package/dist/lib/config.js +21 -4
  17. package/dist/lib/middleware/devServer.js +6 -3
  18. package/dist/lib/middleware/rsc/worker-api.d.ts +4 -0
  19. package/dist/lib/middleware/rsc/worker-api.js +13 -0
  20. package/dist/lib/middleware/rsc/worker-impl.js +69 -41
  21. package/dist/lib/middleware/ssr.js +1 -1
  22. package/dist/lib/vite-plugin/rsc-analyze-plugin.js +1 -1
  23. package/dist/lib/vite-plugin/rsc-delegate-plugin.d.ts +2 -0
  24. package/dist/lib/vite-plugin/rsc-delegate-plugin.js +44 -0
  25. package/dist/lib/vite-plugin/rsc-hmr-plugin.d.ts +3 -0
  26. package/dist/lib/vite-plugin/rsc-hmr-plugin.js +47 -0
  27. package/dist/lib/vite-plugin/rsc-index-plugin.d.ts +1 -1
  28. package/dist/lib/vite-plugin/rsc-index-plugin.js +13 -2
  29. package/dist/lib/vite-plugin/rsc-reload-plugin.js +1 -1
  30. package/dist/node-loader.d.ts +1 -0
  31. package/dist/node-loader.js +14 -0
  32. package/package.json +29 -21
  33. package/src/cli.ts +3 -3
  34. package/src/client.ts +3 -3
  35. package/src/config.ts +1 -1
  36. package/src/lib/builder.ts +64 -57
  37. package/src/lib/config.ts +16 -6
  38. package/src/lib/middleware/devServer.ts +11 -5
  39. package/src/lib/middleware/rsc/utils.ts +2 -2
  40. package/src/lib/middleware/rsc/worker-api.ts +21 -3
  41. package/src/lib/middleware/rsc/worker-impl.ts +84 -46
  42. package/src/lib/middleware/rsc.ts +3 -3
  43. package/src/lib/middleware/ssr/utils.ts +4 -4
  44. package/src/lib/middleware/ssr.ts +8 -8
  45. package/src/lib/vite-plugin/nonjs-resolve-plugin.ts +1 -1
  46. package/src/lib/vite-plugin/rsc-analyze-plugin.ts +2 -2
  47. package/src/lib/vite-plugin/rsc-delegate-plugin.ts +48 -0
  48. package/src/lib/vite-plugin/rsc-hmr-plugin.ts +39 -0
  49. package/src/lib/vite-plugin/rsc-index-plugin.ts +7 -1
  50. package/src/lib/vite-plugin/rsc-reload-plugin.ts +1 -1
  51. package/src/lib/vite-plugin/rsc-transform-plugin.ts +4 -4
  52. package/src/node-loader.ts +11 -0
  53. package/src/router/client.ts +4 -4
  54. package/src/router/server.ts +10 -10
  55. package/src/server.ts +5 -5
package/README.md CHANGED
@@ -21,18 +21,12 @@ yarn create waku
21
21
  ```
22
22
 
23
23
  ```bash
24
- pnpm create waku # pnpm not working for now
24
+ pnpm create waku
25
25
  ```
26
26
 
27
- ## Work in progress
27
+ ## Roadmap
28
28
 
29
- - [x] `waku dev` (development server)
30
- - [x] `waku build` (build for production)
31
- - [x] `waku start` (production server)
32
- - [x] Exportable build
33
- - [x] Static site generation
34
- - [x] Opt-in router (reference implementation)
35
- - [x] Opt-in SSR (HTML generation only)
29
+ https://github.com/dai-shi/waku/issues/24
36
30
 
37
31
  ## Tweets
38
32
 
@@ -75,6 +69,7 @@ pnpm create waku # pnpm not working for now
75
69
  - https://twitter.com/dai_shi/status/1667545252654366721
76
70
  - https://twitter.com/dai_shi/status/1670650381762961408
77
71
  - https://twitter.com/dai_shi/status/1671161795061628930
72
+ - https://twitter.com/dai_shi/status/1676793637282394112
78
73
 
79
74
  </details>
80
75
 
@@ -47,18 +47,10 @@ const analyzeEntries = async (entriesFile)=>{
47
47
  const clientEntryFileSet = new Set();
48
48
  const serverEntryFileSet = new Set();
49
49
  await (0, _vite.build)({
50
- ..._config.configFileConfig,
50
+ ...(0, _config.configFileConfig)(),
51
51
  plugins: [
52
52
  (0, _rscanalyzeplugin.rscAnalyzePlugin)((id)=>clientEntryFileSet.add(id), (id)=>serverEntryFileSet.add(id))
53
53
  ],
54
- ssr: {
55
- noExternal: /^(?!node:)/,
56
- // FIXME this is very adhoc.
57
- external: [
58
- "react",
59
- "minimatch"
60
- ]
61
- },
62
54
  resolve: {
63
55
  conditions: [
64
56
  "react-server"
@@ -90,11 +82,7 @@ const analyzeEntries = async (entriesFile)=>{
90
82
  };
91
83
  const buildServerBundle = async (config, entriesFile, clientEntryFiles, serverEntryFiles)=>{
92
84
  const serverBuildOutput = await (0, _vite.build)({
93
- ..._config.configFileConfig,
94
- ssr: {
95
- noExternal: Object.values(clientEntryFiles).map(// FIXME this might not work with pnpm
96
- (fname)=>_nodepath.default.relative(_nodepath.default.join(config.root, "node_modules"), fname).split("/")[0])
97
- },
85
+ ...(0, _config.configFileConfig)(),
98
86
  resolve: {
99
87
  conditions: [
100
88
  "react-server"
@@ -103,7 +91,8 @@ const buildServerBundle = async (config, entriesFile, clientEntryFiles, serverEn
103
91
  publicDir: false,
104
92
  build: {
105
93
  ssr: true,
106
- outDir: config.framework.distDir,
94
+ ssrEmitAssets: true,
95
+ outDir: _nodepath.default.join(config.root, config.framework.distDir),
107
96
  rollupOptions: {
108
97
  onwarn,
109
98
  input: {
@@ -138,16 +127,19 @@ const buildServerBundle = async (config, entriesFile, clientEntryFiles, serverEn
138
127
  }
139
128
  return serverBuildOutput;
140
129
  };
141
- const buildClientBundle = async (config, clientEntryFiles)=>{
130
+ const buildClientBundle = async (config, clientEntryFiles, serverBuildOutput)=>{
142
131
  const indexHtmlFile = _nodepath.default.join(config.root, config.framework.srcDir, config.framework.indexHtml);
132
+ const cssAssets = serverBuildOutput.output.flatMap(({ type, fileName })=>type === "asset" && fileName.endsWith(".css") ? [
133
+ fileName
134
+ ] : []);
143
135
  const clientBuildOutput = await (0, _vite.build)({
144
- ..._config.configFileConfig,
136
+ ...(0, _config.configFileConfig)(),
137
+ root: _nodepath.default.join(config.root, config.framework.srcDir),
145
138
  plugins: [
146
139
  // @ts-expect-error This expression is not callable.
147
140
  (0, _pluginreact.default)(),
148
- (0, _rscindexplugin.rscIndexPlugin)()
141
+ (0, _rscindexplugin.rscIndexPlugin)(cssAssets)
149
142
  ],
150
- root: _nodepath.default.join(config.root, config.framework.srcDir),
151
143
  build: {
152
144
  outDir: _nodepath.default.join(config.root, config.framework.distDir, config.framework.publicDir),
153
145
  rollupOptions: {
@@ -171,6 +163,11 @@ const buildClientBundle = async (config, clientEntryFiles)=>{
171
163
  if (!("output" in clientBuildOutput)) {
172
164
  throw new Error("Unexpected vite client build output");
173
165
  }
166
+ for (const cssAsset of cssAssets){
167
+ const from = _nodepath.default.join(config.root, config.framework.distDir, cssAsset);
168
+ const to = _nodepath.default.join(config.root, config.framework.distDir, config.framework.publicDir, cssAsset);
169
+ _nodefs.default.renameSync(from, to);
170
+ }
174
171
  return clientBuildOutput;
175
172
  };
176
173
  const emitRscFiles = async (config)=>{
@@ -197,7 +194,8 @@ const emitRscFiles = async (config)=>{
197
194
  const serializedProps = JSON.stringify(props);
198
195
  const searchParams = new URLSearchParams();
199
196
  searchParams.set("props", serializedProps);
200
- const destFile = _nodepath.default.join(config.root, config.framework.distDir, config.framework.publicDir, config.framework.rscPrefix + decodeURIComponent(rscId), decodeURIComponent(`${searchParams}`));
197
+ const destFile = _nodepath.default.join(config.root, config.framework.distDir, config.framework.publicDir, // HACK to support windows filesystem
198
+ config.framework.rscPrefix.replaceAll("/", _nodepath.default.sep) + decodeURIComponent(rscId), decodeURIComponent(`${searchParams}`));
201
199
  if (!rscFileSet.has(destFile)) {
202
200
  rscFileSet.add(destFile);
203
201
  _nodefs.default.mkdirSync(_nodepath.default.dirname(destFile), {
@@ -358,8 +356,8 @@ async function build() {
358
356
  const config = await (0, _config.resolveConfig)("build");
359
357
  const entriesFile = resolveFileName(_nodepath.default.join(config.root, config.framework.srcDir, config.framework.entriesJs));
360
358
  const { clientEntryFiles, serverEntryFiles } = await analyzeEntries(entriesFile);
361
- await buildServerBundle(config, entriesFile, clientEntryFiles, serverEntryFiles);
362
- const clientBuildOutput = await buildClientBundle(config, clientEntryFiles);
359
+ const serverBuildOutput = await buildServerBundle(config, entriesFile, clientEntryFiles, serverEntryFiles);
360
+ const clientBuildOutput = await buildClientBundle(config, clientEntryFiles, serverBuildOutput);
363
361
  const { buildConfig, getClientModules, rscFiles } = await emitRscFiles(config);
364
362
  const { htmlFiles } = await emitHtmlFiles(config, buildConfig, getClientModules);
365
363
  // https://vercel.com/docs/build-output-api/v3
@@ -16,7 +16,14 @@ _export(exports, {
16
16
  return resolveConfig;
17
17
  }
18
18
  });
19
+ const _nodefs = /*#__PURE__*/ _interop_require_default(require("node:fs"));
20
+ const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
19
21
  const _vite = require("vite");
22
+ function _interop_require_default(obj) {
23
+ return obj && obj.__esModule ? obj : {
24
+ default: obj
25
+ };
26
+ }
20
27
  const splitHTML = (htmlStr)=>{
21
28
  const P1 = [
22
29
  "<!--placeholder1-->\\s*<div[^>]*>",
@@ -40,11 +47,26 @@ const getFallback = (id)=>{
40
47
  }
41
48
  return "waku/server#ClientFallback";
42
49
  };
43
- const configFileConfig = process.env.CONFIG_FILE ? {
44
- configFile: process.env.CONFIG_FILE
45
- } : {};
50
+ const configFileConfig = ()=>{
51
+ if (process.env.CONFIG_FILE) {
52
+ return {
53
+ configFile: _nodepath.default.resolve(process.env.CONFIG_FILE)
54
+ };
55
+ }
56
+ for (const file of [
57
+ "vite.config.ts",
58
+ "vite.config.js"
59
+ ]){
60
+ if (_nodefs.default.existsSync(file)) {
61
+ return {
62
+ configFile: _nodepath.default.resolve(file)
63
+ };
64
+ }
65
+ }
66
+ return {};
67
+ };
46
68
  async function resolveConfig(command) {
47
- const origConfig = await (0, _vite.resolveConfig)(configFileConfig, command);
69
+ const origConfig = await (0, _vite.resolveConfig)(configFileConfig(), command);
48
70
  const origFramework = origConfig.framework;
49
71
  const framework = {
50
72
  srcDir: "src",
@@ -14,6 +14,7 @@ const _pluginreact = /*#__PURE__*/ _interop_require_default(require("@vitejs/plu
14
14
  const _config = require("../config.js");
15
15
  const _workerapi = require("./rsc/worker-api.js");
16
16
  const _rscindexplugin = require("../vite-plugin/rsc-index-plugin.js");
17
+ const _rschmrplugin = require("../vite-plugin/rsc-hmr-plugin.js");
17
18
  function _interop_require_default(obj) {
18
19
  return obj && obj.__esModule ? obj : {
19
20
  default: obj
@@ -22,7 +23,7 @@ function _interop_require_default(obj) {
22
23
  function devServer() {
23
24
  const configPromise = (0, _config.resolveConfig)("serve");
24
25
  const vitePromise = configPromise.then((config)=>(0, _vite.createServer)({
25
- ..._config.configFileConfig,
26
+ ...(0, _config.configFileConfig)(),
26
27
  root: _nodepath.default.join(config.root, config.framework.srcDir),
27
28
  optimizeDeps: {
28
29
  include: [
@@ -37,7 +38,8 @@ function devServer() {
37
38
  plugins: [
38
39
  // @ts-expect-error This expression is not callable.
39
40
  (0, _pluginreact.default)(),
40
- (0, _rscindexplugin.rscIndexPlugin)()
41
+ (0, _rscindexplugin.rscIndexPlugin)([]),
42
+ (0, _rschmrplugin.rscHmrPlugin)()
41
43
  ],
42
44
  server: {
43
45
  middlewareMode: true
@@ -47,6 +49,7 @@ function devServer() {
47
49
  (0, _workerapi.registerReloadCallback)((type)=>vite.ws.send({
48
50
  type
49
51
  }));
52
+ (0, _workerapi.registerImportCallback)((source)=>(0, _rschmrplugin.hotImport)(vite, source));
50
53
  });
51
54
  return async (req, res, next)=>{
52
55
  const vite = await vitePromise;
@@ -12,6 +12,9 @@ _export(exports, {
12
12
  registerReloadCallback: function() {
13
13
  return registerReloadCallback;
14
14
  },
15
+ registerImportCallback: function() {
16
+ return registerImportCallback;
17
+ },
15
18
  shutdown: function() {
16
19
  return shutdown;
17
20
  },
@@ -29,6 +32,10 @@ const _nodestream = require("node:stream");
29
32
  const _nodeworker_threads = require("node:worker_threads");
30
33
  const worker = new _nodeworker_threads.Worker(new URL("worker-impl.js", require("url").pathToFileURL(__filename).toString()), {
31
34
  execArgv: [
35
+ "--experimental-loader",
36
+ "waku/node-loader",
37
+ "--experimental-loader",
38
+ "react-server-dom-webpack/node-loader",
32
39
  "--conditions",
33
40
  "react-server"
34
41
  ]
@@ -48,6 +55,15 @@ function registerReloadCallback(fn) {
48
55
  worker.on("message", listener);
49
56
  return ()=>worker.off("message", listener);
50
57
  }
58
+ function registerImportCallback(fn) {
59
+ const listener = (mesg)=>{
60
+ if (mesg.type === "hot-import") {
61
+ fn(mesg.source);
62
+ }
63
+ };
64
+ worker.on("message", listener);
65
+ return ()=>worker.off("message", listener);
66
+ }
51
67
  function shutdown() {
52
68
  return new Promise((resolve)=>{
53
69
  worker.on("close", resolve);
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
6
6
  const _nodeworker_threads = require("node:worker_threads");
7
7
  const _nodestream = require("node:stream");
8
+ const _nodehttp = require("node:http");
8
9
  const _vite = require("vite");
9
10
  const _react = require("react");
10
11
  const _server = /*#__PURE__*/ _interop_require_default(require("react-server-dom-webpack/server"));
@@ -12,6 +13,7 @@ const _config = require("../../config.js");
12
13
  const _utils = require("./utils.js");
13
14
  const _rsctransformplugin = require("../../vite-plugin/rsc-transform-plugin.js");
14
15
  const _rscreloadplugin = require("../../vite-plugin/rsc-reload-plugin.js");
16
+ const _rscdelegateplugin = require("../../vite-plugin/rsc-delegate-plugin.js");
15
17
  function _interop_require_default(obj) {
16
18
  return obj && obj.__esModule ? obj : {
17
19
  default: obj
@@ -34,7 +36,7 @@ const handleRender = async (mesg)=>{
34
36
  _nodeworker_threads.parentPort.postMessage(mesg);
35
37
  };
36
38
  }
37
- const { runWithContext } = await loadServerFile("waku/server");
39
+ const { runWithContext } = await loadServerFile("waku/server", command);
38
40
  const pipeable = await runWithContext(ctx, ()=>renderRSC(input, options));
39
41
  const mesg = {
40
42
  id,
@@ -121,40 +123,62 @@ const handleGetSsrConfig = async (mesg)=>{
121
123
  _nodeworker_threads.parentPort.postMessage(mesg);
122
124
  }
123
125
  };
124
- const vitePromise = (0, _vite.createServer)({
125
- ..._config.configFileConfig,
126
- plugins: [
127
- (0, _rsctransformplugin.rscTransformPlugin)(),
128
- (0, _rscreloadplugin.rscReloadPlugin)((type)=>{
129
- const mesg = {
130
- type
131
- };
132
- _nodeworker_threads.parentPort.postMessage(mesg);
133
- })
134
- ],
135
- ssr: {
136
- noExternal: /^(?!node:)/,
137
- // FIXME this is very adhoc.
138
- external: [
139
- "react",
140
- "minimatch",
141
- "react-server-dom-webpack"
142
- ]
143
- },
144
- resolve: {
145
- conditions: [
146
- "react-server"
147
- ]
148
- },
149
- appType: "custom"
150
- });
126
+ const dummyServer = new _nodehttp.Server();
127
+ let lastViteServer;
128
+ const getViteServer = async (command)=>{
129
+ if (lastViteServer) {
130
+ if (lastViteServer[1] === command) {
131
+ return lastViteServer[0];
132
+ }
133
+ console.warn("Restarting Vite server with different command");
134
+ await lastViteServer[0].close();
135
+ }
136
+ const viteServer = await (0, _vite.createServer)({
137
+ ...(0, _config.configFileConfig)(),
138
+ plugins: [
139
+ (0, _rsctransformplugin.rscTransformPlugin)(),
140
+ (0, _rscreloadplugin.rscReloadPlugin)((type)=>{
141
+ const mesg = {
142
+ type
143
+ };
144
+ _nodeworker_threads.parentPort.postMessage(mesg);
145
+ }),
146
+ (0, _rscdelegateplugin.rscDelegatePlugin)((source)=>{
147
+ const mesg = {
148
+ type: "hot-import",
149
+ source
150
+ };
151
+ _nodeworker_threads.parentPort.postMessage(mesg);
152
+ })
153
+ ],
154
+ resolve: {
155
+ conditions: [
156
+ "react-server"
157
+ ]
158
+ },
159
+ appType: "custom",
160
+ server: {
161
+ middlewareMode: true,
162
+ hmr: {
163
+ server: dummyServer
164
+ }
165
+ }
166
+ });
167
+ lastViteServer = [
168
+ viteServer,
169
+ command
170
+ ];
171
+ return viteServer;
172
+ };
151
173
  const shutdown = async ()=>{
152
- const vite = await vitePromise;
153
- await vite.close();
174
+ if (lastViteServer) {
175
+ await lastViteServer[0].close();
176
+ lastViteServer = undefined;
177
+ }
154
178
  _nodeworker_threads.parentPort.close();
155
179
  };
156
- const loadServerFile = async (fname)=>{
157
- const vite = await vitePromise;
180
+ const loadServerFile = async (fname, command)=>{
181
+ const vite = await getViteServer(command);
158
182
  return vite.ssrLoadModule(fname);
159
183
  };
160
184
  _nodeworker_threads.parentPort.on("message", (mesg)=>{
@@ -172,20 +196,24 @@ const getEntriesFile = async (config, command)=>{
172
196
  return _nodepath.default.join(config.root, command === "dev" ? config.framework.srcDir : config.framework.distDir, config.framework.entriesJs);
173
197
  };
174
198
  const resolveClientEntry = (filePath, config, command)=>{
175
- const root = _nodepath.default.join(config.root, command === "dev" ? config.framework.srcDir : config.framework.distDir);
199
+ let root = _nodepath.default.join(config.root, command === "dev" ? config.framework.srcDir : config.framework.distDir);
200
+ if (_nodepath.default.sep !== "/") {
201
+ // HACK to support windows filesystem
202
+ root = root.replaceAll(_nodepath.default.sep, "/");
203
+ }
176
204
  if (command === "dev" && !filePath.startsWith(root)) {
177
205
  // HACK this relies on Vite's internal implementation detail.
178
- return config.base + "@fs" + filePath;
206
+ return config.base + "@fs/" + filePath.replace(/^\//, "");
179
207
  }
180
208
  return config.base + _nodepath.default.relative(root, filePath);
181
209
  };
182
210
  async function renderRSC(input, options) {
183
211
  const config = await (0, _config.resolveConfig)(options.command === "build" ? "build" : "serve");
184
- const { unstable_setRootDir } = await loadServerFile("waku/config");
212
+ const { unstable_setRootDir } = await loadServerFile("waku/config", options.command);
185
213
  unstable_setRootDir(config.root);
186
214
  const getFunctionComponent = async (rscId)=>{
187
215
  const entriesFile = await getEntriesFile(config, options.command);
188
- const { default: { getEntry } } = await loadServerFile(entriesFile);
216
+ const { default: { getEntry } } = await loadServerFile(entriesFile, options.command);
189
217
  const mod = await getEntry(rscId);
190
218
  if (typeof mod === "function") {
191
219
  return mod;
@@ -215,7 +243,7 @@ async function renderRSC(input, options) {
215
243
  if ("rsfId" in input) {
216
244
  const [fileId, name] = input.rsfId.split("#");
217
245
  const fname = _nodepath.default.join(config.root, fileId);
218
- const mod = await loadServerFile(fname);
246
+ const mod = await loadServerFile(fname, options.command);
219
247
  const data = await (mod[name] || mod)(...input.args);
220
248
  if (!("rscId" in input)) {
221
249
  return renderToPipeableStream(data, bundlerConfig);
@@ -230,10 +258,10 @@ async function renderRSC(input, options) {
230
258
  }
231
259
  async function getBuildConfigRSC() {
232
260
  const config = await (0, _config.resolveConfig)("build");
233
- const { unstable_setRootDir } = await loadServerFile("waku/config");
261
+ const { unstable_setRootDir } = await loadServerFile("waku/config", "build");
234
262
  unstable_setRootDir(config.root);
235
263
  const entriesFile = await getEntriesFile(config, "build");
236
- const { default: { getBuildConfig } } = await loadServerFile(entriesFile);
264
+ const { default: { getBuildConfig } } = await loadServerFile(entriesFile, "build");
237
265
  if (!getBuildConfig) {
238
266
  console.warn("getBuildConfig is undefined. It's recommended for optimization and sometimes required.");
239
267
  return {};
@@ -246,10 +274,10 @@ async function getBuildConfigRSC() {
246
274
  }
247
275
  async function getSsrConfigRSC(pathStr, command) {
248
276
  const config = await (0, _config.resolveConfig)(command === "build" ? "build" : "serve");
249
- const { unstable_setRootDir } = await loadServerFile("waku/config");
277
+ const { unstable_setRootDir } = await loadServerFile("waku/config", command);
250
278
  unstable_setRootDir(config.root);
251
279
  const entriesFile = await getEntriesFile(config, command);
252
- const { default: { getSsrConfig } } = await loadServerFile(entriesFile);
280
+ const { default: { getSsrConfig } } = await loadServerFile(entriesFile, command);
253
281
  if (!getSsrConfig) {
254
282
  return null;
255
283
  }
@@ -60,7 +60,7 @@ const renderHTML = async (pathStr, rscServer, config, ssrConfig)=>{
60
60
  function ssr(options) {
61
61
  const configPromise = (0, _config.resolveConfig)("serve");
62
62
  const vitePromise = (0, _vite.createServer)({
63
- ..._config.configFileConfig,
63
+ ...(0, _config.configFileConfig)(),
64
64
  plugins: [
65
65
  ...options.command === "dev" ? [
66
66
  (0, _nonjsresolveplugin.nonjsResolvePlugin)()
@@ -56,7 +56,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
56
56
  }
57
57
  function rscAnalyzePlugin(clientEntryCallback, serverEntryCallback) {
58
58
  return {
59
- name: "rsc-bundle-plugin",
59
+ name: "rsc-analyze-plugin",
60
60
  transform (code, id) {
61
61
  const ext = _nodepath.default.extname(id);
62
62
  if ([
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "rscDelegatePlugin", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return rscDelegatePlugin;
9
+ }
10
+ });
11
+ const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
12
+ const _core = /*#__PURE__*/ _interop_require_wildcard(require("@swc/core"));
13
+ function _interop_require_default(obj) {
14
+ return obj && obj.__esModule ? obj : {
15
+ default: obj
16
+ };
17
+ }
18
+ function _getRequireWildcardCache(nodeInterop) {
19
+ if (typeof WeakMap !== "function") return null;
20
+ var cacheBabelInterop = new WeakMap();
21
+ var cacheNodeInterop = new WeakMap();
22
+ return (_getRequireWildcardCache = function(nodeInterop) {
23
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
24
+ })(nodeInterop);
25
+ }
26
+ function _interop_require_wildcard(obj, nodeInterop) {
27
+ if (!nodeInterop && obj && obj.__esModule) {
28
+ return obj;
29
+ }
30
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
31
+ return {
32
+ default: obj
33
+ };
34
+ }
35
+ var cache = _getRequireWildcardCache(nodeInterop);
36
+ if (cache && cache.has(obj)) {
37
+ return cache.get(obj);
38
+ }
39
+ var newObj = {};
40
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
41
+ for(var key in obj){
42
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
43
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
44
+ if (desc && (desc.get || desc.set)) {
45
+ Object.defineProperty(newObj, key, desc);
46
+ } else {
47
+ newObj[key] = obj[key];
48
+ }
49
+ }
50
+ }
51
+ newObj.default = obj;
52
+ if (cache) {
53
+ cache.set(obj, newObj);
54
+ }
55
+ return newObj;
56
+ }
57
+ // import { CSS_LANGS_RE } from "vite/dist/node/constants.js";
58
+ const CSS_LANGS_RE = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?)/;
59
+ function rscDelegatePlugin(importCallback) {
60
+ let mode = "development";
61
+ let base = "/";
62
+ return {
63
+ name: "rsc-delegate-plugin",
64
+ configResolved (config) {
65
+ mode = config.mode;
66
+ base = config.base;
67
+ },
68
+ transform (code, id) {
69
+ const ext = _nodepath.default.extname(id);
70
+ if (mode === "development" && [
71
+ ".ts",
72
+ ".tsx",
73
+ ".js",
74
+ ".jsx"
75
+ ].includes(ext)) {
76
+ const mod = _core.parseSync(code, {
77
+ syntax: ext === ".ts" || ext === ".tsx" ? "typescript" : "ecmascript",
78
+ tsx: ext === ".tsx"
79
+ });
80
+ for (const item of mod.body){
81
+ if (item.type === "ImportDeclaration") {
82
+ if (item.source.value.startsWith("virtual:")) {
83
+ // HACK this relies on Vite's internal implementation detail.
84
+ const source = base + "@id/__x00__" + item.source.value;
85
+ importCallback(source);
86
+ } else if (CSS_LANGS_RE.test(item.source.value)) {
87
+ const filePath = _nodepath.default.join(_nodepath.default.dirname(id), item.source.value);
88
+ // HACK this relies on Vite's internal implementation detail.
89
+ const source = base + "@fs/" + filePath.replace(/^\//, "");
90
+ importCallback(source);
91
+ }
92
+ }
93
+ }
94
+ }
95
+ return code;
96
+ }
97
+ };
98
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ rscHmrPlugin: function() {
13
+ return rscHmrPlugin;
14
+ },
15
+ hotImport: function() {
16
+ return hotImport;
17
+ }
18
+ });
19
+ const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
20
+ function _interop_require_default(obj) {
21
+ return obj && obj.__esModule ? obj : {
22
+ default: obj
23
+ };
24
+ }
25
+ const customCode = `
26
+ if (import.meta.hot && !globalThis.__WAKU_HMR_CONFIGURED__) {
27
+ globalThis.__WAKU_HMR_CONFIGURED__ = true;
28
+ import.meta.hot.on('hot-import', (data) => import(/* @vite-ignore */ data));
29
+ }
30
+ `;
31
+ function rscHmrPlugin() {
32
+ return {
33
+ name: "rsc-hmr-plugin",
34
+ async transform (code, id) {
35
+ const ext = _nodepath.default.extname(id);
36
+ if ([
37
+ ".ts",
38
+ ".tsx",
39
+ ".js",
40
+ ".jsx"
41
+ ].includes(ext)) {
42
+ return code + customCode;
43
+ }
44
+ return code;
45
+ }
46
+ };
47
+ }
48
+ const pendingMap = new WeakMap();
49
+ function hotImport(vite, source) {
50
+ let sourceSet = pendingMap.get(vite);
51
+ if (!sourceSet) {
52
+ sourceSet = new Set();
53
+ pendingMap.set(vite, sourceSet);
54
+ vite.ws.on("connection", ()=>{
55
+ for (const source of sourceSet){
56
+ vite.ws.send({
57
+ type: "custom",
58
+ event: "hot-import",
59
+ data: source
60
+ });
61
+ }
62
+ });
63
+ }
64
+ sourceSet.add(source);
65
+ vite.ws.send({
66
+ type: "custom",
67
+ event: "hot-import",
68
+ data: source
69
+ });
70
+ }
@@ -9,16 +9,27 @@ Object.defineProperty(exports, "rscIndexPlugin", {
9
9
  }
10
10
  });
11
11
  const _utils = require("../middleware/rsc/utils.js");
12
- function rscIndexPlugin() {
12
+ function rscIndexPlugin(cssAssets) {
13
13
  return {
14
14
  name: "rsc-index-plugin",
15
15
  async transformIndexHtml () {
16
16
  return [
17
17
  {
18
18
  tag: "script",
19
+ attrs: {
20
+ type: "module"
21
+ },
19
22
  children: _utils.codeToInject,
20
23
  injectTo: "head"
21
- }
24
+ },
25
+ ...cssAssets.map((href)=>({
26
+ tag: "link",
27
+ attrs: {
28
+ rel: "stylesheet",
29
+ href
30
+ },
31
+ injectTo: "head"
32
+ }))
22
33
  ];
23
34
  }
24
35
  };
@@ -77,7 +77,7 @@ function rscReloadPlugin(fn) {
77
77
  return false;
78
78
  };
79
79
  return {
80
- name: "reload-plugin",
80
+ name: "rsc-reload-plugin",
81
81
  configResolved (config) {
82
82
  if (config.mode === "development") {
83
83
  enabled = true;