@velarscript/cli 0.14.9 → 0.16.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/README.md +9 -0
- package/dist/cli.js +193 -62
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -1
- package/dist/config.js.map +1 -1
- package/dist/javascript-output.d.ts +34 -0
- package/dist/javascript-output.d.ts.map +1 -0
- package/dist/javascript-output.js +44 -0
- package/dist/javascript-output.js.map +1 -0
- package/dist/language-server.d.ts.map +1 -1
- package/dist/language-server.js +11 -0
- package/dist/language-server.js.map +1 -1
- package/dist/library-artifact-build.d.ts +2 -1
- package/dist/library-artifact-build.d.ts.map +1 -1
- package/dist/library-artifact-build.js +21 -6
- package/dist/library-artifact-build.js.map +1 -1
- package/dist/node-application.js +2 -2
- package/dist/node-application.js.map +1 -1
- package/dist/production-build.d.ts +5 -2
- package/dist/production-build.d.ts.map +1 -1
- package/dist/production-build.js +18 -14
- package/dist/production-build.js.map +1 -1
- package/dist/production-verifier.d.ts.map +1 -1
- package/dist/production-verifier.js +4 -1
- package/dist/production-verifier.js.map +1 -1
- package/dist/project-check.d.ts +3 -1
- package/dist/project-check.d.ts.map +1 -1
- package/dist/project-check.js +3 -1
- package/dist/project-check.js.map +1 -1
- package/dist/project-format.d.ts +1 -1
- package/dist/project-format.d.ts.map +1 -1
- package/dist/project-format.js +1 -0
- package/dist/project-format.js.map +1 -1
- package/dist/project-semantic.d.ts.map +1 -1
- package/dist/project-semantic.js +6 -0
- package/dist/project-semantic.js.map +1 -1
- package/dist/project.d.ts +7 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +11 -0
- package/dist/project.js.map +1 -1
- package/dist/resource-output.d.ts +2 -1
- package/dist/resource-output.d.ts.map +1 -1
- package/dist/resource-output.js +13 -2
- package/dist/resource-output.js.map +1 -1
- package/dist/standalone-build.d.ts +2 -1
- package/dist/standalone-build.d.ts.map +1 -1
- package/dist/standalone-build.js +11 -8
- package/dist/standalone-build.js.map +1 -1
- package/dist/test-output.d.ts +1 -1
- package/dist/test-output.d.ts.map +1 -1
- package/dist/test-output.js +10 -5
- package/dist/test-output.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -8
- package/skill/ai-skill-node.md +7 -6
- package/skill/ai-skill-server.md +3 -3
- package/skill/ai-skill-web.md +5 -4
- package/skill/ai-skill.md +7 -5
package/README.md
CHANGED
|
@@ -37,6 +37,15 @@ runtime behavior, and `velar build` writes a standalone Node directory with a
|
|
|
37
37
|
launcher and copied public assets. Web/Desktop development continues through
|
|
38
38
|
their framework hosts; `velar run` remains for framework-free CLI programs.
|
|
39
39
|
|
|
40
|
+
`velar build` defaults to optimized `production` JavaScript for every target.
|
|
41
|
+
Select `--mode readable` for one inspectable build, or set top-level
|
|
42
|
+
`"build": {"mode": "readable"}` in `velar.json`; the command-line value
|
|
43
|
+
overrides the project setting for that invocation.
|
|
44
|
+
|
|
45
|
+
Source Map is configured independently. Formal builds default to no maps;
|
|
46
|
+
set top-level `"build": {"sourceMaps": true}` or pass `--source-maps` to
|
|
47
|
+
retain them. Development and test runs keep mappings enabled for diagnostics.
|
|
48
|
+
|
|
40
49
|
Project creation delegates to the exact matching `create-velar` package, the
|
|
41
50
|
same implementation used by `npm create velar@latest`. First-class application
|
|
42
51
|
templates are `web`, `node`, and `desktop`; `docs`, `library`, and `component`
|
package/dist/cli.js
CHANGED
|
@@ -41,6 +41,32 @@ import { writeServerConfigurationDependency, writeWebSocketDependency } from "./
|
|
|
41
41
|
import { assertUniqueEmbeddedModuleOutputs, embeddedModuleFileContents, embeddedModuleOutputPath, VELAR_EMBEDDED_MODULE_MARKER, } from "./embedded-modules.js";
|
|
42
42
|
import { resourceOutputRelativePath, writeBuildResourcePackageManifests, writeProjectResources } from "./resource-output.js";
|
|
43
43
|
import { resolveVelarLibraryBuild, writeVelarLibraryArtifact } from "./library-artifact-build.js";
|
|
44
|
+
import { renderJavaScriptOutput } from "./javascript-output.js";
|
|
45
|
+
// esbuild 转换和文件写入都可并行,但无界 Promise.all 会让大型项目同时保留
|
|
46
|
+
// 全部模块源码、映射和压缩结果。固定四个 worker 在吞吐与峰值内存之间给出
|
|
47
|
+
// 稳定上界;输出路径彼此独立,完成顺序不影响产物。
|
|
48
|
+
const BUILD_OUTPUT_CONCURRENCY = 4;
|
|
49
|
+
async function mapBuildOutputs(items, operation) {
|
|
50
|
+
let next = 0;
|
|
51
|
+
let failure = null;
|
|
52
|
+
const worker = async () => {
|
|
53
|
+
while (failure === null) {
|
|
54
|
+
const index = next;
|
|
55
|
+
if (index >= items.length)
|
|
56
|
+
return;
|
|
57
|
+
next += 1;
|
|
58
|
+
try {
|
|
59
|
+
await operation(items[index]);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
failure = error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
await Promise.all(Array.from({ length: Math.min(BUILD_OUTPUT_CONCURRENCY, items.length) }, worker));
|
|
67
|
+
if (failure !== null)
|
|
68
|
+
throw failure;
|
|
69
|
+
}
|
|
44
70
|
async function main(arguments_) {
|
|
45
71
|
const [command, ...rest] = arguments_;
|
|
46
72
|
if (!command || command === "--help" || command === "-h") {
|
|
@@ -305,21 +331,21 @@ async function main(arguments_) {
|
|
|
305
331
|
}
|
|
306
332
|
}
|
|
307
333
|
if (command === "build-library") {
|
|
308
|
-
const
|
|
309
|
-
if (
|
|
310
|
-
process.stderr.write(`velar build-library: ${
|
|
334
|
+
const parsed = parseBuildLibraryArguments(rest);
|
|
335
|
+
if (typeof parsed === "string") {
|
|
336
|
+
process.stderr.write(`velar build-library: ${parsed}\n`);
|
|
311
337
|
return 2;
|
|
312
338
|
}
|
|
313
339
|
let staging = null;
|
|
314
340
|
try {
|
|
315
|
-
const config = await resolveVelarProject(input);
|
|
341
|
+
const config = await resolveVelarProject(parsed.input);
|
|
316
342
|
const library = await resolveVelarLibraryBuild(config);
|
|
317
|
-
const checked = await checkResolvedProject(library.project, input ?? library.project.root);
|
|
343
|
+
const checked = await checkResolvedProject(library.project, parsed.input ?? library.project.root);
|
|
318
344
|
process.stderr.write(formatCheckOutput(checked));
|
|
319
345
|
if (checked.errors.length > 0)
|
|
320
346
|
return 1;
|
|
321
347
|
staging = await prepareBuildStaging(library.outputRoot, { declared: true, forced: false });
|
|
322
|
-
await writeVelarLibraryArtifact(library, checked.project, staging);
|
|
348
|
+
await writeVelarLibraryArtifact(library, checked.project, staging, parsed.mode ?? config.build.mode);
|
|
323
349
|
await replaceOutputDirectory(staging, library.outputRoot);
|
|
324
350
|
staging = null;
|
|
325
351
|
process.stdout.write(`Built Velar library ABI 1 ${library.packageName}@${library.packageVersion} (${library.target}) -> ${library.receiptPath}\n`);
|
|
@@ -498,7 +524,14 @@ async function main(arguments_) {
|
|
|
498
524
|
process.stderr.write(`velar ${command}: ${hostErrorMessage(error)}\n`);
|
|
499
525
|
return 1;
|
|
500
526
|
}
|
|
501
|
-
|
|
527
|
+
// `check` 不会写出 JavaScript,生产构建也可能明确关闭映射。把这一事实传到
|
|
528
|
+
// 编译器入口,避免先完整生成 Source Map,最后才在输出阶段丢弃它。
|
|
529
|
+
const requestedSourceMaps = command === "check"
|
|
530
|
+
? false
|
|
531
|
+
: command === "package"
|
|
532
|
+
? projectConfig.build.sourceMaps
|
|
533
|
+
: parsed.sourceMaps ?? projectConfig.build.sourceMaps;
|
|
534
|
+
const checked = await checkResolvedProject(projectConfig, parsed.input, { emitSourceMaps: requestedSourceMaps });
|
|
502
535
|
const project = checked.project;
|
|
503
536
|
process.stderr.write(formatCheckOutput(checked));
|
|
504
537
|
if (checked.errors.length > 0) {
|
|
@@ -539,7 +572,7 @@ async function main(arguments_) {
|
|
|
539
572
|
if (buildRequests > 1)
|
|
540
573
|
throw new Error("application package host requested more than one framework build");
|
|
541
574
|
const outputDirectory = packageFrameworkOutput(projectConfig.root, requestedOutput);
|
|
542
|
-
frameworkBuild = writeFrameworkProductionApplication(project, outputDirectory, { forced: false, declared: false });
|
|
575
|
+
frameworkBuild = writeFrameworkProductionApplication(project, outputDirectory, { forced: false, declared: false }, "production", projectConfig.build.sourceMaps);
|
|
543
576
|
await frameworkBuild;
|
|
544
577
|
},
|
|
545
578
|
});
|
|
@@ -557,6 +590,11 @@ async function main(arguments_) {
|
|
|
557
590
|
return 1;
|
|
558
591
|
}
|
|
559
592
|
}
|
|
593
|
+
// JavaScript 表达形式和 Source Map 是两个正交选择。命令行只覆盖本次构建,
|
|
594
|
+
// 项目配置保存稳定默认;两者不能互相推导,否则切到 readable 会意外改变
|
|
595
|
+
// 发布目录的文件集合。
|
|
596
|
+
const buildMode = parsed.mode ?? projectConfig.build.mode;
|
|
597
|
+
const buildSourceMaps = parsed.sourceMaps ?? projectConfig.build.sourceMaps;
|
|
560
598
|
if (parsed.output && project.modules.length !== 1) {
|
|
561
599
|
process.stderr.write("velar build: --out is only valid for a single-file build; use --out-dir for module projects\n");
|
|
562
600
|
return 2;
|
|
@@ -568,19 +606,19 @@ async function main(arguments_) {
|
|
|
568
606
|
await mkdir(dirname(outputPath), { recursive: true });
|
|
569
607
|
const result = project.modules[0].result;
|
|
570
608
|
if (needsStandaloneJavaScriptBundle(result)) {
|
|
571
|
-
const bundled = await bundleStandaloneJavaScript(outputPath, result, project.resources);
|
|
572
|
-
await writeCompiled(outputPath, result, true, bundled.code, bundled.sourceMap, false);
|
|
609
|
+
const bundled = await bundleStandaloneJavaScript(outputPath, result, project.resources, "readable", buildSourceMaps);
|
|
610
|
+
await writeCompiled(outputPath, result, true, bundled.code, bundled.sourceMap, false, buildSourceMaps, buildMode);
|
|
573
611
|
}
|
|
574
612
|
else {
|
|
575
|
-
await writeCompiled(outputPath, result, true);
|
|
613
|
+
await writeCompiled(outputPath, result, true, null, null, true, buildSourceMaps, buildMode);
|
|
576
614
|
}
|
|
577
|
-
await writeNodeStandardModules(dirname(outputPath), project, true);
|
|
615
|
+
await writeNodeStandardModules(dirname(outputPath), project, true, buildMode);
|
|
578
616
|
}
|
|
579
617
|
catch (error) {
|
|
580
618
|
process.stderr.write(`velar build: ${hostErrorMessage(error)}\n`);
|
|
581
619
|
return 1;
|
|
582
620
|
}
|
|
583
|
-
process.stdout.write(`Built ${displayInput(parsed.input, projectConfig)} -> ${outputPath}\n`);
|
|
621
|
+
process.stdout.write(`Built ${buildMode} ${displayInput(parsed.input, projectConfig)} -> ${outputPath}\n`);
|
|
584
622
|
return 0;
|
|
585
623
|
}
|
|
586
624
|
const outputDirectory = parsed.outputDirectory ? resolve(parsed.outputDirectory) : projectConfig.outDir;
|
|
@@ -592,25 +630,25 @@ async function main(arguments_) {
|
|
|
592
630
|
const replacement = { forced: parsed.force, declared: outputDirectory === projectConfig.outDir };
|
|
593
631
|
if (project.framework) {
|
|
594
632
|
try {
|
|
595
|
-
await writeFrameworkProductionApplication(project, outputDirectory, replacement);
|
|
633
|
+
await writeFrameworkProductionApplication(project, outputDirectory, replacement, buildMode, buildSourceMaps);
|
|
596
634
|
}
|
|
597
635
|
catch (error) {
|
|
598
636
|
process.stderr.write(`velar build: ${hostErrorMessage(error)}\n`);
|
|
599
637
|
return 1;
|
|
600
638
|
}
|
|
601
|
-
process.stdout.write(`Built
|
|
639
|
+
process.stdout.write(`Built ${buildMode} ${project.framework.host.displayName} app -> ${outputDirectory}\n`);
|
|
602
640
|
return 0;
|
|
603
641
|
}
|
|
604
642
|
const nodeConfig = nodeApplicationConfig(projectConfig);
|
|
605
643
|
if (nodeConfig) {
|
|
606
644
|
try {
|
|
607
|
-
await writeNodeProductionApplication(project, outputDirectory, nodeConfig, replacement);
|
|
645
|
+
await writeNodeProductionApplication(project, outputDirectory, nodeConfig, replacement, buildMode, buildSourceMaps);
|
|
608
646
|
}
|
|
609
647
|
catch (error) {
|
|
610
648
|
process.stderr.write(`velar build: ${hostErrorMessage(error)}\n`);
|
|
611
649
|
return 1;
|
|
612
650
|
}
|
|
613
|
-
process.stdout.write(`Built
|
|
651
|
+
process.stdout.write(`Built ${buildMode} Node app -> ${outputDirectory}\n`);
|
|
614
652
|
return 0;
|
|
615
653
|
}
|
|
616
654
|
let staging;
|
|
@@ -626,14 +664,14 @@ async function main(arguments_) {
|
|
|
626
664
|
ownerPath: join(staging, module.relativePath.replace(/\.vel$/, ".js")),
|
|
627
665
|
embeddedModules: module.result.embeddedModules,
|
|
628
666
|
})));
|
|
629
|
-
|
|
667
|
+
await mapBuildOutputs(project.modules, async (module) => {
|
|
630
668
|
const outputPath = join(staging, module.relativePath.replace(/\.vel$/, ".js"));
|
|
631
669
|
await mkdir(dirname(outputPath), { recursive: true });
|
|
632
|
-
await writeCompiled(outputPath, module.result, false, rewriteVelarPackageImports(project, module));
|
|
633
|
-
}
|
|
634
|
-
await writeProjectResources(project, staging, "build");
|
|
670
|
+
await writeCompiled(outputPath, module.result, false, rewriteVelarPackageImports(project, module), null, true, buildSourceMaps, buildMode);
|
|
671
|
+
});
|
|
672
|
+
await writeProjectResources(project, staging, "build", buildMode);
|
|
635
673
|
await writeBuildResourcePackageManifests(project, staging);
|
|
636
|
-
await writeNodeStandardModules(staging, project);
|
|
674
|
+
await writeNodeStandardModules(staging, project, false, buildMode);
|
|
637
675
|
await replaceOutputDirectory(staging, outputDirectory);
|
|
638
676
|
}
|
|
639
677
|
catch (error) {
|
|
@@ -641,10 +679,10 @@ async function main(arguments_) {
|
|
|
641
679
|
process.stderr.write(`velar build: ${hostErrorMessage(error)}\n`);
|
|
642
680
|
return 1;
|
|
643
681
|
}
|
|
644
|
-
process.stdout.write(`Built ${project.modules.length} module${project.modules.length === 1 ? "" : "s"} -> ${outputDirectory}\n`);
|
|
682
|
+
process.stdout.write(`Built ${buildMode} ${project.modules.length} module${project.modules.length === 1 ? "" : "s"} -> ${outputDirectory}\n`);
|
|
645
683
|
return 0;
|
|
646
684
|
}
|
|
647
|
-
async function writeFrameworkProductionApplication(project, outputDirectory, replacement) {
|
|
685
|
+
async function writeFrameworkProductionApplication(project, outputDirectory, replacement, mode, sourceMaps) {
|
|
648
686
|
if (!project.framework)
|
|
649
687
|
throw new Error("the checked project has no framework host");
|
|
650
688
|
const framework = project.framework;
|
|
@@ -652,7 +690,7 @@ async function writeFrameworkProductionApplication(project, outputDirectory, rep
|
|
|
652
690
|
const staging = await prepareBuildStaging(outputDirectory, replacement);
|
|
653
691
|
try {
|
|
654
692
|
await copyPublicAssets(project.publicRoot, staging);
|
|
655
|
-
const production = await buildProductionFramework(project, staging);
|
|
693
|
+
const production = await buildProductionFramework(project, staging, mode, sourceMaps);
|
|
656
694
|
const artifacts = createFrameworkArtifacts(project, false, {}, {
|
|
657
695
|
entryPath: production.entryPath,
|
|
658
696
|
stylesheetPath: production.stylesheetPath,
|
|
@@ -672,7 +710,7 @@ async function writeFrameworkProductionApplication(project, outputDirectory, rep
|
|
|
672
710
|
}
|
|
673
711
|
/** The receipt a node build leaves in its output; it also proves velar owns the directory. */
|
|
674
712
|
const NODE_BUILD_MANIFEST_NAME = "velar-node.json";
|
|
675
|
-
async function writeNodeProductionApplication(project, outputDirectory, config, replacement) {
|
|
713
|
+
async function writeNodeProductionApplication(project, outputDirectory, config, replacement, mode, sourceMaps) {
|
|
676
714
|
const application = nodeApplicationEntry(project, config);
|
|
677
715
|
const entry = application.entry;
|
|
678
716
|
const staging = await prepareBuildStaging(outputDirectory, replacement);
|
|
@@ -681,28 +719,39 @@ async function writeNodeProductionApplication(project, outputDirectory, config,
|
|
|
681
719
|
ownerPath: join(staging, module.relativePath.replace(/\.vel$/u, ".js")),
|
|
682
720
|
embeddedModules: module.result.embeddedModules,
|
|
683
721
|
})));
|
|
684
|
-
|
|
722
|
+
await mapBuildOutputs(project.modules, async (module) => {
|
|
685
723
|
const outputPath = join(staging, module.relativePath.replace(/\.vel$/u, ".js"));
|
|
686
724
|
await mkdir(dirname(outputPath), { recursive: true });
|
|
687
|
-
await writeCompiled(outputPath, module.result, false, rewriteVelarPackageImports(project, module), null, true,
|
|
688
|
-
}
|
|
689
|
-
await writeProjectResources(project, staging, "build");
|
|
725
|
+
await writeCompiled(outputPath, module.result, false, rewriteVelarPackageImports(project, module), null, true, sourceMaps, mode);
|
|
726
|
+
});
|
|
727
|
+
await writeProjectResources(project, staging, "build", mode);
|
|
690
728
|
await writeBuildResourcePackageManifests(project, staging);
|
|
691
|
-
await writeNodeStandardModules(staging, project);
|
|
729
|
+
await writeNodeStandardModules(staging, project, false, mode);
|
|
692
730
|
await copyPublicAssets(project.publicRoot, join(staging, "public"), true);
|
|
693
731
|
if (requiredNodeStandardModules(project).has("velar/server")) {
|
|
694
732
|
await copyConventionalServerConfiguration(project.projectRoot, staging);
|
|
695
733
|
}
|
|
696
734
|
const entryPath = `./${relative(project.sourceRoot, entry.inputPath).replace(/\.vel$/u, ".js").replaceAll("\\", "/")}`;
|
|
697
735
|
const launcher = ".velar-node-entry.mjs";
|
|
698
|
-
|
|
736
|
+
const launcherPath = join(staging, launcher);
|
|
737
|
+
const launcherOutput = await renderJavaScriptOutput({
|
|
738
|
+
code: nodeApplicationLauncherSource(entryPath, config, false, application.kind),
|
|
739
|
+
sourceMap: null,
|
|
740
|
+
sourceFile: launcherPath,
|
|
741
|
+
outputFile: launcherPath,
|
|
742
|
+
mode,
|
|
743
|
+
sourceMaps: false,
|
|
744
|
+
target: "node24",
|
|
745
|
+
});
|
|
746
|
+
await writeFile(launcherPath, launcherOutput.code, "utf8");
|
|
699
747
|
await writeFile(join(staging, "package.json"), `${JSON.stringify({ name: "velar-node-build", private: true, type: "module" }, null, 2)}\n`, "utf8");
|
|
700
748
|
await writeFile(join(staging, NODE_BUILD_MANIFEST_NAME), `${JSON.stringify({
|
|
701
|
-
formatVersion:
|
|
749
|
+
formatVersion: 3,
|
|
702
750
|
kind: "velar-node-build",
|
|
751
|
+
mode,
|
|
703
752
|
entry: launcher,
|
|
704
753
|
app: config.app,
|
|
705
|
-
sourceMaps
|
|
754
|
+
sourceMaps,
|
|
706
755
|
}, null, 2)}\n`, "utf8");
|
|
707
756
|
await replaceOutputDirectory(staging, outputDirectory);
|
|
708
757
|
}
|
|
@@ -938,13 +987,13 @@ async function replaceOutputDirectory(staging, outputDirectory) {
|
|
|
938
987
|
}
|
|
939
988
|
}
|
|
940
989
|
const VELAR_GENERATED_RUNTIME_PACKAGE_VERSION = 1;
|
|
941
|
-
async function writeNodeStandardModules(outputRoot, project, replaceExisting = false) {
|
|
990
|
+
async function writeNodeStandardModules(outputRoot, project, replaceExisting = false, mode = "readable") {
|
|
942
991
|
const used = requiredNodeStandardModules(project);
|
|
943
992
|
const packageRoot = join(outputRoot, "node_modules", "velar");
|
|
944
993
|
if (!replaceExisting) {
|
|
945
994
|
if (used.size === 0)
|
|
946
995
|
return;
|
|
947
|
-
await writeNodeStandardModulePackage(packageRoot, used, project);
|
|
996
|
+
await writeNodeStandardModulePackage(packageRoot, used, project, mode);
|
|
948
997
|
if (used.has("velar/websocket"))
|
|
949
998
|
await writeWebSocketDependency(dirname(packageRoot));
|
|
950
999
|
if (used.has("velar/server"))
|
|
@@ -962,7 +1011,7 @@ async function writeNodeStandardModules(outputRoot, project, replaceExisting = f
|
|
|
962
1011
|
await mkdir(dirname(packageRoot), { recursive: true });
|
|
963
1012
|
const staging = await mkdtemp(join(dirname(packageRoot), ".velar-runtime-"));
|
|
964
1013
|
try {
|
|
965
|
-
await writeNodeStandardModulePackage(staging, used, project);
|
|
1014
|
+
await writeNodeStandardModulePackage(staging, used, project, mode);
|
|
966
1015
|
if (ownership === "generated")
|
|
967
1016
|
await replaceOutputDirectory(staging, packageRoot);
|
|
968
1017
|
else
|
|
@@ -997,22 +1046,35 @@ async function assertNodeStandardModuleOutputAvailable(outputRoot, project) {
|
|
|
997
1046
|
throw new Error(`Refusing to replace non-generated package '${packageRoot}'`);
|
|
998
1047
|
}
|
|
999
1048
|
}
|
|
1000
|
-
async function writeNodeStandardModulePackage(packageRoot, used, project) {
|
|
1049
|
+
async function writeNodeStandardModulePackage(packageRoot, used, project, mode) {
|
|
1001
1050
|
await mkdir(packageRoot, { recursive: true });
|
|
1002
1051
|
const exports = {};
|
|
1003
|
-
|
|
1052
|
+
const sources = [...used].sort();
|
|
1053
|
+
for (const source of sources)
|
|
1054
|
+
exports[`./${source.slice("velar/".length)}`] = `./${source.slice("velar/".length)}.js`;
|
|
1055
|
+
await mapBuildOutputs(sources, async (source) => {
|
|
1004
1056
|
const name = source.slice("velar/".length);
|
|
1005
1057
|
const moduleSource = standardModuleSource(source, project.extensionConfig, project.compilerExtensions);
|
|
1006
1058
|
if (moduleSource === null)
|
|
1007
1059
|
throw new Error(`Unknown VelarScript standard module '${source}'`);
|
|
1008
|
-
|
|
1009
|
-
await
|
|
1010
|
-
|
|
1060
|
+
const outputPath = join(packageRoot, `${name}.js`);
|
|
1061
|
+
const output = await renderJavaScriptOutput({
|
|
1062
|
+
code: moduleSource,
|
|
1063
|
+
sourceMap: null,
|
|
1064
|
+
sourceFile: `velar/${name}`,
|
|
1065
|
+
outputFile: outputPath,
|
|
1066
|
+
mode,
|
|
1067
|
+
sourceMaps: false,
|
|
1068
|
+
target: "node24",
|
|
1069
|
+
});
|
|
1070
|
+
await writeFile(outputPath, output.code, "utf8");
|
|
1071
|
+
});
|
|
1011
1072
|
await writeFile(join(packageRoot, "package.json"), `${JSON.stringify({
|
|
1012
1073
|
name: "velar",
|
|
1013
1074
|
private: true,
|
|
1014
1075
|
type: "module",
|
|
1015
1076
|
velarGeneratedRuntime: VELAR_GENERATED_RUNTIME_PACKAGE_VERSION,
|
|
1077
|
+
velarBuildMode: mode,
|
|
1016
1078
|
exports,
|
|
1017
1079
|
}, null, 2)}\n`, "utf8");
|
|
1018
1080
|
}
|
|
@@ -1042,12 +1104,21 @@ async function generatedRuntimePackageOwnership(packageRoot) {
|
|
|
1042
1104
|
throw error;
|
|
1043
1105
|
}
|
|
1044
1106
|
}
|
|
1045
|
-
async function writeCompiled(outputPath, result, writeCss, codeOverride = null, sourceMapOverride = null, writeEmbedded = true, sourceMaps = true) {
|
|
1107
|
+
async function writeCompiled(outputPath, result, writeCss, codeOverride = null, sourceMapOverride = null, writeEmbedded = true, sourceMaps = true, mode = "readable") {
|
|
1046
1108
|
const mapPath = `${outputPath}.map`;
|
|
1047
1109
|
const rawCode = codeOverride ?? result.code ?? "";
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
:
|
|
1110
|
+
const output = await renderJavaScriptOutput({
|
|
1111
|
+
code: rawCode,
|
|
1112
|
+
sourceMap: sourceMapOverride ?? result.sourceMap,
|
|
1113
|
+
sourceFile: result.source.path,
|
|
1114
|
+
outputFile: outputPath,
|
|
1115
|
+
mode,
|
|
1116
|
+
sourceMaps,
|
|
1117
|
+
target: "node24",
|
|
1118
|
+
});
|
|
1119
|
+
const code = !sourceMaps || output.code.includes(`//# sourceMappingURL=${basename(mapPath)}`)
|
|
1120
|
+
? output.code
|
|
1121
|
+
: `${output.code}//# sourceMappingURL=${basename(mapPath)}\n`;
|
|
1051
1122
|
if (writeEmbedded) {
|
|
1052
1123
|
assertUniqueEmbeddedModuleOutputs([{ ownerPath: outputPath, embeddedModules: result.embeddedModules }]);
|
|
1053
1124
|
for (const module of result.embeddedModules) {
|
|
@@ -1055,18 +1126,28 @@ async function writeCompiled(outputPath, result, writeCss, codeOverride = null,
|
|
|
1055
1126
|
await assertEmbeddedModuleOutputWritable(embeddedPath);
|
|
1056
1127
|
}
|
|
1057
1128
|
}
|
|
1129
|
+
const embeddedWrites = (await Promise.all((writeEmbedded ? result.embeddedModules : []).map(async (module) => {
|
|
1130
|
+
const embeddedPath = embeddedModuleOutputPath(outputPath, module.specifier);
|
|
1131
|
+
const embeddedOutput = await renderJavaScriptOutput({
|
|
1132
|
+
code: module.code,
|
|
1133
|
+
sourceMap: module.sourceMap,
|
|
1134
|
+
sourceFile: `${result.source.path}:${module.specifier}`,
|
|
1135
|
+
outputFile: embeddedPath,
|
|
1136
|
+
mode,
|
|
1137
|
+
sourceMaps,
|
|
1138
|
+
target: "node24",
|
|
1139
|
+
});
|
|
1140
|
+
const embeddedCode = sourceMaps
|
|
1141
|
+
? embeddedModuleFileContents(embeddedPath, { ...module, code: embeddedOutput.code })
|
|
1142
|
+
: `${embeddedOutput.code}${VELAR_EMBEDDED_MODULE_MARKER}`;
|
|
1143
|
+
return sourceMaps
|
|
1144
|
+
? [writeFile(embeddedPath, embeddedCode, "utf8"), writeFile(`${embeddedPath}.map`, embeddedOutput.sourceMap, "utf8")]
|
|
1145
|
+
: [writeFile(embeddedPath, embeddedCode, "utf8"), rm(`${embeddedPath}.map`, { force: true })];
|
|
1146
|
+
}))).flat();
|
|
1058
1147
|
const writes = [
|
|
1059
1148
|
writeFile(outputPath, code, "utf8"),
|
|
1060
|
-
...(sourceMaps ? [writeFile(mapPath,
|
|
1061
|
-
...
|
|
1062
|
-
const embeddedPath = embeddedModuleOutputPath(outputPath, module.specifier);
|
|
1063
|
-
const embeddedCode = sourceMaps
|
|
1064
|
-
? embeddedModuleFileContents(embeddedPath, module)
|
|
1065
|
-
: `${module.code.endsWith("\n") || module.code.endsWith("\r") ? module.code : `${module.code}\n`}${VELAR_EMBEDDED_MODULE_MARKER}`;
|
|
1066
|
-
return sourceMaps
|
|
1067
|
-
? [writeFile(embeddedPath, embeddedCode, "utf8"), writeFile(`${embeddedPath}.map`, module.sourceMap, "utf8")]
|
|
1068
|
-
: [writeFile(embeddedPath, embeddedCode, "utf8")];
|
|
1069
|
-
}),
|
|
1149
|
+
...(sourceMaps ? [writeFile(mapPath, output.sourceMap, "utf8")] : [rm(mapPath, { force: true })]),
|
|
1150
|
+
...embeddedWrites,
|
|
1070
1151
|
];
|
|
1071
1152
|
if (writeCss) {
|
|
1072
1153
|
const cssPath = outputPath.replace(/\.js$/u, ".css");
|
|
@@ -1146,11 +1227,28 @@ function parseCommandArguments(arguments_, allowForce = false) {
|
|
|
1146
1227
|
let output = null;
|
|
1147
1228
|
let outputDirectory = null;
|
|
1148
1229
|
let force = false;
|
|
1230
|
+
let mode = null;
|
|
1231
|
+
let sourceMaps = null;
|
|
1149
1232
|
for (let index = 0; index < arguments_.length; index += 1) {
|
|
1150
1233
|
const argument = arguments_[index];
|
|
1151
1234
|
if (allowForce && argument === "--force") {
|
|
1152
1235
|
force = true;
|
|
1153
1236
|
}
|
|
1237
|
+
else if (allowForce && (argument === "--mode" || argument.startsWith("--mode="))) {
|
|
1238
|
+
if (mode !== null)
|
|
1239
|
+
return "--mode may be provided only once";
|
|
1240
|
+
const value = argument === "--mode" ? arguments_[index + 1] : argument.slice("--mode=".length);
|
|
1241
|
+
if (value !== "production" && value !== "readable")
|
|
1242
|
+
return "--mode must be production or readable";
|
|
1243
|
+
mode = value;
|
|
1244
|
+
if (argument === "--mode")
|
|
1245
|
+
index += 1;
|
|
1246
|
+
}
|
|
1247
|
+
else if (allowForce && (argument === "--source-maps" || argument === "--no-source-maps")) {
|
|
1248
|
+
if (sourceMaps !== null)
|
|
1249
|
+
return "--source-maps and --no-source-maps may be provided only once";
|
|
1250
|
+
sourceMaps = argument === "--source-maps";
|
|
1251
|
+
}
|
|
1154
1252
|
else if (argument === "--out" || argument === "--out-dir") {
|
|
1155
1253
|
const value = arguments_[index + 1];
|
|
1156
1254
|
if (!value || value.startsWith("--")) {
|
|
@@ -1176,7 +1274,34 @@ function parseCommandArguments(arguments_, allowForce = false) {
|
|
|
1176
1274
|
input = argument;
|
|
1177
1275
|
}
|
|
1178
1276
|
}
|
|
1179
|
-
return { input, output, outputDirectory, force };
|
|
1277
|
+
return { input, output, outputDirectory, force, mode, sourceMaps };
|
|
1278
|
+
}
|
|
1279
|
+
function parseBuildLibraryArguments(arguments_) {
|
|
1280
|
+
let input = null;
|
|
1281
|
+
let mode = null;
|
|
1282
|
+
for (let index = 0; index < arguments_.length; index += 1) {
|
|
1283
|
+
const argument = arguments_[index];
|
|
1284
|
+
if (argument === "--mode" || argument.startsWith("--mode=")) {
|
|
1285
|
+
if (mode !== null)
|
|
1286
|
+
return "--mode may be provided only once";
|
|
1287
|
+
const value = argument === "--mode" ? arguments_[index + 1] : argument.slice("--mode=".length);
|
|
1288
|
+
if (value !== "production" && value !== "readable")
|
|
1289
|
+
return "--mode must be production or readable";
|
|
1290
|
+
mode = value;
|
|
1291
|
+
if (argument === "--mode")
|
|
1292
|
+
index += 1;
|
|
1293
|
+
}
|
|
1294
|
+
else if (argument.startsWith("--")) {
|
|
1295
|
+
return `unknown option '${argument}'`;
|
|
1296
|
+
}
|
|
1297
|
+
else if (input !== null) {
|
|
1298
|
+
return `unexpected extra input '${argument}'`;
|
|
1299
|
+
}
|
|
1300
|
+
else {
|
|
1301
|
+
input = argument;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
return { input, mode };
|
|
1180
1305
|
}
|
|
1181
1306
|
function parseReproArguments(arguments_) {
|
|
1182
1307
|
let input = null;
|
|
@@ -1216,7 +1341,7 @@ function parsePackageArguments(arguments_) {
|
|
|
1216
1341
|
return `unexpected extra input '${arguments_[1]}'`;
|
|
1217
1342
|
if (arguments_[0]?.startsWith("-"))
|
|
1218
1343
|
return `unknown option '${arguments_[0]}'`;
|
|
1219
|
-
return { input: arguments_[0] ?? null, output: null, outputDirectory: null, force: false };
|
|
1344
|
+
return { input: arguments_[0] ?? null, output: null, outputDirectory: null, force: false, mode: null, sourceMaps: null };
|
|
1220
1345
|
}
|
|
1221
1346
|
function parseDevArguments(arguments_) {
|
|
1222
1347
|
let input = null;
|
|
@@ -1413,8 +1538,8 @@ function printHelp(output = process.stdout) {
|
|
|
1413
1538
|
" velar update [package...]",
|
|
1414
1539
|
" velar dev [entry.vel | project-directory] [--port <port>]",
|
|
1415
1540
|
" velar serve [project-directory]",
|
|
1416
|
-
" velar build [entry.vel | project-directory] [--out-dir <directory>] [--force]",
|
|
1417
|
-
" velar build-library [project-directory]",
|
|
1541
|
+
" velar build [entry.vel | project-directory] [--out-dir <directory>] [--mode <production|readable>] [--source-maps|--no-source-maps] [--force]",
|
|
1542
|
+
" velar build-library [project-directory] [--mode <production|readable>]",
|
|
1418
1543
|
" velar run [entry.vel | project-directory] [--stack] [-- <program-arguments>...]",
|
|
1419
1544
|
" velar verify [project-directory | build-directory]",
|
|
1420
1545
|
" velar preview [project-directory | build-directory] [--port <port>]",
|
|
@@ -1446,8 +1571,14 @@ function printCommandHelp(command, output = process.stdout) {
|
|
|
1446
1571
|
update: ["Usage: velar update [package...]", "Updates all or selected direct dependencies within package.json ranges through npm."],
|
|
1447
1572
|
dev: ["Usage: velar dev [entry.vel | project-directory] [--port <1-65535>]", "Watches a framework app or last-good Node server factory; --port applies only to Web and Desktop development servers."],
|
|
1448
1573
|
serve: ["Usage: velar serve [project-directory]", "Checks and runs a Node server factory with production runtime behavior; host and port belong to velar/server configuration."],
|
|
1449
|
-
build: [
|
|
1450
|
-
|
|
1574
|
+
build: [
|
|
1575
|
+
"Usage: velar build [entry.vel | project-directory] [--out-dir <directory>] [--mode <production|readable>] [--source-maps|--no-source-maps] [--force]",
|
|
1576
|
+
" velar build <single.vel> --out <file.js> [--mode <production|readable>] [--source-maps|--no-source-maps]",
|
|
1577
|
+
"Builds isolated Web/Desktop output, a standalone Node application, or JavaScript modules.",
|
|
1578
|
+
"production is the default and emits compressed deployable JavaScript; readable preserves structured generated JavaScript for inspection and handover.",
|
|
1579
|
+
"--out-dir refuses a directory that is not empty and was not produced by a previous build; --force replaces one anyway.",
|
|
1580
|
+
],
|
|
1581
|
+
"build-library": ["Usage: velar build-library [project-directory] [--mode <production|readable>]", "Checks a Core or Node source library, then writes its frozen ABI-1 JavaScript, source map, portable type interface, and integrity receipt; production JavaScript is the default."],
|
|
1451
1582
|
package: ["Usage: velar package [project-directory]", "Packages an application through its target-owned native packaging host."],
|
|
1452
1583
|
run: ["Usage: velar run [entry.vel | project-directory] [--stack] [-- <program-arguments>...]", "Compiles the resolved Core project and executes its entry module once on Node.js; arguments after '--' reach the program.", "--stack prints the full Node.js trace behind an uncaught program error instead of the VelarScript frames."],
|
|
1453
1584
|
verify: ["Usage: velar verify [project-directory | build-directory]", "Verifies the exact production manifest, inventory, sizes, hashes, and relationships."],
|