@blinkk/root 1.0.0-beta.1 → 1.0.0-beta.10
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/bin/root.js +3 -0
- package/dist/{chunk-GGQGZ7ZE.js → chunk-WVRC46JG.js} +18 -18
- package/dist/chunk-WVRC46JG.js.map +1 -0
- package/dist/cli.d.ts +30 -4
- package/dist/cli.js +627 -577
- package/dist/cli.js.map +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/node.d.ts +1 -1
- package/dist/render.d.ts +1 -1
- package/dist/render.js +54 -23
- package/dist/render.js.map +1 -1
- package/dist/{config-872b068d.d.ts → types-8310f09f.d.ts} +141 -131
- package/package.json +1 -1
- package/dist/chunk-GGQGZ7ZE.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
htmlPretty,
|
|
4
4
|
isValidTagName,
|
|
5
5
|
parseTagNames
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WVRC46JG.js";
|
|
7
7
|
import {
|
|
8
8
|
copyGlob,
|
|
9
9
|
createViteServer,
|
|
@@ -22,186 +22,173 @@ import {
|
|
|
22
22
|
getVitePlugins
|
|
23
23
|
} from "./chunk-DTEQ2AIW.js";
|
|
24
24
|
|
|
25
|
-
// src/cli/commands/
|
|
25
|
+
// src/cli/commands/build.ts
|
|
26
26
|
import path3 from "node:path";
|
|
27
27
|
import { fileURLToPath } from "node:url";
|
|
28
|
-
import
|
|
28
|
+
import fsExtra from "fs-extra";
|
|
29
|
+
import glob2 from "tiny-glob";
|
|
30
|
+
import { build as viteBuild } from "vite";
|
|
29
31
|
|
|
30
|
-
// src/render/asset-map/
|
|
32
|
+
// src/render/asset-map/build-asset-map.ts
|
|
33
|
+
import fs from "node:fs";
|
|
31
34
|
import path from "node:path";
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
constructor(rootConfig, moduleGraph) {
|
|
35
|
+
var BuildAssetMap = class {
|
|
36
|
+
constructor(rootConfig) {
|
|
35
37
|
this.rootConfig = rootConfig;
|
|
36
|
-
this.
|
|
38
|
+
this.srcToAsset = /* @__PURE__ */ new Map();
|
|
37
39
|
}
|
|
38
40
|
async get(src) {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const [viteModule] = viteModules;
|
|
43
|
-
return new DevServerAsset(src, {
|
|
44
|
-
assetMap: this,
|
|
45
|
-
viteModule
|
|
46
|
-
});
|
|
41
|
+
const asset = this.srcToAsset.get(src);
|
|
42
|
+
if (asset) {
|
|
43
|
+
return asset;
|
|
47
44
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
getJsDeps: async () => [assetUrl]
|
|
55
|
-
};
|
|
45
|
+
const realSrc = realPathRelativeTo(this.rootConfig.rootDir, src);
|
|
46
|
+
if (realSrc !== src) {
|
|
47
|
+
const asset2 = this.srcToAsset.get(realSrc);
|
|
48
|
+
if (asset2) {
|
|
49
|
+
return asset2;
|
|
50
|
+
}
|
|
56
51
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
console.log(`could not find build asset: ${src}`);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
add(asset) {
|
|
56
|
+
this.srcToAsset.set(asset.src, asset);
|
|
57
|
+
}
|
|
58
|
+
toJson() {
|
|
59
|
+
const result = {};
|
|
60
|
+
for (const src of this.srcToAsset.keys()) {
|
|
61
|
+
result[src] = this.srcToAsset.get(src).toJson();
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
static fromViteManifest(rootConfig, clientManifest, elementsGraph) {
|
|
66
|
+
const assetMap = new BuildAssetMap(rootConfig);
|
|
67
|
+
const elementFiles = /* @__PURE__ */ new Set();
|
|
68
|
+
Object.values(elementsGraph.sourceFiles).forEach((elementSource) => {
|
|
69
|
+
elementFiles.add(elementSource.relPath);
|
|
70
|
+
const realSrc = realPathRelativeTo(
|
|
71
|
+
rootConfig.rootDir,
|
|
72
|
+
elementSource.relPath
|
|
73
|
+
);
|
|
74
|
+
if (realSrc !== elementSource.filePath) {
|
|
75
|
+
elementFiles.add(realSrc);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.keys(clientManifest).forEach((manifestKey) => {
|
|
79
|
+
const src = manifestKey;
|
|
80
|
+
const manifestChunk = clientManifest[manifestKey];
|
|
81
|
+
const isElement = elementFiles.has(src);
|
|
82
|
+
const assetUrl = src.startsWith("routes/") && isJsFile(src) ? "" : `/${manifestChunk.file}`;
|
|
83
|
+
const assetData = {
|
|
61
84
|
src,
|
|
62
85
|
assetUrl,
|
|
63
|
-
|
|
64
|
-
|
|
86
|
+
importedModules: manifestChunk.imports || [],
|
|
87
|
+
importedCss: (manifestChunk.css || []).map((relPath) => `/${relPath}`),
|
|
88
|
+
isElement
|
|
65
89
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return
|
|
90
|
+
assetMap.add(new BuildAsset(assetMap, assetData));
|
|
91
|
+
});
|
|
92
|
+
return assetMap;
|
|
69
93
|
}
|
|
70
|
-
|
|
71
|
-
|
|
94
|
+
static fromRootManifest(rootConfig, rootManifest) {
|
|
95
|
+
const assetMap = new BuildAssetMap(rootConfig);
|
|
96
|
+
Object.keys(rootManifest).forEach((moduleId) => {
|
|
97
|
+
const assetData = rootManifest[moduleId];
|
|
98
|
+
assetMap.add(new BuildAsset(assetMap, assetData));
|
|
99
|
+
});
|
|
100
|
+
return assetMap;
|
|
72
101
|
}
|
|
73
102
|
};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
103
|
+
function realPathRelativeTo(rootDir, src) {
|
|
104
|
+
const fullPath = path.resolve(rootDir, src);
|
|
105
|
+
if (!fs.existsSync(fullPath)) {
|
|
106
|
+
return src;
|
|
107
|
+
}
|
|
108
|
+
const realpath = fs.realpathSync(path.resolve(rootDir, src));
|
|
109
|
+
return path.relative(rootDir, realpath);
|
|
110
|
+
}
|
|
111
|
+
var BuildAsset = class {
|
|
112
|
+
constructor(assetMap, assetData) {
|
|
113
|
+
this.assetMap = assetMap;
|
|
114
|
+
this.src = assetData.src;
|
|
115
|
+
this.assetUrl = assetData.assetUrl;
|
|
116
|
+
this.importedModules = assetData.importedModules;
|
|
117
|
+
this.importedCss = assetData.importedCss;
|
|
118
|
+
this.isElement = assetData.isElement;
|
|
81
119
|
}
|
|
82
120
|
async getCssDeps() {
|
|
83
121
|
const visited = /* @__PURE__ */ new Set();
|
|
84
122
|
const deps = /* @__PURE__ */ new Set();
|
|
85
|
-
this.collectCss(this, deps, visited);
|
|
123
|
+
await this.collectCss(this, deps, visited);
|
|
86
124
|
return Array.from(deps);
|
|
87
125
|
}
|
|
88
126
|
async getJsDeps() {
|
|
89
127
|
const visited = /* @__PURE__ */ new Set();
|
|
90
128
|
const deps = /* @__PURE__ */ new Set();
|
|
91
|
-
this.collectJs(this, deps, visited);
|
|
129
|
+
await this.collectJs(this, deps, visited);
|
|
92
130
|
return Array.from(deps);
|
|
93
131
|
}
|
|
94
|
-
|
|
95
|
-
return this.viteModule.importedModules;
|
|
96
|
-
}
|
|
97
|
-
collectJs(asset, urls, visited) {
|
|
132
|
+
async collectJs(asset, urls, visited) {
|
|
98
133
|
if (!asset) {
|
|
99
134
|
return;
|
|
100
135
|
}
|
|
101
|
-
if (!asset.
|
|
136
|
+
if (!asset.src) {
|
|
102
137
|
return;
|
|
103
138
|
}
|
|
104
|
-
if (visited.has(asset.
|
|
139
|
+
if (visited.has(asset.src)) {
|
|
105
140
|
return;
|
|
106
141
|
}
|
|
107
|
-
visited.add(asset.
|
|
108
|
-
|
|
109
|
-
if ([".js", ".jsx", ".ts", ".tsx"].includes(parts.ext) && asset.moduleId.includes("/elements/")) {
|
|
142
|
+
visited.add(asset.src);
|
|
143
|
+
if (asset.isElement) {
|
|
110
144
|
urls.add(asset.assetUrl);
|
|
111
145
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
const importedAsset = new DevServerAsset(src, {
|
|
116
|
-
assetMap: this.assetMap,
|
|
117
|
-
viteModule
|
|
118
|
-
});
|
|
146
|
+
await Promise.all(
|
|
147
|
+
asset.importedModules.map(async (src) => {
|
|
148
|
+
const importedAsset = await this.assetMap.get(src);
|
|
119
149
|
this.collectJs(importedAsset, urls, visited);
|
|
120
|
-
}
|
|
121
|
-
|
|
150
|
+
})
|
|
151
|
+
);
|
|
122
152
|
}
|
|
123
|
-
collectCss(asset, urls, visited) {
|
|
153
|
+
async collectCss(asset, urls, visited) {
|
|
124
154
|
if (!asset) {
|
|
125
155
|
return;
|
|
126
156
|
}
|
|
127
|
-
if (!asset.
|
|
157
|
+
if (!asset.src) {
|
|
128
158
|
return;
|
|
129
159
|
}
|
|
130
|
-
if (visited.has(asset.
|
|
160
|
+
if (visited.has(asset.src)) {
|
|
131
161
|
return;
|
|
132
162
|
}
|
|
133
|
-
visited.add(asset.
|
|
134
|
-
if (asset.
|
|
135
|
-
|
|
136
|
-
if (!parts.name.startsWith("_")) {
|
|
137
|
-
urls.add(asset.assetUrl);
|
|
138
|
-
}
|
|
163
|
+
visited.add(asset.src);
|
|
164
|
+
if (asset.importedCss) {
|
|
165
|
+
asset.importedCss.forEach((cssUrl) => urls.add(cssUrl));
|
|
139
166
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
const importedAsset = new DevServerAsset(src, {
|
|
144
|
-
assetMap: this.assetMap,
|
|
145
|
-
viteModule
|
|
146
|
-
});
|
|
167
|
+
await Promise.all(
|
|
168
|
+
asset.importedModules.map(async (moduleId) => {
|
|
169
|
+
const importedAsset = await this.assetMap.get(moduleId);
|
|
147
170
|
this.collectCss(importedAsset, urls, visited);
|
|
148
|
-
}
|
|
149
|
-
|
|
171
|
+
})
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
toJson() {
|
|
175
|
+
return {
|
|
176
|
+
src: this.src,
|
|
177
|
+
assetUrl: this.assetUrl,
|
|
178
|
+
importedModules: this.importedModules,
|
|
179
|
+
importedCss: this.importedCss,
|
|
180
|
+
isElement: this.isElement
|
|
181
|
+
};
|
|
150
182
|
}
|
|
151
183
|
};
|
|
152
184
|
|
|
153
|
-
// src/cli/commands/
|
|
154
|
-
import { dim } from "kleur/colors";
|
|
155
|
-
|
|
156
|
-
// src/core/middleware.ts
|
|
157
|
-
function rootProjectMiddleware(options) {
|
|
158
|
-
return (req, _, next) => {
|
|
159
|
-
req.rootConfig = options.rootConfig;
|
|
160
|
-
next();
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// src/utils/ports.ts
|
|
165
|
-
import { createServer } from "node:net";
|
|
166
|
-
function isPortOpen(port) {
|
|
167
|
-
return new Promise((resolve, reject) => {
|
|
168
|
-
const server = createServer();
|
|
169
|
-
server.on("error", (err) => {
|
|
170
|
-
if (err.code === "EADDRINUSE") {
|
|
171
|
-
resolve(false);
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
reject(err);
|
|
175
|
-
});
|
|
176
|
-
server.on("close", () => {
|
|
177
|
-
resolve(true);
|
|
178
|
-
});
|
|
179
|
-
server.listen(port, () => {
|
|
180
|
-
server.close((err) => {
|
|
181
|
-
if (err) {
|
|
182
|
-
console.log(`error closing server: ${err}`);
|
|
183
|
-
reject(err);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
async function findOpenPort(min, max) {
|
|
190
|
-
let port = min;
|
|
191
|
-
while (port <= max) {
|
|
192
|
-
const isOpen = await isPortOpen(port);
|
|
193
|
-
if (isOpen) {
|
|
194
|
-
return port;
|
|
195
|
-
}
|
|
196
|
-
port += 1;
|
|
197
|
-
}
|
|
198
|
-
throw new Error(`no ports open between ${min} and ${max}`);
|
|
199
|
-
}
|
|
185
|
+
// src/cli/commands/build.ts
|
|
186
|
+
import { dim, cyan } from "kleur/colors";
|
|
200
187
|
|
|
201
188
|
// src/node/element-graph.ts
|
|
202
|
-
import
|
|
189
|
+
import fs2 from "node:fs";
|
|
203
190
|
import path2 from "node:path";
|
|
204
|
-
import { searchForWorkspaceRoot
|
|
191
|
+
import { searchForWorkspaceRoot } from "vite";
|
|
205
192
|
import glob from "tiny-glob";
|
|
206
193
|
var ElementGraph = class {
|
|
207
194
|
constructor(sourceFiles) {
|
|
@@ -209,6 +196,20 @@ var ElementGraph = class {
|
|
|
209
196
|
this.deps = {};
|
|
210
197
|
this.sourceFiles = sourceFiles;
|
|
211
198
|
}
|
|
199
|
+
toJson() {
|
|
200
|
+
for (const tagName in this.sourceFiles) {
|
|
201
|
+
this.deps[tagName] ??= this.parseDepsFromSource(tagName);
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
sourceFiles: this.sourceFiles,
|
|
205
|
+
deps: this.deps
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
static fromJson(data) {
|
|
209
|
+
const graph = new ElementGraph(data.sourceFiles);
|
|
210
|
+
graph.deps = data.deps;
|
|
211
|
+
return graph;
|
|
212
|
+
}
|
|
212
213
|
getDeps(tagName, visited) {
|
|
213
214
|
visited ??= /* @__PURE__ */ new Set();
|
|
214
215
|
if (visited.has(tagName)) {
|
|
@@ -229,7 +230,7 @@ var ElementGraph = class {
|
|
|
229
230
|
if (!srcFile) {
|
|
230
231
|
throw new Error(`could not find file path for tagName <${tagName}>`);
|
|
231
232
|
}
|
|
232
|
-
const src =
|
|
233
|
+
const src = fs2.readFileSync(srcFile.filePath, "utf-8");
|
|
233
234
|
const tagNames = parseTagNames(src);
|
|
234
235
|
const deps = /* @__PURE__ */ new Set();
|
|
235
236
|
for (const depTagName of tagNames) {
|
|
@@ -243,7 +244,7 @@ var ElementGraph = class {
|
|
|
243
244
|
async function getElements(rootConfig) {
|
|
244
245
|
var _a, _b;
|
|
245
246
|
const rootDir = rootConfig.rootDir;
|
|
246
|
-
const workspaceRoot =
|
|
247
|
+
const workspaceRoot = searchForWorkspaceRoot(rootDir);
|
|
247
248
|
const elementsDirs = [path2.join(rootDir, "elements")];
|
|
248
249
|
const elementsInclude = ((_a = rootConfig.elements) == null ? void 0 : _a.include) || [];
|
|
249
250
|
const excludePatterns = ((_b = rootConfig.elements) == null ? void 0 : _b.exclude) || [];
|
|
@@ -280,321 +281,30 @@ async function getElements(rootConfig) {
|
|
|
280
281
|
return graph;
|
|
281
282
|
}
|
|
282
283
|
|
|
283
|
-
// src/cli/commands/
|
|
284
|
-
import glob2 from "tiny-glob";
|
|
284
|
+
// src/cli/commands/build.ts
|
|
285
285
|
var __dirname = path3.dirname(fileURLToPath(import.meta.url));
|
|
286
|
-
async function
|
|
287
|
-
|
|
286
|
+
async function build(rootProjectDir, options) {
|
|
287
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
288
|
+
const mode = (options == null ? void 0 : options.mode) || "production";
|
|
289
|
+
process.env.NODE_ENV = mode;
|
|
288
290
|
const rootDir = path3.resolve(rootProjectDir || process.cwd());
|
|
289
|
-
const
|
|
290
|
-
const
|
|
291
|
+
const rootConfig = await loadRootConfig(rootDir, { command: "build" });
|
|
292
|
+
const distDir = path3.join(rootDir, "dist");
|
|
293
|
+
const ssrOnly = (options == null ? void 0 : options.ssrOnly) || false;
|
|
291
294
|
console.log();
|
|
292
295
|
console.log(`${dim("\u2503")} project: ${rootDir}`);
|
|
293
|
-
console.log(`${dim("\u2503")}
|
|
294
|
-
console.log(`${dim("\u2503")} mode:
|
|
295
|
-
console.log();
|
|
296
|
-
const server = await createServer2({ rootDir, port });
|
|
297
|
-
server.listen(port);
|
|
298
|
-
}
|
|
299
|
-
async function createServer2(options) {
|
|
300
|
-
const rootDir = path3.resolve((options == null ? void 0 : options.rootDir) || process.cwd());
|
|
301
|
-
const rootConfig = await loadRootConfig(rootDir, { command: "dev" });
|
|
302
|
-
const port = options == null ? void 0 : options.port;
|
|
303
|
-
const server = express();
|
|
304
|
-
server.disable("x-powered-by");
|
|
305
|
-
server.use(rootProjectMiddleware({ rootConfig }));
|
|
306
|
-
server.use(await viteServerMiddleware({ rootConfig, port }));
|
|
307
|
-
const plugins = rootConfig.plugins || [];
|
|
308
|
-
await configureServerPlugins(
|
|
309
|
-
server,
|
|
310
|
-
async () => {
|
|
311
|
-
var _a;
|
|
312
|
-
const userMiddlewares = ((_a = rootConfig.server) == null ? void 0 : _a.middlewares) || [];
|
|
313
|
-
for (const middleware of userMiddlewares) {
|
|
314
|
-
server.use(middleware);
|
|
315
|
-
}
|
|
316
|
-
server.use(rootDevServerMiddleware());
|
|
317
|
-
server.use(rootDevServer404Middleware());
|
|
318
|
-
server.use(rootDevServer500Middleware());
|
|
319
|
-
},
|
|
320
|
-
plugins,
|
|
321
|
-
{ type: "dev", rootConfig }
|
|
322
|
-
);
|
|
323
|
-
return server;
|
|
324
|
-
}
|
|
325
|
-
async function viteServerMiddleware(options) {
|
|
326
|
-
const rootConfig = options.rootConfig;
|
|
327
|
-
const rootDir = rootConfig.rootDir;
|
|
328
|
-
const elementGraph = await getElements(rootConfig);
|
|
329
|
-
const elements = Object.values(elementGraph.sourceFiles).map((sourceFile) => {
|
|
330
|
-
return sourceFile.relPath;
|
|
331
|
-
});
|
|
332
|
-
const bundleScripts = [];
|
|
333
|
-
if (await isDirectory(path3.join(rootDir, "bundles"))) {
|
|
334
|
-
const bundleFiles = await glob2("bundles/*", { cwd: rootDir });
|
|
335
|
-
bundleFiles.forEach((file) => {
|
|
336
|
-
const parts = path3.parse(file);
|
|
337
|
-
if (isJsFile(parts.base)) {
|
|
338
|
-
bundleScripts.push(file);
|
|
339
|
-
}
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
const optimizeDeps = [...elements, ...bundleScripts];
|
|
343
|
-
const viteServer = await createViteServer(rootConfig, {
|
|
344
|
-
port: options.port,
|
|
345
|
-
optimizeDeps
|
|
346
|
-
});
|
|
347
|
-
return async (req, res, next) => {
|
|
348
|
-
try {
|
|
349
|
-
req.viteServer = viteServer;
|
|
350
|
-
const renderModulePath = path3.resolve(__dirname, "./render.js");
|
|
351
|
-
const render = await viteServer.ssrLoadModule(
|
|
352
|
-
renderModulePath
|
|
353
|
-
);
|
|
354
|
-
const assetMap = new DevServerAssetMap(
|
|
355
|
-
rootConfig,
|
|
356
|
-
viteServer.moduleGraph
|
|
357
|
-
);
|
|
358
|
-
req.renderer = new render.Renderer(rootConfig, { assetMap, elementGraph });
|
|
359
|
-
viteServer.middlewares(req, res, next);
|
|
360
|
-
} catch (e) {
|
|
361
|
-
next(e);
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
function rootDevServerMiddleware() {
|
|
366
|
-
return async (req, res, next) => {
|
|
367
|
-
const renderer = req.renderer;
|
|
368
|
-
const viteServer = req.viteServer;
|
|
369
|
-
try {
|
|
370
|
-
await renderer.handle(req, res, next);
|
|
371
|
-
} catch (err) {
|
|
372
|
-
viteServer.ssrFixStacktrace(err);
|
|
373
|
-
next(err);
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
function rootDevServer404Middleware() {
|
|
378
|
-
return async (req, res) => {
|
|
379
|
-
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
380
|
-
if (req.renderer) {
|
|
381
|
-
const url = req.path;
|
|
382
|
-
const ext = path3.extname(url);
|
|
383
|
-
if (!ext) {
|
|
384
|
-
const renderer = req.renderer;
|
|
385
|
-
const data = await renderer.renderDevServer404(req);
|
|
386
|
-
const html = data.html || "";
|
|
387
|
-
res.status(404).set({ "Content-Type": "text/html" }).end(html);
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
res.status(404).set({ "Content-Type": "text/plain" }).end("404");
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
function rootDevServer500Middleware() {
|
|
395
|
-
return async (err, req, res, next) => {
|
|
396
|
-
console.error(`\u2757 500 ${req.originalUrl}`);
|
|
397
|
-
console.error(String(err.stack || err));
|
|
398
|
-
if (req.renderer) {
|
|
399
|
-
const url = req.path;
|
|
400
|
-
const ext = path3.extname(url);
|
|
401
|
-
if (!ext) {
|
|
402
|
-
const renderer = req.renderer;
|
|
403
|
-
const data = await renderer.renderDevServer500(req, err);
|
|
404
|
-
const html = data.html || "";
|
|
405
|
-
res.status(500).set({ "Content-Type": "text/html" }).end(html);
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
next(err);
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// src/cli/commands/build.ts
|
|
414
|
-
import path5 from "node:path";
|
|
415
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
416
|
-
import fsExtra from "fs-extra";
|
|
417
|
-
import glob3 from "tiny-glob";
|
|
418
|
-
import { build as viteBuild } from "vite";
|
|
419
|
-
|
|
420
|
-
// src/render/asset-map/build-asset-map.ts
|
|
421
|
-
import fs2 from "node:fs";
|
|
422
|
-
import path4 from "node:path";
|
|
423
|
-
var BuildAssetMap = class {
|
|
424
|
-
constructor(rootConfig) {
|
|
425
|
-
this.rootConfig = rootConfig;
|
|
426
|
-
this.srcToAsset = /* @__PURE__ */ new Map();
|
|
427
|
-
}
|
|
428
|
-
async get(src) {
|
|
429
|
-
const asset = this.srcToAsset.get(src);
|
|
430
|
-
if (asset) {
|
|
431
|
-
return asset;
|
|
432
|
-
}
|
|
433
|
-
const realSrc = realPathRelativeTo(this.rootConfig.rootDir, src);
|
|
434
|
-
if (realSrc !== src) {
|
|
435
|
-
const asset2 = this.srcToAsset.get(realSrc);
|
|
436
|
-
if (asset2) {
|
|
437
|
-
return asset2;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
console.log(`could not find build asset: ${src}`);
|
|
441
|
-
return null;
|
|
442
|
-
}
|
|
443
|
-
add(asset) {
|
|
444
|
-
this.srcToAsset.set(asset.src, asset);
|
|
445
|
-
}
|
|
446
|
-
toJson() {
|
|
447
|
-
const result = {};
|
|
448
|
-
for (const src of this.srcToAsset.keys()) {
|
|
449
|
-
result[src] = this.srcToAsset.get(src).toJson();
|
|
450
|
-
}
|
|
451
|
-
return result;
|
|
452
|
-
}
|
|
453
|
-
static fromViteManifest(rootConfig, clientManifest, elementsGraph) {
|
|
454
|
-
const assetMap = new BuildAssetMap(rootConfig);
|
|
455
|
-
const elementFiles = /* @__PURE__ */ new Set();
|
|
456
|
-
Object.values(elementsGraph.sourceFiles).forEach((elementSource) => {
|
|
457
|
-
elementFiles.add(elementSource.relPath);
|
|
458
|
-
const realSrc = realPathRelativeTo(
|
|
459
|
-
rootConfig.rootDir,
|
|
460
|
-
elementSource.relPath
|
|
461
|
-
);
|
|
462
|
-
if (realSrc !== elementSource.filePath) {
|
|
463
|
-
elementFiles.add(realSrc);
|
|
464
|
-
}
|
|
465
|
-
});
|
|
466
|
-
Object.keys(clientManifest).forEach((manifestKey) => {
|
|
467
|
-
const src = manifestKey;
|
|
468
|
-
const manifestChunk = clientManifest[manifestKey];
|
|
469
|
-
const isElement = elementFiles.has(src);
|
|
470
|
-
const assetUrl = src.startsWith("routes/") ? "" : `/${manifestChunk.file}`;
|
|
471
|
-
const assetData = {
|
|
472
|
-
src,
|
|
473
|
-
assetUrl,
|
|
474
|
-
importedModules: manifestChunk.imports || [],
|
|
475
|
-
importedCss: (manifestChunk.css || []).map((relPath) => `/${relPath}`),
|
|
476
|
-
isElement
|
|
477
|
-
};
|
|
478
|
-
assetMap.add(new BuildAsset(assetMap, assetData));
|
|
479
|
-
});
|
|
480
|
-
return assetMap;
|
|
481
|
-
}
|
|
482
|
-
static fromRootManifest(rootConfig, rootManifest) {
|
|
483
|
-
const assetMap = new BuildAssetMap(rootConfig);
|
|
484
|
-
Object.keys(rootManifest).forEach((moduleId) => {
|
|
485
|
-
const assetData = rootManifest[moduleId];
|
|
486
|
-
assetMap.add(new BuildAsset(assetMap, assetData));
|
|
487
|
-
});
|
|
488
|
-
return assetMap;
|
|
489
|
-
}
|
|
490
|
-
};
|
|
491
|
-
function realPathRelativeTo(rootDir, src) {
|
|
492
|
-
const fullPath = path4.resolve(rootDir, src);
|
|
493
|
-
if (!fs2.existsSync(fullPath)) {
|
|
494
|
-
return src;
|
|
495
|
-
}
|
|
496
|
-
const realpath = fs2.realpathSync(path4.resolve(rootDir, src));
|
|
497
|
-
return path4.relative(rootDir, realpath);
|
|
498
|
-
}
|
|
499
|
-
var BuildAsset = class {
|
|
500
|
-
constructor(assetMap, assetData) {
|
|
501
|
-
this.assetMap = assetMap;
|
|
502
|
-
this.src = assetData.src;
|
|
503
|
-
this.assetUrl = assetData.assetUrl;
|
|
504
|
-
this.importedModules = assetData.importedModules;
|
|
505
|
-
this.importedCss = assetData.importedCss;
|
|
506
|
-
this.isElement = assetData.isElement;
|
|
507
|
-
}
|
|
508
|
-
async getCssDeps() {
|
|
509
|
-
const visited = /* @__PURE__ */ new Set();
|
|
510
|
-
const deps = /* @__PURE__ */ new Set();
|
|
511
|
-
await this.collectCss(this, deps, visited);
|
|
512
|
-
return Array.from(deps);
|
|
513
|
-
}
|
|
514
|
-
async getJsDeps() {
|
|
515
|
-
const visited = /* @__PURE__ */ new Set();
|
|
516
|
-
const deps = /* @__PURE__ */ new Set();
|
|
517
|
-
await this.collectJs(this, deps, visited);
|
|
518
|
-
return Array.from(deps);
|
|
519
|
-
}
|
|
520
|
-
async collectJs(asset, urls, visited) {
|
|
521
|
-
if (!asset) {
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
|
-
if (!asset.src) {
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
if (visited.has(asset.src)) {
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
visited.add(asset.src);
|
|
531
|
-
if (asset.isElement) {
|
|
532
|
-
urls.add(asset.assetUrl);
|
|
533
|
-
}
|
|
534
|
-
await Promise.all(
|
|
535
|
-
asset.importedModules.map(async (src) => {
|
|
536
|
-
const importedAsset = await this.assetMap.get(src);
|
|
537
|
-
this.collectJs(importedAsset, urls, visited);
|
|
538
|
-
})
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
async collectCss(asset, urls, visited) {
|
|
542
|
-
if (!asset) {
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
if (!asset.src) {
|
|
546
|
-
return;
|
|
547
|
-
}
|
|
548
|
-
if (visited.has(asset.src)) {
|
|
549
|
-
return;
|
|
550
|
-
}
|
|
551
|
-
visited.add(asset.src);
|
|
552
|
-
if (asset.importedCss) {
|
|
553
|
-
asset.importedCss.forEach((cssUrl) => urls.add(cssUrl));
|
|
554
|
-
}
|
|
555
|
-
await Promise.all(
|
|
556
|
-
asset.importedModules.map(async (moduleId) => {
|
|
557
|
-
const importedAsset = await this.assetMap.get(moduleId);
|
|
558
|
-
this.collectCss(importedAsset, urls, visited);
|
|
559
|
-
})
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
|
-
toJson() {
|
|
563
|
-
return {
|
|
564
|
-
src: this.src,
|
|
565
|
-
assetUrl: this.assetUrl,
|
|
566
|
-
importedModules: this.importedModules,
|
|
567
|
-
importedCss: this.importedCss,
|
|
568
|
-
isElement: this.isElement
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
};
|
|
572
|
-
|
|
573
|
-
// src/cli/commands/build.ts
|
|
574
|
-
import { dim as dim2, cyan } from "kleur/colors";
|
|
575
|
-
var __dirname2 = path5.dirname(fileURLToPath2(import.meta.url));
|
|
576
|
-
async function build(rootProjectDir, options) {
|
|
577
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
578
|
-
const mode = (options == null ? void 0 : options.mode) || "production";
|
|
579
|
-
process.env.NODE_ENV = mode;
|
|
580
|
-
const rootDir = path5.resolve(rootProjectDir || process.cwd());
|
|
581
|
-
const rootConfig = await loadRootConfig(rootDir, { command: "build" });
|
|
582
|
-
const distDir = path5.join(rootDir, "dist");
|
|
583
|
-
const ssrOnly = (options == null ? void 0 : options.ssrOnly) || false;
|
|
584
|
-
console.log();
|
|
585
|
-
console.log(`${dim2("\u2503")} project: ${rootDir}`);
|
|
586
|
-
console.log(`${dim2("\u2503")} output: ${distDir}/html`);
|
|
587
|
-
console.log(`${dim2("\u2503")} mode: ${mode}`);
|
|
296
|
+
console.log(`${dim("\u2503")} output: ${distDir}/html`);
|
|
297
|
+
console.log(`${dim("\u2503")} mode: ${mode}`);
|
|
588
298
|
console.log();
|
|
589
299
|
await rmDir(distDir);
|
|
590
300
|
await makeDir(distDir);
|
|
591
301
|
const routeFiles = [];
|
|
592
|
-
if (await isDirectory(
|
|
593
|
-
const pageFiles = await
|
|
302
|
+
if (await isDirectory(path3.join(rootDir, "routes"))) {
|
|
303
|
+
const pageFiles = await glob2("routes/**/*", { cwd: rootDir });
|
|
594
304
|
pageFiles.forEach((file) => {
|
|
595
|
-
const parts =
|
|
305
|
+
const parts = path3.parse(file);
|
|
596
306
|
if (!parts.name.startsWith("_") && isJsFile(parts.base)) {
|
|
597
|
-
routeFiles.push(
|
|
307
|
+
routeFiles.push(path3.resolve(rootDir, file));
|
|
598
308
|
}
|
|
599
309
|
});
|
|
600
310
|
}
|
|
@@ -603,12 +313,12 @@ async function build(rootProjectDir, options) {
|
|
|
603
313
|
return sourceFile.filePath;
|
|
604
314
|
});
|
|
605
315
|
const bundleScripts = [];
|
|
606
|
-
if (await isDirectory(
|
|
607
|
-
const bundleFiles = await
|
|
316
|
+
if (await isDirectory(path3.join(rootDir, "bundles"))) {
|
|
317
|
+
const bundleFiles = await glob2("bundles/*", { cwd: rootDir });
|
|
608
318
|
bundleFiles.forEach((file) => {
|
|
609
|
-
const parts =
|
|
319
|
+
const parts = path3.parse(file);
|
|
610
320
|
if (isJsFile(parts.base)) {
|
|
611
|
-
bundleScripts.push(
|
|
321
|
+
bundleScripts.push(path3.resolve(rootDir, file));
|
|
612
322
|
}
|
|
613
323
|
});
|
|
614
324
|
}
|
|
@@ -631,7 +341,7 @@ async function build(rootProjectDir, options) {
|
|
|
631
341
|
plugins: vitePlugins
|
|
632
342
|
};
|
|
633
343
|
const ssrInput = {
|
|
634
|
-
render:
|
|
344
|
+
render: path3.resolve(__dirname, "./render.js")
|
|
635
345
|
};
|
|
636
346
|
rootPlugins.forEach((plugin) => {
|
|
637
347
|
if (plugin.ssrInput) {
|
|
@@ -661,7 +371,7 @@ async function build(rootProjectDir, options) {
|
|
|
661
371
|
assetFileNames: "assets/[name].[hash][extname]"
|
|
662
372
|
}
|
|
663
373
|
},
|
|
664
|
-
outDir:
|
|
374
|
+
outDir: path3.join(distDir, "server"),
|
|
665
375
|
ssr: true,
|
|
666
376
|
ssrManifest: false,
|
|
667
377
|
cssCodeSplit: true,
|
|
@@ -692,7 +402,7 @@ async function build(rootProjectDir, options) {
|
|
|
692
402
|
...(_e = (_d = viteConfig == null ? void 0 : viteConfig.build) == null ? void 0 : _d.rollupOptions) == null ? void 0 : _e.output
|
|
693
403
|
}
|
|
694
404
|
},
|
|
695
|
-
outDir:
|
|
405
|
+
outDir: path3.join(distDir, "routes"),
|
|
696
406
|
ssr: false,
|
|
697
407
|
ssrManifest: false,
|
|
698
408
|
manifest: true,
|
|
@@ -721,7 +431,7 @@ async function build(rootProjectDir, options) {
|
|
|
721
431
|
...(_h = (_g = viteConfig == null ? void 0 : viteConfig.build) == null ? void 0 : _g.rollupOptions) == null ? void 0 : _h.output
|
|
722
432
|
}
|
|
723
433
|
},
|
|
724
|
-
outDir:
|
|
434
|
+
outDir: path3.join(distDir, "client"),
|
|
725
435
|
ssr: false,
|
|
726
436
|
ssrManifest: false,
|
|
727
437
|
manifest: true,
|
|
@@ -732,136 +442,451 @@ async function build(rootProjectDir, options) {
|
|
|
732
442
|
reportCompressedSize: false
|
|
733
443
|
}
|
|
734
444
|
});
|
|
735
|
-
} else {
|
|
736
|
-
await writeFile(
|
|
737
|
-
}
|
|
738
|
-
await copyGlob(
|
|
739
|
-
"*.css",
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
);
|
|
743
|
-
const routesManifest = await loadJson(
|
|
744
|
-
|
|
745
|
-
);
|
|
746
|
-
const clientManifest = await loadJson(
|
|
747
|
-
|
|
748
|
-
);
|
|
749
|
-
function collectRouteCss(asset, cssDeps, visited) {
|
|
750
|
-
if (!asset || !asset.file || visited.has(asset.file)) {
|
|
751
|
-
return;
|
|
752
|
-
}
|
|
753
|
-
visited.add(asset.file);
|
|
754
|
-
if (asset.css) {
|
|
755
|
-
asset.css.forEach((dep) => cssDeps.add(dep));
|
|
756
|
-
}
|
|
757
|
-
if (asset.imports) {
|
|
758
|
-
asset.imports.forEach((manifestKey) => {
|
|
759
|
-
collectRouteCss(routesManifest[manifestKey], cssDeps, visited);
|
|
445
|
+
} else {
|
|
446
|
+
await writeFile(path3.join(distDir, "client/manifest.json"), "{}");
|
|
447
|
+
}
|
|
448
|
+
await copyGlob(
|
|
449
|
+
"*.css",
|
|
450
|
+
path3.join(distDir, "routes/assets"),
|
|
451
|
+
path3.join(distDir, "client/assets")
|
|
452
|
+
);
|
|
453
|
+
const routesManifest = await loadJson(
|
|
454
|
+
path3.join(distDir, "routes/manifest.json")
|
|
455
|
+
);
|
|
456
|
+
const clientManifest = await loadJson(
|
|
457
|
+
path3.join(distDir, "client/manifest.json")
|
|
458
|
+
);
|
|
459
|
+
function collectRouteCss(asset, cssDeps, visited) {
|
|
460
|
+
if (!asset || !asset.file || visited.has(asset.file)) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
visited.add(asset.file);
|
|
464
|
+
if (asset.css) {
|
|
465
|
+
asset.css.forEach((dep) => cssDeps.add(dep));
|
|
466
|
+
}
|
|
467
|
+
if (asset.imports) {
|
|
468
|
+
asset.imports.forEach((manifestKey) => {
|
|
469
|
+
collectRouteCss(routesManifest[manifestKey], cssDeps, visited);
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
Object.keys(routesManifest).forEach((manifestKey) => {
|
|
474
|
+
const asset = routesManifest[manifestKey];
|
|
475
|
+
if (asset.isEntry) {
|
|
476
|
+
const visited = /* @__PURE__ */ new Set();
|
|
477
|
+
const cssDeps = /* @__PURE__ */ new Set();
|
|
478
|
+
collectRouteCss(asset, cssDeps, visited);
|
|
479
|
+
asset.css = Array.from(cssDeps);
|
|
480
|
+
asset.imports = [];
|
|
481
|
+
clientManifest[manifestKey] = asset;
|
|
482
|
+
} else if (asset.file.endsWith(".css")) {
|
|
483
|
+
clientManifest[manifestKey] = asset;
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
const assetMap = BuildAssetMap.fromViteManifest(
|
|
487
|
+
rootConfig,
|
|
488
|
+
clientManifest,
|
|
489
|
+
elementGraph
|
|
490
|
+
);
|
|
491
|
+
const rootManifest = assetMap.toJson();
|
|
492
|
+
await writeFile(
|
|
493
|
+
path3.join(distDir, "client/root-manifest.json"),
|
|
494
|
+
JSON.stringify(rootManifest, null, 2)
|
|
495
|
+
);
|
|
496
|
+
const elementGraphJson = elementGraph.toJson();
|
|
497
|
+
await writeFile(
|
|
498
|
+
path3.join(distDir, "client/root-element-graph.json"),
|
|
499
|
+
JSON.stringify(elementGraphJson, null, 2)
|
|
500
|
+
);
|
|
501
|
+
const buildDir = path3.join(distDir, "html");
|
|
502
|
+
const publicDir = path3.join(rootDir, "public");
|
|
503
|
+
if (fsExtra.existsSync(path3.join(rootDir, "public"))) {
|
|
504
|
+
fsExtra.copySync(publicDir, buildDir, { dereference: true });
|
|
505
|
+
} else {
|
|
506
|
+
await makeDir(buildDir);
|
|
507
|
+
}
|
|
508
|
+
await makeDir(path3.join(buildDir, "assets"));
|
|
509
|
+
await makeDir(path3.join(buildDir, "chunks"));
|
|
510
|
+
console.log("\njs/css output:");
|
|
511
|
+
await Promise.all(
|
|
512
|
+
Object.keys(rootManifest).map(async (src) => {
|
|
513
|
+
if (isRouteFile(src)) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const assetData = rootManifest[src];
|
|
517
|
+
if (!assetData.assetUrl) {
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
const assetRelPath = assetData.assetUrl.slice(1);
|
|
521
|
+
const assetFrom = path3.join(distDir, "client", assetRelPath);
|
|
522
|
+
const assetTo = path3.join(buildDir, assetRelPath);
|
|
523
|
+
if (!await fileExists(assetFrom)) {
|
|
524
|
+
console.log(`${assetFrom} does not exist`);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
await fsExtra.copy(assetFrom, assetTo);
|
|
528
|
+
printFileOutput(fileSize(assetTo), "dist/html/", assetRelPath);
|
|
529
|
+
})
|
|
530
|
+
);
|
|
531
|
+
if (!ssrOnly) {
|
|
532
|
+
const render = await import(path3.join(distDir, "server/render.js"));
|
|
533
|
+
const renderer = new render.Renderer(rootConfig, { assetMap, elementGraph });
|
|
534
|
+
const sitemap = await renderer.getSitemap();
|
|
535
|
+
console.log("\nhtml output:");
|
|
536
|
+
await Promise.all(
|
|
537
|
+
Object.keys(sitemap).map(async (urlPath) => {
|
|
538
|
+
const { route, params } = sitemap[urlPath];
|
|
539
|
+
const data = await renderer.renderRoute(route, {
|
|
540
|
+
routeParams: params
|
|
541
|
+
});
|
|
542
|
+
if (data.notFound) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
let outFilePath = path3.join(urlPath.slice(1), "index.html");
|
|
546
|
+
if (outFilePath.endsWith("404/index.html")) {
|
|
547
|
+
outFilePath = outFilePath.replace("404/index.html", "404.html");
|
|
548
|
+
}
|
|
549
|
+
const outPath = path3.join(buildDir, outFilePath);
|
|
550
|
+
let html = data.html || "";
|
|
551
|
+
if (rootConfig.prettyHtml !== false) {
|
|
552
|
+
html = await htmlPretty(html, rootConfig.prettyHtmlOptions);
|
|
553
|
+
}
|
|
554
|
+
if (rootConfig.minifyHtml !== false) {
|
|
555
|
+
html = await htmlMinify(html, rootConfig.minifyHtmlOptions);
|
|
556
|
+
}
|
|
557
|
+
await writeFile(outPath, html);
|
|
558
|
+
printFileOutput(fileSize(outPath), "dist/html/", outFilePath);
|
|
559
|
+
})
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
function isRouteFile(filepath) {
|
|
564
|
+
return filepath.startsWith("routes") && isJsFile(filepath);
|
|
565
|
+
}
|
|
566
|
+
function fileSize(filepath) {
|
|
567
|
+
const stats = fsExtra.statSync(filepath);
|
|
568
|
+
const bytes = stats.size;
|
|
569
|
+
const k = 1024;
|
|
570
|
+
if (bytes < k) {
|
|
571
|
+
return (bytes / k).toFixed(2) + " kB";
|
|
572
|
+
}
|
|
573
|
+
const units = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
|
574
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
575
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + units[i];
|
|
576
|
+
}
|
|
577
|
+
function printFileOutput(fileSize2, outputDir, outputFile) {
|
|
578
|
+
const indent = " ".repeat(2);
|
|
579
|
+
const paddedSize = fileSize2.padStart(9, " ");
|
|
580
|
+
console.log(
|
|
581
|
+
`${indent}${dim(paddedSize)} ${dim(outputDir)}${cyan(outputFile)}`
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// src/cli/commands/dev.ts
|
|
586
|
+
import path5 from "node:path";
|
|
587
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
588
|
+
import { default as express } from "express";
|
|
589
|
+
|
|
590
|
+
// src/render/asset-map/dev-asset-map.ts
|
|
591
|
+
import path4 from "node:path";
|
|
592
|
+
import { searchForWorkspaceRoot as searchForWorkspaceRoot2 } from "vite";
|
|
593
|
+
var DevServerAssetMap = class {
|
|
594
|
+
constructor(rootConfig, moduleGraph) {
|
|
595
|
+
this.rootConfig = rootConfig;
|
|
596
|
+
this.moduleGraph = moduleGraph;
|
|
597
|
+
}
|
|
598
|
+
async get(src) {
|
|
599
|
+
const file = path4.resolve(this.rootConfig.rootDir, src);
|
|
600
|
+
const viteModules = this.moduleGraph.getModulesByFile(file);
|
|
601
|
+
if (viteModules && viteModules.size > 0) {
|
|
602
|
+
const [viteModule] = viteModules;
|
|
603
|
+
return new DevServerAsset(src, {
|
|
604
|
+
assetMap: this,
|
|
605
|
+
viteModule
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
if (file.startsWith(this.rootConfig.rootDir)) {
|
|
609
|
+
const assetUrl = file.slice(this.rootConfig.rootDir.length);
|
|
610
|
+
return {
|
|
611
|
+
src,
|
|
612
|
+
assetUrl,
|
|
613
|
+
getCssDeps: async () => [],
|
|
614
|
+
getJsDeps: async () => [assetUrl]
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
const workspaceRoot = searchForWorkspaceRoot2(this.rootConfig.rootDir);
|
|
618
|
+
if (await directoryContains(workspaceRoot, file)) {
|
|
619
|
+
const assetUrl = `/@fs/${file}`;
|
|
620
|
+
return {
|
|
621
|
+
src,
|
|
622
|
+
assetUrl,
|
|
623
|
+
getCssDeps: async () => [],
|
|
624
|
+
getJsDeps: async () => [assetUrl]
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
console.log(`could not find asset in asset map: ${src}`);
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
filePathToSrc(file) {
|
|
631
|
+
return path4.relative(this.rootConfig.rootDir, file);
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
var DevServerAsset = class {
|
|
635
|
+
constructor(src, options) {
|
|
636
|
+
this.src = src;
|
|
637
|
+
this.assetMap = options.assetMap;
|
|
638
|
+
this.viteModule = options.viteModule;
|
|
639
|
+
this.moduleId = this.viteModule.id;
|
|
640
|
+
this.assetUrl = this.viteModule.url;
|
|
641
|
+
}
|
|
642
|
+
async getCssDeps() {
|
|
643
|
+
const visited = /* @__PURE__ */ new Set();
|
|
644
|
+
const deps = /* @__PURE__ */ new Set();
|
|
645
|
+
this.collectCss(this, deps, visited);
|
|
646
|
+
return Array.from(deps);
|
|
647
|
+
}
|
|
648
|
+
async getJsDeps() {
|
|
649
|
+
const visited = /* @__PURE__ */ new Set();
|
|
650
|
+
const deps = /* @__PURE__ */ new Set();
|
|
651
|
+
this.collectJs(this, deps, visited);
|
|
652
|
+
return Array.from(deps);
|
|
653
|
+
}
|
|
654
|
+
getImportedModules() {
|
|
655
|
+
return this.viteModule.importedModules;
|
|
656
|
+
}
|
|
657
|
+
collectJs(asset, urls, visited) {
|
|
658
|
+
if (!asset) {
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
if (!asset.moduleId) {
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
if (visited.has(asset.moduleId)) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
visited.add(asset.moduleId);
|
|
668
|
+
const parts = path4.parse(asset.assetUrl);
|
|
669
|
+
if ([".js", ".jsx", ".ts", ".tsx"].includes(parts.ext) && asset.moduleId.includes("/elements/")) {
|
|
670
|
+
urls.add(asset.assetUrl);
|
|
671
|
+
}
|
|
672
|
+
asset.getImportedModules().forEach((viteModule) => {
|
|
673
|
+
if (viteModule.file) {
|
|
674
|
+
const src = this.assetMap.filePathToSrc(viteModule.file);
|
|
675
|
+
const importedAsset = new DevServerAsset(src, {
|
|
676
|
+
assetMap: this.assetMap,
|
|
677
|
+
viteModule
|
|
678
|
+
});
|
|
679
|
+
this.collectJs(importedAsset, urls, visited);
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
collectCss(asset, urls, visited) {
|
|
684
|
+
if (!asset) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (!asset.assetUrl) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
if (visited.has(asset.assetUrl)) {
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
visited.add(asset.assetUrl);
|
|
694
|
+
if (asset.src.endsWith(".scss")) {
|
|
695
|
+
const parts = path4.parse(asset.src);
|
|
696
|
+
if (!parts.name.startsWith("_")) {
|
|
697
|
+
urls.add(asset.assetUrl);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
asset.getImportedModules().forEach((viteModule) => {
|
|
701
|
+
if (viteModule.file) {
|
|
702
|
+
const src = this.assetMap.filePathToSrc(viteModule.file);
|
|
703
|
+
const importedAsset = new DevServerAsset(src, {
|
|
704
|
+
assetMap: this.assetMap,
|
|
705
|
+
viteModule
|
|
706
|
+
});
|
|
707
|
+
this.collectCss(importedAsset, urls, visited);
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
// src/cli/commands/dev.ts
|
|
714
|
+
import { dim as dim2 } from "kleur/colors";
|
|
715
|
+
|
|
716
|
+
// src/core/middleware.ts
|
|
717
|
+
function rootProjectMiddleware(options) {
|
|
718
|
+
return (req, _, next) => {
|
|
719
|
+
req.rootConfig = options.rootConfig;
|
|
720
|
+
next();
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// src/utils/ports.ts
|
|
725
|
+
import { createServer } from "node:net";
|
|
726
|
+
function isPortOpen(port) {
|
|
727
|
+
return new Promise((resolve, reject) => {
|
|
728
|
+
const server = createServer();
|
|
729
|
+
server.on("error", (err) => {
|
|
730
|
+
if (err.code === "EADDRINUSE") {
|
|
731
|
+
resolve(false);
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
reject(err);
|
|
735
|
+
});
|
|
736
|
+
server.on("close", () => {
|
|
737
|
+
resolve(true);
|
|
738
|
+
});
|
|
739
|
+
server.listen(port, () => {
|
|
740
|
+
server.close((err) => {
|
|
741
|
+
if (err) {
|
|
742
|
+
console.log(`error closing server: ${err}`);
|
|
743
|
+
reject(err);
|
|
744
|
+
}
|
|
760
745
|
});
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
Object.keys(routesManifest).forEach((manifestKey) => {
|
|
764
|
-
const asset = routesManifest[manifestKey];
|
|
765
|
-
if (asset.isEntry) {
|
|
766
|
-
const visited = /* @__PURE__ */ new Set();
|
|
767
|
-
const cssDeps = /* @__PURE__ */ new Set();
|
|
768
|
-
collectRouteCss(asset, cssDeps, visited);
|
|
769
|
-
asset.css = Array.from(cssDeps);
|
|
770
|
-
asset.imports = [];
|
|
771
|
-
clientManifest[manifestKey] = asset;
|
|
772
|
-
} else if (asset.file.endsWith(".css")) {
|
|
773
|
-
clientManifest[manifestKey] = asset;
|
|
774
|
-
}
|
|
746
|
+
});
|
|
775
747
|
});
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
);
|
|
786
|
-
const buildDir = path5.join(distDir, "html");
|
|
787
|
-
const publicDir = path5.join(rootDir, "public");
|
|
788
|
-
if (fsExtra.existsSync(path5.join(rootDir, "public"))) {
|
|
789
|
-
fsExtra.copySync(publicDir, buildDir, { dereference: true });
|
|
790
|
-
} else {
|
|
791
|
-
makeDir(buildDir);
|
|
748
|
+
}
|
|
749
|
+
async function findOpenPort(min, max) {
|
|
750
|
+
let port = min;
|
|
751
|
+
while (port <= max) {
|
|
752
|
+
const isOpen = await isPortOpen(port);
|
|
753
|
+
if (isOpen) {
|
|
754
|
+
return port;
|
|
755
|
+
}
|
|
756
|
+
port += 1;
|
|
792
757
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
758
|
+
throw new Error(`no ports open between ${min} and ${max}`);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// src/cli/commands/dev.ts
|
|
762
|
+
import glob3 from "tiny-glob";
|
|
763
|
+
var __dirname2 = path5.dirname(fileURLToPath2(import.meta.url));
|
|
764
|
+
async function dev(rootProjectDir, options) {
|
|
765
|
+
process.env.NODE_ENV = "development";
|
|
766
|
+
const rootDir = path5.resolve(rootProjectDir || process.cwd());
|
|
767
|
+
const defaultPort = parseInt(process.env.PORT || "4007");
|
|
768
|
+
const host = (options == null ? void 0 : options.host) || "localhost";
|
|
769
|
+
const port = await findOpenPort(defaultPort, defaultPort + 10);
|
|
770
|
+
console.log();
|
|
771
|
+
console.log(`${dim2("\u2503")} project: ${rootDir}`);
|
|
772
|
+
console.log(`${dim2("\u2503")} server: http://${host}:${port}`);
|
|
773
|
+
console.log(`${dim2("\u2503")} mode: development`);
|
|
774
|
+
console.log();
|
|
775
|
+
const server = await createDevServer({ rootDir, port });
|
|
776
|
+
server.listen(port, host);
|
|
777
|
+
}
|
|
778
|
+
async function createDevServer(options) {
|
|
779
|
+
const rootDir = path5.resolve((options == null ? void 0 : options.rootDir) || process.cwd());
|
|
780
|
+
const rootConfig = await loadRootConfig(rootDir, { command: "dev" });
|
|
781
|
+
const port = options == null ? void 0 : options.port;
|
|
782
|
+
const server = express();
|
|
783
|
+
server.disable("x-powered-by");
|
|
784
|
+
server.use(rootProjectMiddleware({ rootConfig }));
|
|
785
|
+
server.use(await viteServerMiddleware({ rootConfig, port }));
|
|
786
|
+
const plugins = rootConfig.plugins || [];
|
|
787
|
+
await configureServerPlugins(
|
|
788
|
+
server,
|
|
789
|
+
async () => {
|
|
790
|
+
var _a;
|
|
791
|
+
const userMiddlewares = ((_a = rootConfig.server) == null ? void 0 : _a.middlewares) || [];
|
|
792
|
+
for (const middleware of userMiddlewares) {
|
|
793
|
+
server.use(middleware);
|
|
808
794
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
795
|
+
server.use(rootDevServerMiddleware());
|
|
796
|
+
server.use(rootDevServer404Middleware());
|
|
797
|
+
server.use(rootDevServer500Middleware());
|
|
798
|
+
},
|
|
799
|
+
plugins,
|
|
800
|
+
{ type: "dev", rootConfig }
|
|
812
801
|
);
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
const outPath = path5.join(buildDir, outFilePath);
|
|
832
|
-
let html = data.html || "";
|
|
833
|
-
if (rootConfig.prettyHtml !== false) {
|
|
834
|
-
html = await htmlPretty(html, rootConfig.prettyHtmlOptions);
|
|
835
|
-
}
|
|
836
|
-
if (rootConfig.minifyHtml !== false) {
|
|
837
|
-
html = await htmlMinify(html, rootConfig.minifyHtmlOptions);
|
|
838
|
-
}
|
|
839
|
-
await writeFile(outPath, html);
|
|
840
|
-
printFileOutput(fileSize(outPath), "dist/html/", outFilePath);
|
|
841
|
-
})
|
|
842
|
-
);
|
|
802
|
+
return server;
|
|
803
|
+
}
|
|
804
|
+
async function viteServerMiddleware(options) {
|
|
805
|
+
const rootConfig = options.rootConfig;
|
|
806
|
+
const rootDir = rootConfig.rootDir;
|
|
807
|
+
const elementGraph = await getElements(rootConfig);
|
|
808
|
+
const elements = Object.values(elementGraph.sourceFiles).map((sourceFile) => {
|
|
809
|
+
return sourceFile.relPath;
|
|
810
|
+
});
|
|
811
|
+
const bundleScripts = [];
|
|
812
|
+
if (await isDirectory(path5.join(rootDir, "bundles"))) {
|
|
813
|
+
const bundleFiles = await glob3("bundles/*", { cwd: rootDir });
|
|
814
|
+
bundleFiles.forEach((file) => {
|
|
815
|
+
const parts = path5.parse(file);
|
|
816
|
+
if (isJsFile(parts.base)) {
|
|
817
|
+
bundleScripts.push(file);
|
|
818
|
+
}
|
|
819
|
+
});
|
|
843
820
|
}
|
|
821
|
+
const optimizeDeps = [...elements, ...bundleScripts];
|
|
822
|
+
const viteServer = await createViteServer(rootConfig, {
|
|
823
|
+
port: options.port,
|
|
824
|
+
optimizeDeps
|
|
825
|
+
});
|
|
826
|
+
return async (req, res, next) => {
|
|
827
|
+
try {
|
|
828
|
+
req.viteServer = viteServer;
|
|
829
|
+
const renderModulePath = path5.resolve(__dirname2, "./render.js");
|
|
830
|
+
const render = await viteServer.ssrLoadModule(
|
|
831
|
+
renderModulePath
|
|
832
|
+
);
|
|
833
|
+
const assetMap = new DevServerAssetMap(
|
|
834
|
+
rootConfig,
|
|
835
|
+
viteServer.moduleGraph
|
|
836
|
+
);
|
|
837
|
+
req.renderer = new render.Renderer(rootConfig, { assetMap, elementGraph });
|
|
838
|
+
viteServer.middlewares(req, res, next);
|
|
839
|
+
} catch (e) {
|
|
840
|
+
next(e);
|
|
841
|
+
}
|
|
842
|
+
};
|
|
844
843
|
}
|
|
845
|
-
function
|
|
846
|
-
return
|
|
844
|
+
function rootDevServerMiddleware() {
|
|
845
|
+
return async (req, res, next) => {
|
|
846
|
+
const renderer = req.renderer;
|
|
847
|
+
const viteServer = req.viteServer;
|
|
848
|
+
try {
|
|
849
|
+
await renderer.handle(req, res, next);
|
|
850
|
+
} catch (err) {
|
|
851
|
+
viteServer.ssrFixStacktrace(err);
|
|
852
|
+
next(err);
|
|
853
|
+
}
|
|
854
|
+
};
|
|
847
855
|
}
|
|
848
|
-
function
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
856
|
+
function rootDevServer404Middleware() {
|
|
857
|
+
return async (req, res) => {
|
|
858
|
+
console.error(`\u2753 404 ${req.originalUrl}`);
|
|
859
|
+
if (req.renderer) {
|
|
860
|
+
const url = req.path;
|
|
861
|
+
const ext = path5.extname(url);
|
|
862
|
+
if (!ext) {
|
|
863
|
+
const renderer = req.renderer;
|
|
864
|
+
const data = await renderer.renderDevServer404(req);
|
|
865
|
+
const html = data.html || "";
|
|
866
|
+
res.status(404).set({ "Content-Type": "text/html" }).end(html);
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
res.status(404).set({ "Content-Type": "text/plain" }).end("404");
|
|
871
|
+
};
|
|
858
872
|
}
|
|
859
|
-
function
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
873
|
+
function rootDevServer500Middleware() {
|
|
874
|
+
return async (err, req, res, next) => {
|
|
875
|
+
console.error(`\u2757 500 ${req.originalUrl}`);
|
|
876
|
+
console.error(String(err.stack || err));
|
|
877
|
+
if (req.renderer) {
|
|
878
|
+
const url = req.path;
|
|
879
|
+
const ext = path5.extname(url);
|
|
880
|
+
if (!ext) {
|
|
881
|
+
const renderer = req.renderer;
|
|
882
|
+
const data = await renderer.renderDevServer500(req, err);
|
|
883
|
+
const html = data.html || "";
|
|
884
|
+
res.status(500).set({ "Content-Type": "text/html" }).end(html);
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
next(err);
|
|
889
|
+
};
|
|
865
890
|
}
|
|
866
891
|
|
|
867
892
|
// src/cli/commands/preview.ts
|
|
@@ -870,19 +895,20 @@ import { default as express2 } from "express";
|
|
|
870
895
|
import { dim as dim3 } from "kleur/colors";
|
|
871
896
|
import sirv from "sirv";
|
|
872
897
|
import compression from "compression";
|
|
873
|
-
async function preview(rootProjectDir) {
|
|
898
|
+
async function preview(rootProjectDir, options) {
|
|
874
899
|
process.env.NODE_ENV = "development";
|
|
875
900
|
const rootDir = path6.resolve(rootProjectDir || process.cwd());
|
|
876
|
-
const server = await
|
|
901
|
+
const server = await createPreviewServer({ rootDir });
|
|
877
902
|
const port = parseInt(process.env.PORT || "4007");
|
|
903
|
+
const host = (options == null ? void 0 : options.host) || "localhost";
|
|
878
904
|
console.log();
|
|
879
905
|
console.log(`${dim3("\u2503")} project: ${rootDir}`);
|
|
880
|
-
console.log(`${dim3("\u2503")} server: http
|
|
906
|
+
console.log(`${dim3("\u2503")} server: http://${host}:${port}`);
|
|
881
907
|
console.log(`${dim3("\u2503")} mode: preview`);
|
|
882
908
|
console.log();
|
|
883
|
-
server.listen(port);
|
|
909
|
+
server.listen(port, host);
|
|
884
910
|
}
|
|
885
|
-
async function
|
|
911
|
+
async function createPreviewServer(options) {
|
|
886
912
|
const rootDir = options.rootDir;
|
|
887
913
|
const rootConfig = await loadRootConfig(rootDir, { command: "preview" });
|
|
888
914
|
const distDir = path6.join(rootDir, "dist");
|
|
@@ -920,9 +946,19 @@ async function rootPreviewRendererMiddleware(options) {
|
|
|
920
946
|
`could not find ${manifestPath}. run \`root build\` before \`root preview\`.`
|
|
921
947
|
);
|
|
922
948
|
}
|
|
949
|
+
const elementGraphJsonPath = path6.join(
|
|
950
|
+
distDir,
|
|
951
|
+
"client/root-element-graph.json"
|
|
952
|
+
);
|
|
953
|
+
if (!await fileExists(elementGraphJsonPath)) {
|
|
954
|
+
throw new Error(
|
|
955
|
+
`could not find ${elementGraphJsonPath}. run \`root build\` before \`root start\`.`
|
|
956
|
+
);
|
|
957
|
+
}
|
|
923
958
|
const rootManifest = await loadJson(manifestPath);
|
|
924
959
|
const assetMap = BuildAssetMap.fromRootManifest(rootConfig, rootManifest);
|
|
925
|
-
const
|
|
960
|
+
const elementGraphJson = await loadJson(elementGraphJsonPath);
|
|
961
|
+
const elementGraph = ElementGraph.fromJson(elementGraphJson);
|
|
926
962
|
const renderer = new render.Renderer(rootConfig, { assetMap, elementGraph });
|
|
927
963
|
return async (req, _, next) => {
|
|
928
964
|
req.renderer = renderer;
|
|
@@ -984,19 +1020,20 @@ import { default as express3 } from "express";
|
|
|
984
1020
|
import { dim as dim4 } from "kleur/colors";
|
|
985
1021
|
import sirv2 from "sirv";
|
|
986
1022
|
import compression2 from "compression";
|
|
987
|
-
async function start(rootProjectDir) {
|
|
1023
|
+
async function start(rootProjectDir, options) {
|
|
988
1024
|
process.env.NODE_ENV = "production";
|
|
989
1025
|
const rootDir = path7.resolve(rootProjectDir || process.cwd());
|
|
990
|
-
const server = await
|
|
1026
|
+
const server = await createProdServer({ rootDir });
|
|
991
1027
|
const port = parseInt(process.env.PORT || "4007");
|
|
1028
|
+
const host = (options == null ? void 0 : options.host) || "localhost";
|
|
992
1029
|
console.log();
|
|
993
1030
|
console.log(`${dim4("\u2503")} project: ${rootDir}`);
|
|
994
|
-
console.log(`${dim4("\u2503")} server: http
|
|
1031
|
+
console.log(`${dim4("\u2503")} server: http://${host}:${port}`);
|
|
995
1032
|
console.log(`${dim4("\u2503")} mode: production`);
|
|
996
1033
|
console.log();
|
|
997
|
-
server.listen(port);
|
|
1034
|
+
server.listen(port, host);
|
|
998
1035
|
}
|
|
999
|
-
async function
|
|
1036
|
+
async function createProdServer(options) {
|
|
1000
1037
|
const rootDir = options.rootDir;
|
|
1001
1038
|
const rootConfig = await loadRootConfig(rootDir, { command: "start" });
|
|
1002
1039
|
const distDir = path7.join(rootDir, "dist");
|
|
@@ -1034,9 +1071,19 @@ async function rootProdRendererMiddleware(options) {
|
|
|
1034
1071
|
`could not find ${manifestPath}. run \`root build\` before \`root start\`.`
|
|
1035
1072
|
);
|
|
1036
1073
|
}
|
|
1074
|
+
const elementGraphJsonPath = path7.join(
|
|
1075
|
+
distDir,
|
|
1076
|
+
"client/root-element-graph.json"
|
|
1077
|
+
);
|
|
1078
|
+
if (!await fileExists(elementGraphJsonPath)) {
|
|
1079
|
+
throw new Error(
|
|
1080
|
+
`could not find ${elementGraphJsonPath}. run \`root build\` before \`root start\`.`
|
|
1081
|
+
);
|
|
1082
|
+
}
|
|
1037
1083
|
const rootManifest = await loadJson(manifestPath);
|
|
1038
1084
|
const assetMap = BuildAssetMap.fromRootManifest(rootConfig, rootManifest);
|
|
1039
|
-
const
|
|
1085
|
+
const elementGraphJson = await loadJson(elementGraphJsonPath);
|
|
1086
|
+
const elementGraph = ElementGraph.fromJson(elementGraphJson);
|
|
1040
1087
|
const renderer = new render.Renderer(rootConfig, { assetMap, elementGraph });
|
|
1041
1088
|
return async (req, _, next) => {
|
|
1042
1089
|
req.renderer = renderer;
|
|
@@ -1097,6 +1144,9 @@ function rootProdServer500Middleware() {
|
|
|
1097
1144
|
}
|
|
1098
1145
|
export {
|
|
1099
1146
|
build,
|
|
1147
|
+
createDevServer,
|
|
1148
|
+
createPreviewServer,
|
|
1149
|
+
createProdServer,
|
|
1100
1150
|
dev,
|
|
1101
1151
|
preview,
|
|
1102
1152
|
start
|