gofront 1.2.3 → 1.3.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.
- package/package.json +6 -4
- package/src/cli-core.js +520 -15
- package/src/codegen/expressions.js +229 -30
- package/src/codegen/index.js +38 -20
- package/src/codegen/runtime.js +14 -2
- package/src/codegen/statements.js +95 -15
- package/src/codegen/stdlib/builder.js +2 -2
- package/src/codegen/stdlib/bytes.js +1 -1
- package/src/codegen/stdlib/fmt.js +3 -4
- package/src/codegen/stdlib/io.js +1 -2
- package/src/codegen/templ.js +1 -1
- package/src/dev-server.js +279 -83
- package/src/index.js +87 -16
- package/src/parser/expressions.js +11 -0
- package/src/pwa.js +138 -0
- package/src/typechecker/assignability.js +61 -8
- package/src/typechecker/resolve.js +37 -3
- package/src/typechecker/stdlib/core.js +16 -13
- package/src/typechecker/stdlib/extended.js +11 -2
- package/src/typechecker/stdlib/web.js +418 -0
- package/src/typechecker/stdlib.js +2 -0
- package/src/typechecker/types.js +78 -17
- package/src/vendor.js +158 -43
package/src/vendor.js
CHANGED
|
@@ -59,12 +59,13 @@ ${exports.join(",\n")}
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
export function findBundler(projectDir) {
|
|
62
|
-
const
|
|
62
|
+
const root = resolve(projectDir);
|
|
63
|
+
const pkgPath = join(root, "package.json");
|
|
63
64
|
let req;
|
|
64
65
|
if (existsSync(pkgPath)) {
|
|
65
66
|
req = createRequire(pkgPath);
|
|
66
67
|
} else {
|
|
67
|
-
req = createRequire(join(
|
|
68
|
+
req = createRequire(join(root, "dummy.js"));
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
try {
|
|
@@ -162,47 +163,135 @@ export function resolveDestinationPaths(projectRoot, dest) {
|
|
|
162
163
|
});
|
|
163
164
|
}
|
|
164
165
|
|
|
165
|
-
|
|
166
|
+
export const NODE_BUILTINS = [
|
|
167
|
+
"buffer",
|
|
168
|
+
"events",
|
|
169
|
+
"path",
|
|
170
|
+
"util",
|
|
171
|
+
"process",
|
|
172
|
+
"stream",
|
|
173
|
+
"crypto",
|
|
174
|
+
"fs",
|
|
175
|
+
"os",
|
|
176
|
+
"http",
|
|
177
|
+
"https",
|
|
178
|
+
"net",
|
|
179
|
+
"tls",
|
|
180
|
+
"zlib",
|
|
181
|
+
"url",
|
|
182
|
+
"assert",
|
|
183
|
+
"child_process",
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
export const NODE_POLYFILLS_TIP =
|
|
187
|
+
"gofront: tip: npm package requires Node built-ins. Install @rolldown/plugin-node-polyfills:\n npm install --save-dev @rolldown/plugin-node-polyfills";
|
|
188
|
+
|
|
189
|
+
export function isNodeBuiltinError(errorMsg) {
|
|
190
|
+
if (typeof errorMsg !== "string") return false;
|
|
191
|
+
const lower = errorMsg.toLowerCase();
|
|
192
|
+
return NODE_BUILTINS.some(
|
|
193
|
+
(mod) =>
|
|
194
|
+
lower.includes(`"${mod}"`) ||
|
|
195
|
+
lower.includes(`'${mod}'`) ||
|
|
196
|
+
lower.includes(`node:${mod}`) ||
|
|
197
|
+
lower.includes(`module '${mod}'`) ||
|
|
198
|
+
lower.includes(`resolve "${mod}"`) ||
|
|
199
|
+
lower.includes(`resolve '${mod}'`),
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function findNodePolyfills(projectDir) {
|
|
204
|
+
const root = resolve(projectDir);
|
|
205
|
+
const pkgPath = join(root, "package.json");
|
|
206
|
+
let req;
|
|
207
|
+
if (existsSync(pkgPath)) {
|
|
208
|
+
req = createRequire(pkgPath);
|
|
209
|
+
} else {
|
|
210
|
+
req = createRequire(join(root, "dummy.js"));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
const path = req.resolve("@rolldown/plugin-node-polyfills");
|
|
215
|
+
return { name: "node-polyfills", path };
|
|
216
|
+
} catch {}
|
|
217
|
+
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export async function loadNodePolyfillsPlugin(projectRoot, customPlugin) {
|
|
222
|
+
if (customPlugin !== undefined) {
|
|
223
|
+
if (customPlugin === null) return null;
|
|
224
|
+
return typeof customPlugin === "function" ? customPlugin() : customPlugin;
|
|
225
|
+
}
|
|
226
|
+
const info = findNodePolyfills(projectRoot);
|
|
227
|
+
if (!info) return null;
|
|
228
|
+
try {
|
|
229
|
+
const mod = await import(pathToFileURL(info.path).href);
|
|
230
|
+
const fn =
|
|
231
|
+
mod.nodePolyfills || mod.default?.nodePolyfills || mod.default || mod;
|
|
232
|
+
return typeof fn === "function" ? fn() : mod;
|
|
233
|
+
} catch {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function bundleWithRolldown(
|
|
239
|
+
bundlerInfo,
|
|
240
|
+
{ projectRoot, entryFile, destPath, minify, nodePolyfillsPlugin },
|
|
241
|
+
) {
|
|
242
|
+
const rolldownModule =
|
|
243
|
+
bundlerInfo.instance ??
|
|
244
|
+
(await import(pathToFileURL(bundlerInfo.path).href));
|
|
245
|
+
const rolldownFn =
|
|
246
|
+
rolldownModule.rolldown ||
|
|
247
|
+
rolldownModule.default?.rolldown ||
|
|
248
|
+
rolldownModule.default;
|
|
249
|
+
|
|
250
|
+
const plugins = [];
|
|
251
|
+
if (nodePolyfillsPlugin) {
|
|
252
|
+
plugins.push(nodePolyfillsPlugin);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const bundle = await rolldownFn({
|
|
256
|
+
input: entryFile,
|
|
257
|
+
cwd: projectRoot,
|
|
258
|
+
plugins,
|
|
259
|
+
});
|
|
260
|
+
await bundle.write({
|
|
261
|
+
file: destPath,
|
|
262
|
+
format: "esm",
|
|
263
|
+
minify: Boolean(minify),
|
|
264
|
+
});
|
|
265
|
+
await bundle.close();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async function bundleWithEsbuild(
|
|
166
269
|
bundlerInfo,
|
|
167
270
|
{ projectRoot, entryFile, destPath, minify },
|
|
168
271
|
) {
|
|
272
|
+
const esbuildModule =
|
|
273
|
+
bundlerInfo.instance ??
|
|
274
|
+
(await import(pathToFileURL(bundlerInfo.path).href));
|
|
275
|
+
const buildFn =
|
|
276
|
+
esbuildModule.build || esbuildModule.default?.build || esbuildModule;
|
|
277
|
+
|
|
278
|
+
await buildFn({
|
|
279
|
+
entryPoints: [entryFile],
|
|
280
|
+
bundle: true,
|
|
281
|
+
format: "esm",
|
|
282
|
+
outfile: destPath,
|
|
283
|
+
absWorkingDir: projectRoot,
|
|
284
|
+
minify: Boolean(minify),
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async function runBundler(bundlerInfo, options) {
|
|
169
289
|
if (bundlerInfo.name === "rolldown") {
|
|
170
|
-
|
|
171
|
-
bundlerInfo.instance ??
|
|
172
|
-
(await import(pathToFileURL(bundlerInfo.path).href));
|
|
173
|
-
const rolldownFn =
|
|
174
|
-
rolldownModule.rolldown ||
|
|
175
|
-
rolldownModule.default?.rolldown ||
|
|
176
|
-
rolldownModule.default;
|
|
177
|
-
|
|
178
|
-
const bundle = await rolldownFn({
|
|
179
|
-
input: entryFile,
|
|
180
|
-
cwd: projectRoot,
|
|
181
|
-
});
|
|
182
|
-
await bundle.write({
|
|
183
|
-
file: destPath,
|
|
184
|
-
format: "esm",
|
|
185
|
-
minify: Boolean(minify),
|
|
186
|
-
});
|
|
187
|
-
await bundle.close();
|
|
290
|
+
await bundleWithRolldown(bundlerInfo, options);
|
|
188
291
|
return;
|
|
189
292
|
}
|
|
190
|
-
|
|
191
293
|
if (bundlerInfo.name === "esbuild") {
|
|
192
|
-
|
|
193
|
-
bundlerInfo.instance ??
|
|
194
|
-
(await import(pathToFileURL(bundlerInfo.path).href));
|
|
195
|
-
const buildFn =
|
|
196
|
-
esbuildModule.build || esbuildModule.default?.build || esbuildModule;
|
|
197
|
-
|
|
198
|
-
await buildFn({
|
|
199
|
-
entryPoints: [entryFile],
|
|
200
|
-
bundle: true,
|
|
201
|
-
format: "esm",
|
|
202
|
-
outfile: destPath,
|
|
203
|
-
absWorkingDir: projectRoot,
|
|
204
|
-
minify: Boolean(minify),
|
|
205
|
-
});
|
|
294
|
+
await bundleWithEsbuild(bundlerInfo, options);
|
|
206
295
|
}
|
|
207
296
|
}
|
|
208
297
|
|
|
@@ -227,8 +316,9 @@ export async function bundleVendor(projectDir = ".", options = {}) {
|
|
|
227
316
|
|
|
228
317
|
const destPaths = resolveDestinationPaths(projectRoot, dest);
|
|
229
318
|
const bundlerInfo = options.bundler ?? findBundler(projectRoot);
|
|
319
|
+
const warn = options.logger?.warn ?? console.warn;
|
|
230
320
|
if (!bundlerInfo) {
|
|
231
|
-
|
|
321
|
+
warn(
|
|
232
322
|
"gofront: no bundler found (rolldown or esbuild). Run 'npm install --save-dev rolldown' to enable vendor bundling.",
|
|
233
323
|
);
|
|
234
324
|
return {
|
|
@@ -245,18 +335,36 @@ export async function bundleVendor(projectDir = ".", options = {}) {
|
|
|
245
335
|
mkdirSync(dirname(p), { recursive: true });
|
|
246
336
|
}
|
|
247
337
|
|
|
338
|
+
const customPlugin =
|
|
339
|
+
options.nodePolyfillsPlugin ??
|
|
340
|
+
bundlerInfo.nodePolyfillsPlugin ??
|
|
341
|
+
(options.nodePolyfills === false ? null : undefined);
|
|
342
|
+
const polyfillPlugin = await loadNodePolyfillsPlugin(
|
|
343
|
+
projectRoot,
|
|
344
|
+
customPlugin,
|
|
345
|
+
);
|
|
346
|
+
|
|
248
347
|
if (typeof bundlerInfo.bundle === "function") {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
348
|
+
try {
|
|
349
|
+
await bundlerInfo.bundle({
|
|
350
|
+
projectRoot,
|
|
351
|
+
packages,
|
|
352
|
+
dest: destPaths.length === 1 ? destPaths[0] : destPaths,
|
|
353
|
+
minify: Boolean(minify),
|
|
354
|
+
nodePolyfillsPlugin: polyfillPlugin,
|
|
355
|
+
});
|
|
356
|
+
} catch (err) {
|
|
357
|
+
if (!polyfillPlugin && isNodeBuiltinError(err.message)) {
|
|
358
|
+
warn(NODE_POLYFILLS_TIP);
|
|
359
|
+
}
|
|
360
|
+
throw err;
|
|
361
|
+
}
|
|
255
362
|
return {
|
|
256
363
|
bundled: packages,
|
|
257
364
|
bundler: bundlerInfo.name ?? "custom",
|
|
258
365
|
dest,
|
|
259
366
|
minify: Boolean(minify),
|
|
367
|
+
nodePolyfills: Boolean(polyfillPlugin),
|
|
260
368
|
};
|
|
261
369
|
}
|
|
262
370
|
|
|
@@ -273,11 +381,17 @@ export async function bundleVendor(projectDir = ".", options = {}) {
|
|
|
273
381
|
entryFile,
|
|
274
382
|
destPath: destPaths[0],
|
|
275
383
|
minify,
|
|
384
|
+
nodePolyfillsPlugin: polyfillPlugin,
|
|
276
385
|
});
|
|
277
386
|
|
|
278
387
|
for (let i = 1; i < destPaths.length; i++) {
|
|
279
388
|
copyFileSync(destPaths[0], destPaths[i]);
|
|
280
389
|
}
|
|
390
|
+
} catch (err) {
|
|
391
|
+
if (!polyfillPlugin && isNodeBuiltinError(err.message)) {
|
|
392
|
+
warn(NODE_POLYFILLS_TIP);
|
|
393
|
+
}
|
|
394
|
+
throw err;
|
|
281
395
|
} finally {
|
|
282
396
|
if (existsSync(entryFile)) {
|
|
283
397
|
rmSync(entryFile, { force: true });
|
|
@@ -289,5 +403,6 @@ export async function bundleVendor(projectDir = ".", options = {}) {
|
|
|
289
403
|
bundler: bundlerInfo.name,
|
|
290
404
|
dest,
|
|
291
405
|
minify: Boolean(minify),
|
|
406
|
+
nodePolyfills: Boolean(polyfillPlugin),
|
|
292
407
|
};
|
|
293
408
|
}
|