waku 0.18.0 → 0.18.1
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 +33 -2
- package/dist/cjs/cli.js +24 -13
- package/dist/cjs/dev.js +2 -2
- package/dist/cjs/lib/{builder.js → builder/build.js} +26 -103
- package/dist/cjs/lib/builder/output-cloudflare.js +47 -0
- package/dist/cjs/lib/builder/output-deno.js +38 -0
- package/dist/cjs/lib/builder/output-vercel.js +89 -0
- package/dist/cjs/lib/plugins/vite-plugin-rsc-delegate.js +12 -6
- package/dist/cjs/lib/plugins/vite-plugin-rsc-hmr.js +41 -17
- package/dist/cjs/lib/rsc/handler-dev.js +4 -1
- package/dist/cjs/lib/rsc/html-renderer.js +24 -23
- package/dist/cjs/lib/rsc/utils.js +4 -2
- package/dist/cjs/lib/rsc/worker-api.js +24 -4
- package/dist/cjs/lib/rsc/worker-impl.js +14 -9
- package/dist/cjs/lib/utils/merge-vite-config.js +25 -0
- package/dist/cjs/router/common.js +3 -1
- package/dist/cli.js +24 -13
- package/dist/dev.d.ts +1 -1
- package/dist/dev.js +1 -1
- package/dist/lib/builder/build.d.ts +8 -0
- package/dist/lib/{builder.js → builder/build.js} +31 -108
- package/dist/lib/builder/output-cloudflare.d.ts +2 -0
- package/dist/lib/builder/output-cloudflare.js +33 -0
- package/dist/lib/builder/output-deno.d.ts +2 -0
- package/dist/lib/builder/output-deno.js +24 -0
- package/dist/lib/builder/output-vercel.d.ts +2 -0
- package/dist/lib/builder/output-vercel.js +75 -0
- package/dist/lib/plugins/vite-plugin-rsc-delegate.d.ts +2 -2
- package/dist/lib/plugins/vite-plugin-rsc-delegate.js +12 -6
- package/dist/lib/plugins/vite-plugin-rsc-hmr.d.ts +2 -1
- package/dist/lib/plugins/vite-plugin-rsc-hmr.js +38 -12
- package/dist/lib/rsc/handler-dev.js +7 -4
- package/dist/lib/rsc/html-renderer.js +24 -23
- package/dist/lib/rsc/utils.js +4 -2
- package/dist/lib/rsc/worker-api.d.ts +5 -0
- package/dist/lib/rsc/worker-api.js +21 -4
- package/dist/lib/rsc/worker-impl.js +15 -10
- package/dist/lib/utils/merge-vite-config.d.ts +2 -0
- package/dist/lib/utils/merge-vite-config.js +16 -0
- package/dist/router/common.js +3 -1
- package/package.json +8 -8
- package/src/cli.ts +32 -10
- package/src/dev.ts +1 -1
- package/src/lib/{builder.ts → builder/build.ts} +47 -141
- package/src/lib/builder/output-cloudflare.ts +54 -0
- package/src/lib/builder/output-deno.ts +42 -0
- package/src/lib/builder/output-vercel.ts +99 -0
- package/src/lib/plugins/vite-plugin-rsc-delegate.ts +18 -9
- package/src/lib/plugins/vite-plugin-rsc-hmr.ts +39 -8
- package/src/lib/rsc/handler-dev.ts +11 -4
- package/src/lib/rsc/html-renderer.ts +31 -28
- package/src/lib/rsc/utils.ts +5 -3
- package/src/lib/rsc/worker-api.ts +28 -6
- package/src/lib/rsc/worker-impl.ts +16 -11
- package/src/lib/utils/merge-vite-config.ts +29 -0
- package/src/router/common.ts +3 -1
- package/dist/lib/builder.d.ts +0 -5
package/README.md
CHANGED
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
<!-- [](https://bundlephobia.com/result?p=waku) -->
|
|
10
10
|
|
|
11
|
+
Waku means "frame" in Japanese. Waku-Waku means being excited.
|
|
12
|
+
https://github.com/dai-shi/waku/discussions/260
|
|
13
|
+
|
|
11
14
|
## Project status
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
Roadmap: See https://github.com/dai-shi/waku/issues/24 (working towards v1-alpha)
|
|
14
17
|
|
|
15
18
|
Feel free to try it _seriously_ with non-production projects and give us feedback.
|
|
16
19
|
|
|
@@ -73,7 +76,7 @@ pnpm create waku
|
|
|
73
76
|
These commands will create an example app that you can use as a
|
|
74
77
|
starting point for your project.
|
|
75
78
|
|
|
76
|
-
Minimum requirement: Node.js 18
|
|
79
|
+
Minimum requirement: Node.js 18.3.0
|
|
77
80
|
|
|
78
81
|
## Practices
|
|
79
82
|
|
|
@@ -290,6 +293,34 @@ Alternatively, you could create a project with something like
|
|
|
290
293
|
`npm create waku@latest` and copy files from the example
|
|
291
294
|
folder in the repository.
|
|
292
295
|
|
|
296
|
+
## Deploy
|
|
297
|
+
|
|
298
|
+
### Vercel
|
|
299
|
+
|
|
300
|
+
```sh
|
|
301
|
+
vercel
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Then change the setting as follows (needs redeploy for the first time):
|
|
305
|
+
|
|
306
|
+

|
|
307
|
+
|
|
308
|
+
### Cloudflare (experimental)
|
|
309
|
+
|
|
310
|
+
```sh
|
|
311
|
+
npm run build -- --with-cloudflare
|
|
312
|
+
rm -r node_modules
|
|
313
|
+
npm install --omit=dev --omit=peer
|
|
314
|
+
npx wrangler dev # or deploy
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Deno Deploy (experimental)
|
|
318
|
+
|
|
319
|
+
```sh
|
|
320
|
+
npm run build -- --with-deno
|
|
321
|
+
DENO_DEPLOY_TOKEN=... deployctl deploy --project=... --prod serve.ts --exclude node_modules
|
|
322
|
+
```
|
|
323
|
+
|
|
293
324
|
## Tweets
|
|
294
325
|
|
|
295
326
|
<https://github.com/dai-shi/waku/discussions/150>
|
package/dist/cjs/cli.js
CHANGED
|
@@ -13,7 +13,7 @@ const _servestatic = require("@hono/node-server/serve-static");
|
|
|
13
13
|
const _config = require("./lib/config.js");
|
|
14
14
|
const _honodev = require("./lib/middleware/hono-dev.js");
|
|
15
15
|
const _honoprd = require("./lib/middleware/hono-prd.js");
|
|
16
|
-
const
|
|
16
|
+
const _build = require("./lib/builder/build.js");
|
|
17
17
|
function _interop_require_default(obj) {
|
|
18
18
|
return obj && obj.__esModule ? obj : {
|
|
19
19
|
default: obj
|
|
@@ -68,6 +68,15 @@ const { values, positionals } = (0, _nodeutil.parseArgs)({
|
|
|
68
68
|
'with-ssr': {
|
|
69
69
|
type: 'boolean'
|
|
70
70
|
},
|
|
71
|
+
'with-vercel': {
|
|
72
|
+
type: 'boolean'
|
|
73
|
+
},
|
|
74
|
+
'with-cloudflare': {
|
|
75
|
+
type: 'boolean'
|
|
76
|
+
},
|
|
77
|
+
'with-deno': {
|
|
78
|
+
type: 'boolean'
|
|
79
|
+
},
|
|
71
80
|
version: {
|
|
72
81
|
type: 'boolean',
|
|
73
82
|
short: 'v'
|
|
@@ -85,20 +94,24 @@ if (values.version) {
|
|
|
85
94
|
} else if (values.help) {
|
|
86
95
|
displayUsage();
|
|
87
96
|
} else {
|
|
97
|
+
const withSsr = !!values['with-ssr'];
|
|
88
98
|
switch(cmd){
|
|
89
99
|
case 'dev':
|
|
90
100
|
runDev({
|
|
91
|
-
ssr:
|
|
101
|
+
ssr: withSsr
|
|
92
102
|
});
|
|
93
103
|
break;
|
|
94
104
|
case 'build':
|
|
95
105
|
runBuild({
|
|
96
|
-
ssr:
|
|
106
|
+
ssr: withSsr,
|
|
107
|
+
vercel: values['with-vercel'],
|
|
108
|
+
cloudflare: !!values['with-cloudflare'],
|
|
109
|
+
deno: !!values['with-deno']
|
|
97
110
|
});
|
|
98
111
|
break;
|
|
99
112
|
case 'start':
|
|
100
113
|
runStart({
|
|
101
|
-
ssr:
|
|
114
|
+
ssr: withSsr
|
|
102
115
|
});
|
|
103
116
|
break;
|
|
104
117
|
default:
|
|
@@ -111,16 +124,12 @@ if (values.version) {
|
|
|
111
124
|
}
|
|
112
125
|
async function runDev(options) {
|
|
113
126
|
const app = new _hono.Hono();
|
|
114
|
-
app.use('*', (0, _honodev.honoMiddleware)(
|
|
115
|
-
ssr: options.ssr
|
|
116
|
-
}));
|
|
127
|
+
app.use('*', (0, _honodev.honoMiddleware)(options));
|
|
117
128
|
const port = parseInt(process.env.PORT || '3000', 10);
|
|
118
129
|
startServer(app, port);
|
|
119
130
|
}
|
|
120
131
|
async function runBuild(options) {
|
|
121
|
-
await (0,
|
|
122
|
-
ssr: options.ssr
|
|
123
|
-
});
|
|
132
|
+
await (0, _build.build)(options);
|
|
124
133
|
}
|
|
125
134
|
async function runStart(options) {
|
|
126
135
|
const { distDir, publicDir, entriesJs } = await (0, _config.resolveConfig)({});
|
|
@@ -128,7 +137,7 @@ async function runStart(options) {
|
|
|
128
137
|
const app = new _hono.Hono();
|
|
129
138
|
app.use('*', (0, _honoprd.honoMiddleware)({
|
|
130
139
|
entries,
|
|
131
|
-
|
|
140
|
+
...options
|
|
132
141
|
}));
|
|
133
142
|
app.use('*', (0, _servestatic.serveStatic)({
|
|
134
143
|
root: _nodepath.default.join(distDir, publicDir)
|
|
@@ -148,7 +157,7 @@ async function startServer(app, port) {
|
|
|
148
157
|
console.log(`warn: Port ${port} is in use, trying ${port + 1} instead.`);
|
|
149
158
|
startServer(app, port + 1);
|
|
150
159
|
} else {
|
|
151
|
-
console.error(
|
|
160
|
+
console.error(`Failed to start server: ${err.message}`);
|
|
152
161
|
}
|
|
153
162
|
});
|
|
154
163
|
}
|
|
@@ -162,8 +171,10 @@ Commands:
|
|
|
162
171
|
start Start the production server
|
|
163
172
|
|
|
164
173
|
Options:
|
|
165
|
-
-c, --config <path> Path to the configuration file
|
|
166
174
|
--with-ssr Use opt-in SSR
|
|
175
|
+
--with-vercel Output for Vercel on build
|
|
176
|
+
--with-cloudflare Output for Cloudflare on build
|
|
177
|
+
--with-deno Output for Deno on build
|
|
167
178
|
-v, --version Display the version number
|
|
168
179
|
-h, --help Display this help message
|
|
169
180
|
`);
|
package/dist/cjs/dev.js
CHANGED
|
@@ -10,7 +10,7 @@ function _export(target, all) {
|
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
12
|
build: function() {
|
|
13
|
-
return
|
|
13
|
+
return _build.build;
|
|
14
14
|
},
|
|
15
15
|
connectMiddleware: function() {
|
|
16
16
|
return _connectdev.connectMiddleware;
|
|
@@ -25,4 +25,4 @@ _export(exports, {
|
|
|
25
25
|
const _honodev = require("./lib/middleware/hono-dev.js");
|
|
26
26
|
const _connectdev = require("./lib/middleware/connect-dev.js");
|
|
27
27
|
const _handlerdev = require("./lib/rsc/handler-dev.js");
|
|
28
|
-
const
|
|
28
|
+
const _build = require("./lib/builder/build.js");
|
|
@@ -13,18 +13,21 @@ const _nodestream = require("node:stream");
|
|
|
13
13
|
const _promises = require("node:stream/promises");
|
|
14
14
|
const _vite = require("vite");
|
|
15
15
|
const _pluginreact = /*#__PURE__*/ _interop_require_default(require("@vitejs/plugin-react"));
|
|
16
|
-
const _config = require("
|
|
17
|
-
const _path = require("
|
|
18
|
-
const _nodefs = require("
|
|
19
|
-
const _stream = require("
|
|
20
|
-
const _utils = require("
|
|
21
|
-
const _rscrenderer = require("
|
|
22
|
-
const _htmlrenderer = require("
|
|
23
|
-
const _vitepluginrscindex = require("
|
|
24
|
-
const _vitepluginrscanalyze = require("
|
|
25
|
-
const _vitepluginnonjsresolve = require("
|
|
26
|
-
const _vitepluginrsctransform = require("
|
|
27
|
-
const _patchreactrefresh = require("
|
|
16
|
+
const _config = require("../config.js");
|
|
17
|
+
const _path = require("../utils/path.js");
|
|
18
|
+
const _nodefs = require("../utils/node-fs.js");
|
|
19
|
+
const _stream = require("../utils/stream.js");
|
|
20
|
+
const _utils = require("../rsc/utils.js");
|
|
21
|
+
const _rscrenderer = require("../rsc/rsc-renderer.js");
|
|
22
|
+
const _htmlrenderer = require("../rsc/html-renderer.js");
|
|
23
|
+
const _vitepluginrscindex = require("../plugins/vite-plugin-rsc-index.js");
|
|
24
|
+
const _vitepluginrscanalyze = require("../plugins/vite-plugin-rsc-analyze.js");
|
|
25
|
+
const _vitepluginnonjsresolve = require("../plugins/vite-plugin-nonjs-resolve.js");
|
|
26
|
+
const _vitepluginrsctransform = require("../plugins/vite-plugin-rsc-transform.js");
|
|
27
|
+
const _patchreactrefresh = require("../plugins/patch-react-refresh.js");
|
|
28
|
+
const _outputvercel = require("./output-vercel.js");
|
|
29
|
+
const _outputcloudflare = require("./output-cloudflare.js");
|
|
30
|
+
const _outputdeno = require("./output-deno.js");
|
|
28
31
|
function _interop_require_default(obj) {
|
|
29
32
|
return obj && obj.__esModule ? obj : {
|
|
30
33
|
default: obj
|
|
@@ -368,7 +371,7 @@ export function loadHtml(pathStr) {
|
|
|
368
371
|
const code = (0, _utils.generatePrefetchCode)(basePrefix, inputsForPrefetch, moduleIdsForPrefetch) + (customCode || '');
|
|
369
372
|
if (code) {
|
|
370
373
|
// HACK is this too naive to inject script code?
|
|
371
|
-
htmlStr = htmlStr.replace(/<\/head>/, `<script>${code}</script></head>`);
|
|
374
|
+
htmlStr = htmlStr.replace(/<\/head>/, `<script type="module" async>${code}</script></head>`);
|
|
372
375
|
}
|
|
373
376
|
const htmlResult = ssr && await (0, _htmlrenderer.renderHtml)({
|
|
374
377
|
config,
|
|
@@ -402,93 +405,6 @@ export function loadHtml(pathStr) {
|
|
|
402
405
|
htmlFiles
|
|
403
406
|
};
|
|
404
407
|
};
|
|
405
|
-
const emitVercelOutput = async (rootDir, config, clientBuildOutput, rscFiles, htmlFiles, ssr)=>{
|
|
406
|
-
// FIXME somehow utils/(path,node-fs).ts doesn't work
|
|
407
|
-
const [path, { existsSync, mkdirSync, readdirSync, symlinkSync, writeFileSync }] = await Promise.all([
|
|
408
|
-
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("node:path"))),
|
|
409
|
-
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("node:fs")))
|
|
410
|
-
]);
|
|
411
|
-
const clientFiles = clientBuildOutput.output.map(({ fileName })=>path.join(rootDir, config.distDir, config.publicDir, fileName));
|
|
412
|
-
const srcDir = path.join(rootDir, config.distDir, config.publicDir);
|
|
413
|
-
const dstDir = path.join(rootDir, config.distDir, '.vercel', 'output');
|
|
414
|
-
for (const file of [
|
|
415
|
-
...clientFiles,
|
|
416
|
-
...rscFiles,
|
|
417
|
-
...htmlFiles
|
|
418
|
-
]){
|
|
419
|
-
const dstFile = path.join(dstDir, 'static', path.relative(srcDir, file));
|
|
420
|
-
if (!existsSync(dstFile)) {
|
|
421
|
-
mkdirSync(path.dirname(dstFile), {
|
|
422
|
-
recursive: true
|
|
423
|
-
});
|
|
424
|
-
symlinkSync(path.relative(path.dirname(dstFile), file), dstFile);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
// for serverless function
|
|
428
|
-
const serverlessDir = path.join(dstDir, 'functions', config.rscPath + '.func');
|
|
429
|
-
mkdirSync(path.join(serverlessDir, config.distDir), {
|
|
430
|
-
recursive: true
|
|
431
|
-
});
|
|
432
|
-
mkdirSync(path.join(serverlessDir, 'node_modules'));
|
|
433
|
-
symlinkSync(path.relative(path.join(serverlessDir, 'node_modules'), path.join(rootDir, 'node_modules', 'waku')), path.join(serverlessDir, 'node_modules', 'waku'));
|
|
434
|
-
for (const file of readdirSync(path.join(rootDir, config.distDir))){
|
|
435
|
-
if ([
|
|
436
|
-
'.vercel'
|
|
437
|
-
].includes(file)) {
|
|
438
|
-
continue;
|
|
439
|
-
}
|
|
440
|
-
symlinkSync(path.relative(path.join(serverlessDir, config.distDir), path.join(rootDir, config.distDir, file)), path.join(serverlessDir, config.distDir, file));
|
|
441
|
-
}
|
|
442
|
-
const vcConfigJson = {
|
|
443
|
-
runtime: 'nodejs18.x',
|
|
444
|
-
handler: 'serve.js',
|
|
445
|
-
launcherType: 'Nodejs'
|
|
446
|
-
};
|
|
447
|
-
writeFileSync(path.join(serverlessDir, '.vc-config.json'), JSON.stringify(vcConfigJson, null, 2));
|
|
448
|
-
writeFileSync(path.join(serverlessDir, 'package.json'), JSON.stringify({
|
|
449
|
-
type: 'module'
|
|
450
|
-
}, null, 2));
|
|
451
|
-
writeFileSync(path.join(serverlessDir, 'serve.js'), `
|
|
452
|
-
import path from 'node:path';
|
|
453
|
-
import { connectMiddleware } from 'waku';
|
|
454
|
-
const entries = import(path.resolve('${config.distDir}', '${config.entriesJs}'));
|
|
455
|
-
export default async function handler(req, res) {
|
|
456
|
-
connectMiddleware({ entries, ssr: true })(req, res, () => {
|
|
457
|
-
throw new Error('not handled');
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
`);
|
|
461
|
-
const overrides = Object.fromEntries(rscFiles.filter((file)=>!path.extname(file)).map((file)=>[
|
|
462
|
-
path.relative(srcDir, file),
|
|
463
|
-
{
|
|
464
|
-
contentType: 'text/plain'
|
|
465
|
-
}
|
|
466
|
-
]));
|
|
467
|
-
const basePrefix = config.basePath + config.rscPath + '/';
|
|
468
|
-
const routes = [
|
|
469
|
-
{
|
|
470
|
-
src: basePrefix + '(.*)',
|
|
471
|
-
dest: basePrefix
|
|
472
|
-
},
|
|
473
|
-
...ssr ? htmlFiles.map((htmlFile)=>{
|
|
474
|
-
const file = config.basePath + path.relative(srcDir, htmlFile);
|
|
475
|
-
const src = file.endsWith('/' + config.indexHtml) ? file.slice(0, -('/' + config.indexHtml).length) || '/' : file;
|
|
476
|
-
return {
|
|
477
|
-
src,
|
|
478
|
-
dest: basePrefix
|
|
479
|
-
};
|
|
480
|
-
}) : []
|
|
481
|
-
];
|
|
482
|
-
const configJson = {
|
|
483
|
-
version: 3,
|
|
484
|
-
overrides,
|
|
485
|
-
routes
|
|
486
|
-
};
|
|
487
|
-
mkdirSync(dstDir, {
|
|
488
|
-
recursive: true
|
|
489
|
-
});
|
|
490
|
-
writeFileSync(path.join(dstDir, 'config.json'), JSON.stringify(configJson, null, 2));
|
|
491
|
-
};
|
|
492
408
|
const resolveFileName = (fname)=>{
|
|
493
409
|
for (const ext of [
|
|
494
410
|
'.js',
|
|
@@ -510,9 +426,16 @@ async function build(options) {
|
|
|
510
426
|
const distEntriesFile = resolveFileName((0, _path.joinPath)(rootDir, config.distDir, config.entriesJs));
|
|
511
427
|
const { commonEntryFiles, clientEntryFiles, serverEntryFiles } = await analyzeEntries(entriesFile);
|
|
512
428
|
const serverBuildOutput = await buildServerBundle(rootDir, config, entriesFile, distEntriesFile, commonEntryFiles, clientEntryFiles, serverEntryFiles);
|
|
513
|
-
|
|
429
|
+
await buildClientBundle(rootDir, config, commonEntryFiles, clientEntryFiles, serverBuildOutput);
|
|
514
430
|
const { buildConfig, getClientModules, rscFiles } = await emitRscFiles(rootDir, config, distEntriesFile);
|
|
515
431
|
const { htmlFiles } = await emitHtmlFiles(rootDir, config, distEntriesFile, buildConfig, getClientModules, !!options?.ssr);
|
|
516
|
-
|
|
517
|
-
|
|
432
|
+
if (options?.vercel ?? process.env.VERCEL) {
|
|
433
|
+
await (0, _outputvercel.emitVercelOutput)(rootDir, config, rscFiles, htmlFiles, !!options?.ssr);
|
|
434
|
+
}
|
|
435
|
+
if (options?.cloudflare) {
|
|
436
|
+
await (0, _outputcloudflare.emitCloudflareOutput)(rootDir, config, !!options?.ssr);
|
|
437
|
+
}
|
|
438
|
+
if (options?.deno) {
|
|
439
|
+
await (0, _outputdeno.emitDenoOutput)(rootDir, config, !!options?.ssr);
|
|
440
|
+
}
|
|
518
441
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "emitCloudflareOutput", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return emitCloudflareOutput;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
12
|
+
const _nodefs = require("node:fs");
|
|
13
|
+
function _interop_require_default(obj) {
|
|
14
|
+
return obj && obj.__esModule ? obj : {
|
|
15
|
+
default: obj
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const emitCloudflareOutput = async (rootDir, config, ssr)=>{
|
|
19
|
+
const outputDir = _nodepath.default.resolve('.');
|
|
20
|
+
const relativeRootDir = _nodepath.default.relative(outputDir, rootDir);
|
|
21
|
+
const entriesFile = _nodepath.default.join(relativeRootDir, config.distDir, config.entriesJs);
|
|
22
|
+
const publicDir = _nodepath.default.join(relativeRootDir, config.distDir, config.publicDir);
|
|
23
|
+
if (!(0, _nodefs.existsSync)(_nodepath.default.join(outputDir, 'serve.js'))) {
|
|
24
|
+
(0, _nodefs.writeFileSync)(_nodepath.default.join(outputDir, 'serve.js'), `
|
|
25
|
+
import { honoMiddleware } from 'waku';
|
|
26
|
+
import { Hono } from 'hono';
|
|
27
|
+
import { serveStatic } from 'hono/cloudflare-workers';
|
|
28
|
+
|
|
29
|
+
const entries = import('./${entriesFile}');
|
|
30
|
+
|
|
31
|
+
const app = new Hono();
|
|
32
|
+
app.use('*', honoMiddleware({ entries, ssr: ${ssr} }));
|
|
33
|
+
app.use('*', serveStatic({ root: './' }));
|
|
34
|
+
export default app;
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
if (!(0, _nodefs.existsSync)(_nodepath.default.join(outputDir, 'wrangler.toml'))) {
|
|
38
|
+
(0, _nodefs.writeFileSync)(_nodepath.default.join(outputDir, 'wrangler.toml'), `
|
|
39
|
+
name = "waku-project"
|
|
40
|
+
main = "serve.js"
|
|
41
|
+
compatibility_date = "2023-12-06"
|
|
42
|
+
|
|
43
|
+
[site]
|
|
44
|
+
bucket = "./${publicDir}"
|
|
45
|
+
`);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "emitDenoOutput", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return emitDenoOutput;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
12
|
+
const _nodefs = require("node:fs");
|
|
13
|
+
function _interop_require_default(obj) {
|
|
14
|
+
return obj && obj.__esModule ? obj : {
|
|
15
|
+
default: obj
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const emitDenoOutput = async (rootDir, config, ssr)=>{
|
|
19
|
+
const outputDir = _nodepath.default.resolve('.');
|
|
20
|
+
const relativeRootDir = _nodepath.default.relative(outputDir, rootDir);
|
|
21
|
+
const entriesFile = _nodepath.default.join(relativeRootDir, config.distDir, config.entriesJs);
|
|
22
|
+
const publicDir = _nodepath.default.join(relativeRootDir, config.distDir, config.publicDir);
|
|
23
|
+
if (!(0, _nodefs.existsSync)(_nodepath.default.join(outputDir, 'serve.ts'))) {
|
|
24
|
+
(0, _nodefs.writeFileSync)(_nodepath.default.join(outputDir, 'serve.ts'), `
|
|
25
|
+
import { Hono } from "https://deno.land/x/hono/mod.ts";
|
|
26
|
+
import { serveStatic } from "https://deno.land/x/hono/middleware.ts";
|
|
27
|
+
import { honoMiddleware } from "npm:waku@0.18.1";
|
|
28
|
+
|
|
29
|
+
const entries = import('./${entriesFile}');
|
|
30
|
+
|
|
31
|
+
const app = new Hono();
|
|
32
|
+
app.use('*', honoMiddleware({ entries, ssr: ${ssr} }));
|
|
33
|
+
app.use("*", serveStatic({ root: "${publicDir}" }));
|
|
34
|
+
|
|
35
|
+
Deno.serve(app.fetch);
|
|
36
|
+
`);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "emitVercelOutput", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return emitVercelOutput;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
12
|
+
const _nodefs = require("node:fs");
|
|
13
|
+
function _interop_require_default(obj) {
|
|
14
|
+
return obj && obj.__esModule ? obj : {
|
|
15
|
+
default: obj
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const emitVercelOutput = async (rootDir, config, rscFiles, htmlFiles, ssr)=>{
|
|
19
|
+
const publicDir = _nodepath.default.join(rootDir, config.distDir, config.publicDir);
|
|
20
|
+
const outputDir = _nodepath.default.resolve('.vercel', 'output');
|
|
21
|
+
(0, _nodefs.cpSync)(_nodepath.default.join(rootDir, config.distDir, config.publicDir), _nodepath.default.join(outputDir, 'static'), {
|
|
22
|
+
recursive: true
|
|
23
|
+
});
|
|
24
|
+
// for serverless function
|
|
25
|
+
const serverlessDir = _nodepath.default.join(outputDir, 'functions', config.rscPath + '.func');
|
|
26
|
+
(0, _nodefs.mkdirSync)(_nodepath.default.join(serverlessDir, config.distDir), {
|
|
27
|
+
recursive: true
|
|
28
|
+
});
|
|
29
|
+
(0, _nodefs.mkdirSync)(_nodepath.default.join(serverlessDir, 'node_modules'), {
|
|
30
|
+
recursive: true
|
|
31
|
+
});
|
|
32
|
+
(0, _nodefs.cpSync)(_nodepath.default.join(rootDir, 'node_modules', 'waku'), _nodepath.default.join(serverlessDir, 'node_modules', 'waku'), {
|
|
33
|
+
dereference: true,
|
|
34
|
+
recursive: true
|
|
35
|
+
});
|
|
36
|
+
(0, _nodefs.cpSync)(_nodepath.default.join(rootDir, config.distDir), _nodepath.default.join(serverlessDir, config.distDir), {
|
|
37
|
+
recursive: true
|
|
38
|
+
});
|
|
39
|
+
const vcConfigJson = {
|
|
40
|
+
runtime: 'nodejs18.x',
|
|
41
|
+
handler: 'serve.js',
|
|
42
|
+
launcherType: 'Nodejs'
|
|
43
|
+
};
|
|
44
|
+
(0, _nodefs.writeFileSync)(_nodepath.default.join(serverlessDir, '.vc-config.json'), JSON.stringify(vcConfigJson, null, 2));
|
|
45
|
+
(0, _nodefs.writeFileSync)(_nodepath.default.join(serverlessDir, 'package.json'), JSON.stringify({
|
|
46
|
+
type: 'module'
|
|
47
|
+
}, null, 2));
|
|
48
|
+
(0, _nodefs.writeFileSync)(_nodepath.default.join(serverlessDir, 'serve.js'), `
|
|
49
|
+
import path from 'node:path';
|
|
50
|
+
import { connectMiddleware } from 'waku';
|
|
51
|
+
const entries = import(path.resolve('${config.distDir}', '${config.entriesJs}'));
|
|
52
|
+
export default async function handler(req, res) {
|
|
53
|
+
connectMiddleware({ entries, ssr: ${ssr} })(req, res, () => {
|
|
54
|
+
res.statusCode = 404;
|
|
55
|
+
res.end();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
`);
|
|
59
|
+
const overrides = Object.fromEntries(rscFiles.filter((file)=>!_nodepath.default.extname(file)).map((file)=>[
|
|
60
|
+
_nodepath.default.relative(publicDir, file),
|
|
61
|
+
{
|
|
62
|
+
contentType: 'text/plain'
|
|
63
|
+
}
|
|
64
|
+
]));
|
|
65
|
+
const basePrefix = config.basePath + config.rscPath + '/';
|
|
66
|
+
const routes = [
|
|
67
|
+
{
|
|
68
|
+
src: basePrefix + '(.*)',
|
|
69
|
+
dest: basePrefix
|
|
70
|
+
},
|
|
71
|
+
...ssr ? htmlFiles.map((htmlFile)=>{
|
|
72
|
+
const file = config.basePath + _nodepath.default.relative(publicDir, htmlFile);
|
|
73
|
+
const src = file.endsWith('/' + config.indexHtml) ? file.slice(0, -('/' + config.indexHtml).length) || '/' : file;
|
|
74
|
+
return {
|
|
75
|
+
src,
|
|
76
|
+
dest: basePrefix
|
|
77
|
+
};
|
|
78
|
+
}) : []
|
|
79
|
+
];
|
|
80
|
+
const configJson = {
|
|
81
|
+
version: 3,
|
|
82
|
+
overrides,
|
|
83
|
+
routes
|
|
84
|
+
};
|
|
85
|
+
(0, _nodefs.mkdirSync)(outputDir, {
|
|
86
|
+
recursive: true
|
|
87
|
+
});
|
|
88
|
+
(0, _nodefs.writeFileSync)(_nodepath.default.join(outputDir, 'config.json'), JSON.stringify(configJson, null, 2));
|
|
89
|
+
};
|
|
@@ -10,7 +10,6 @@ Object.defineProperty(exports, "rscDelegatePlugin", {
|
|
|
10
10
|
});
|
|
11
11
|
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
12
12
|
const _core = /*#__PURE__*/ _interop_require_wildcard(require("@swc/core"));
|
|
13
|
-
const _path = require("../utils/path.js");
|
|
14
13
|
function _interop_require_default(obj) {
|
|
15
14
|
return obj && obj.__esModule ? obj : {
|
|
16
15
|
default: obj
|
|
@@ -62,13 +61,17 @@ const CSS_LANGS_RE = /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:$|\?
|
|
|
62
61
|
function rscDelegatePlugin(importCallback) {
|
|
63
62
|
let mode = 'development';
|
|
64
63
|
let base = '/';
|
|
64
|
+
let server;
|
|
65
65
|
return {
|
|
66
66
|
name: 'rsc-delegate-plugin',
|
|
67
67
|
configResolved (config) {
|
|
68
68
|
mode = config.mode;
|
|
69
69
|
base = config.base;
|
|
70
70
|
},
|
|
71
|
-
|
|
71
|
+
configureServer (serverInstance) {
|
|
72
|
+
server = serverInstance;
|
|
73
|
+
},
|
|
74
|
+
async transform (code, id) {
|
|
72
75
|
const ext = _nodepath.default.extname(id);
|
|
73
76
|
if (mode === 'development' && [
|
|
74
77
|
'.ts',
|
|
@@ -87,10 +90,13 @@ function rscDelegatePlugin(importCallback) {
|
|
|
87
90
|
const source = base + '@id/__x00__' + item.source.value;
|
|
88
91
|
importCallback(source);
|
|
89
92
|
} else if (CSS_LANGS_RE.test(item.source.value)) {
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
const resolvedSource = await server.pluginContainer.resolveId(item.source.value, id, {
|
|
94
|
+
ssr: true
|
|
95
|
+
});
|
|
96
|
+
if (resolvedSource?.id) {
|
|
97
|
+
const transformedResult = await server.transformRequest(resolvedSource.id);
|
|
98
|
+
transformedResult && importCallback(transformedResult);
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
101
|
}
|
|
96
102
|
}
|
|
@@ -12,36 +12,37 @@ _export(exports, {
|
|
|
12
12
|
hotImport: function() {
|
|
13
13
|
return hotImport;
|
|
14
14
|
},
|
|
15
|
+
moduleImport: function() {
|
|
16
|
+
return moduleImport;
|
|
17
|
+
},
|
|
15
18
|
rscHmrPlugin: function() {
|
|
16
19
|
return rscHmrPlugin;
|
|
17
20
|
}
|
|
18
21
|
});
|
|
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
22
|
const customCode = `
|
|
23
|
+
import { createHotContext as __vite__createHotContext } from "/@vite/client";
|
|
24
|
+
import.meta.hot = __vite__createHotContext(import.meta.url);
|
|
25
|
+
|
|
26
26
|
if (import.meta.hot && !globalThis.__WAKU_HMR_CONFIGURED__) {
|
|
27
27
|
globalThis.__WAKU_HMR_CONFIGURED__ = true;
|
|
28
|
+
|
|
28
29
|
import.meta.hot.on('hot-import', (data) => import(/* @vite-ignore */ data));
|
|
30
|
+
|
|
31
|
+
import.meta.hot.on('module', (data) => {
|
|
32
|
+
const code = data.code;
|
|
33
|
+
const script = document.createElement('script');
|
|
34
|
+
script.type = 'module';
|
|
35
|
+
script.text = code;
|
|
36
|
+
document.head.appendChild(script);
|
|
37
|
+
});
|
|
29
38
|
}
|
|
30
39
|
`;
|
|
31
40
|
function rscHmrPlugin() {
|
|
32
41
|
return {
|
|
33
42
|
name: 'rsc-hmr-plugin',
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
'.ts',
|
|
38
|
-
'.tsx',
|
|
39
|
-
'.js',
|
|
40
|
-
'.jsx'
|
|
41
|
-
].includes(ext)) {
|
|
42
|
-
return code + customCode;
|
|
43
|
-
}
|
|
44
|
-
return code;
|
|
43
|
+
enforce: 'post',
|
|
44
|
+
transformIndexHtml (html) {
|
|
45
|
+
return html.replace('</body>', `<script type="module" async>${customCode}</script></body>`);
|
|
45
46
|
}
|
|
46
47
|
};
|
|
47
48
|
}
|
|
@@ -68,3 +69,26 @@ function hotImport(vite, source) {
|
|
|
68
69
|
data: source
|
|
69
70
|
});
|
|
70
71
|
}
|
|
72
|
+
const modulePendingMap = new WeakMap();
|
|
73
|
+
function moduleImport(viteServer, result) {
|
|
74
|
+
let sourceSet = modulePendingMap.get(viteServer);
|
|
75
|
+
if (!sourceSet) {
|
|
76
|
+
sourceSet = new Set();
|
|
77
|
+
modulePendingMap.set(viteServer, sourceSet);
|
|
78
|
+
viteServer.ws.on('connection', ()=>{
|
|
79
|
+
for (const result of sourceSet){
|
|
80
|
+
viteServer.ws.send({
|
|
81
|
+
type: 'custom',
|
|
82
|
+
event: 'module',
|
|
83
|
+
data: result
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
sourceSet.add(result);
|
|
89
|
+
viteServer.ws.send({
|
|
90
|
+
type: 'custom',
|
|
91
|
+
event: 'module',
|
|
92
|
+
data: result
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -22,6 +22,7 @@ const _vitepluginnonjsresolve = require("../plugins/vite-plugin-nonjs-resolve.js
|
|
|
22
22
|
const _patchreactrefresh = require("../plugins/patch-react-refresh.js");
|
|
23
23
|
const _vitepluginrscindex = require("../plugins/vite-plugin-rsc-index.js");
|
|
24
24
|
const _vitepluginrschmr = require("../plugins/vite-plugin-rsc-hmr.js");
|
|
25
|
+
const _mergeviteconfig = require("../utils/merge-vite-config.js");
|
|
25
26
|
function _interop_require_default(obj) {
|
|
26
27
|
return obj && obj.__esModule ? obj : {
|
|
27
28
|
default: obj
|
|
@@ -34,7 +35,7 @@ function createHandler(options) {
|
|
|
34
35
|
}
|
|
35
36
|
const configPromise = (0, _config.resolveConfig)(options.config || {});
|
|
36
37
|
const vitePromise = configPromise.then(async (config)=>{
|
|
37
|
-
const
|
|
38
|
+
const mergedViteConfig = await (0, _mergeviteconfig.mergeUserViteConfig)({
|
|
38
39
|
base: config.basePath,
|
|
39
40
|
optimizeDeps: {
|
|
40
41
|
include: [
|
|
@@ -59,10 +60,12 @@ function createHandler(options) {
|
|
|
59
60
|
middlewareMode: true
|
|
60
61
|
}
|
|
61
62
|
});
|
|
63
|
+
const viteServer = await (0, _vite.createServer)(mergedViteConfig);
|
|
62
64
|
(0, _workerapi.registerReloadCallback)((type)=>viteServer.ws.send({
|
|
63
65
|
type
|
|
64
66
|
}));
|
|
65
67
|
(0, _workerapi.registerImportCallback)((source)=>(0, _vitepluginrschmr.hotImport)(viteServer, source));
|
|
68
|
+
(0, _workerapi.registerModuleCallback)((result)=>(0, _vitepluginrschmr.moduleImport)(viteServer, result));
|
|
66
69
|
return viteServer;
|
|
67
70
|
});
|
|
68
71
|
const entries = Promise.all([
|