tungsten 0.4.9 → 0.4.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/dist/.build-complete +1 -1
- package/dist/Framework.d.ts +1 -0
- package/dist/Framework.d.ts.map +1 -1
- package/dist/Framework.js +30 -20
- package/dist/FrameworkConfig.d.ts +4 -0
- package/dist/FrameworkConfig.d.ts.map +1 -1
- package/dist/Servers/DevServer.d.ts +0 -1
- package/dist/Servers/DevServer.d.ts.map +1 -1
- package/dist/Servers/DevServer.js +2 -1
- package/dist/Servers/hono/TungstenServerHono.d.ts +1 -1
- package/dist/Servers/hono/TungstenServerHono.d.ts.map +1 -1
- package/dist/Servers/loadEnvsDev.d.ts.map +1 -1
- package/dist/Servers/loadEnvsDev.js +13 -20
- package/dist/Servers/tungstenCorePrivateEnvSchema.d.ts +6 -6
- package/dist/Servers/tungstenCorePrivateEnvSchema.d.ts.map +1 -1
- package/dist/Servers/tungstenCorePrivateEnvSchema.js +12 -22
- package/dist/Servers/tungstenCorePublicEnvSchema.d.ts +7 -7
- package/dist/Servers/tungstenCorePublicEnvSchema.d.ts.map +1 -1
- package/dist/Servers/tungstenCorePublicEnvSchema.js +6 -7
- package/dist/api/getApiRoutesHono.d.ts +1 -1
- package/dist/api/getApiRoutesHono.d.ts.map +1 -1
- package/dist/babelPlugins/BabelAddDevCacheBust.d.ts +1 -0
- package/dist/babelPlugins/BabelAddDevCacheBust.d.ts.map +1 -1
- package/dist/babelPlugins/BabelAddDevCacheBust.js +1 -0
- package/dist/babelPlugins/BabelTransformComponentStyles.d.ts.map +1 -1
- package/dist/babelPlugins/BabelTransformComponentStyles.js +4 -2
- package/dist/babelPlugins/BabelTransformCssImports.d.ts +1 -0
- package/dist/babelPlugins/BabelTransformCssImports.d.ts.map +1 -1
- package/dist/babelPlugins/BabelTransformCssImports.js +1 -0
- package/dist/babelPlugins/BabelTransformJsxExtensionsToJs.d.ts +1 -0
- package/dist/babelPlugins/BabelTransformJsxExtensionsToJs.d.ts.map +1 -1
- package/dist/babelPlugins/BabelTransformJsxExtensionsToJs.js +1 -0
- package/dist/babelPlugins/BabelTransformPackageImports.d.ts +1 -0
- package/dist/babelPlugins/BabelTransformPackageImports.d.ts.map +1 -1
- package/dist/babelPlugins/BabelTransformPackageImports.js +75 -15
- package/dist/bin/args.d.ts +11 -0
- package/dist/bin/args.d.ts.map +1 -0
- package/dist/bin/args.js +77 -0
- package/dist/bin/commands/build.d.ts.map +1 -1
- package/dist/bin/commands/build.js +15 -4
- package/dist/bin/commands/buildHelp.js +4 -1
- package/dist/bin/commands/clean.d.ts.map +1 -1
- package/dist/bin/commands/clean.js +2 -0
- package/dist/bin/commands/compile.d.ts.map +1 -1
- package/dist/bin/commands/compile.js +73 -81
- package/dist/bin/commands/dev.d.ts.map +1 -1
- package/dist/bin/commands/dev.js +23 -8
- package/dist/bin/commands/devmon.d.ts.map +1 -1
- package/dist/bin/commands/devmon.js +26 -30
- package/dist/bin/commands/help.js +2 -2
- package/dist/bin/commands/start.d.ts.map +1 -1
- package/dist/bin/commands/start.js +2 -1
- package/dist/bin/commands/static.d.ts.map +1 -1
- package/dist/bin/commands/static.js +2 -0
- package/dist/bin/index.d.ts.map +1 -1
- package/dist/bin/index.js +35 -1
- package/dist/bin/moduleLoadAnalysis.d.ts +2 -0
- package/dist/bin/moduleLoadAnalysis.d.ts.map +1 -0
- package/dist/bin/moduleLoadAnalysis.js +243 -0
- package/dist/build/compileJavascript.d.ts +1 -0
- package/dist/build/compileJavascript.d.ts.map +1 -1
- package/dist/build/compileJavascript.js +67 -11
- package/dist/build/compileUserApp.d.ts +1 -1
- package/dist/build/compileUserApp.d.ts.map +1 -1
- package/dist/build/compileUserApp.js +4 -2
- package/dist/build/sassImportParser.d.ts.map +1 -1
- package/dist/build/sassImportParser.js +5 -2
- package/dist/build/tallyBabelPlugins.d.ts +3 -0
- package/dist/build/tallyBabelPlugins.d.ts.map +1 -0
- package/dist/build/tallyBabelPlugins.js +68 -0
- package/dist/componentCss/tungsten.css +2 -2
- package/dist/env/getEnvSchemas.d.ts +3 -3
- package/dist/env/getEnvSchemas.d.ts.map +1 -1
- package/dist/env/getEnvSchemas.js +9 -15
- package/dist/env/setPrivateEnvValidator.d.ts +2 -2
- package/dist/env/setPrivateEnvValidator.d.ts.map +1 -1
- package/dist/env/setPublicEnvValidator.d.ts +2 -2
- package/dist/env/setPublicEnvValidator.d.ts.map +1 -1
- package/dist/frameworkConfigSchema.d.ts +61 -192
- package/dist/frameworkConfigSchema.d.ts.map +1 -1
- package/dist/frameworkConfigSchema.js +49 -62
- package/dist/getUserConfig.d.ts.map +1 -1
- package/dist/getUserConfig.js +5 -5
- package/dist/moduleReloader.d.ts +1 -3
- package/dist/moduleReloader.d.ts.map +1 -1
- package/dist/moduleReloader.js +17 -15
- package/dist/standardSchema.d.ts +37 -0
- package/dist/standardSchema.d.ts.map +1 -0
- package/dist/standardSchema.js +47 -0
- package/dist/timeProfiler.d.ts +6 -0
- package/dist/timeProfiler.d.ts.map +1 -1
- package/dist/timeProfiler.js +253 -10
- package/package.json +3 -4
|
@@ -14,7 +14,7 @@ import precinct from 'precinct';
|
|
|
14
14
|
//import sxyPrecinct from 'sxy-precinct'
|
|
15
15
|
import { existsSync, mkdirSync, promises as fsPromises, readFileSync, writeFileSync } from 'fs';
|
|
16
16
|
import { createRequire } from 'module';
|
|
17
|
-
import {
|
|
17
|
+
import { transformFileSync as babelTransformFileSync, transformSync as babelTransformSync } from '@babel/core';
|
|
18
18
|
import babelPluginSyntaxImportAssertionsModule from '@babel/plugin-syntax-import-assertions';
|
|
19
19
|
import { arrays } from 'sxy-lib';
|
|
20
20
|
const babelPluginSyntaxImportAssertions = babelPluginSyntaxImportAssertionsModule.default;
|
|
@@ -32,6 +32,7 @@ import { isBareImport } from "./isBareImport.js";
|
|
|
32
32
|
import { resolveBareImport } from "./transformPackageImports/resolveBareImport.js";
|
|
33
33
|
import { TungstenError } from "../TungstenError.js";
|
|
34
34
|
import { throwError } from "../throwError.js";
|
|
35
|
+
import { isProfiling, tally } from "../timeProfiler.js";
|
|
35
36
|
//import { copyPackageModulesToPackagesFolder } from '../build/copyPackageModulesToPackagesFolder.js'
|
|
36
37
|
const require = createRequire(import.meta.url);
|
|
37
38
|
function debug(...texts) {
|
|
@@ -209,9 +210,11 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
209
210
|
const {
|
|
210
211
|
file
|
|
211
212
|
} = fileInfo;
|
|
213
|
+
const precinctStart = performance.now();
|
|
212
214
|
const precinctResults = precinct.paperwork(file, {
|
|
213
215
|
includeCore: false
|
|
214
216
|
});
|
|
217
|
+
tally('precinct.paperwork', performance.now() - precinctStart);
|
|
215
218
|
const deps = precinctResults.map(d => {
|
|
216
219
|
//console.log('getFileDependencies', 'd', d)
|
|
217
220
|
return isBareImport(d) ? applyImportAliases(d, fileInfo.type) : d;
|
|
@@ -343,7 +346,11 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
343
346
|
};
|
|
344
347
|
}
|
|
345
348
|
async function babelFileEsm(file /*, packageInfo*/, nonEsmDeps, onStylesheet) {
|
|
346
|
-
|
|
349
|
+
// Sync, so it can be tallied: these run concurrently in the deferred package work, where a
|
|
350
|
+
// wall clock around an async call would count the same time once per file in flight.
|
|
351
|
+
const esmStart = performance.now();
|
|
352
|
+
const result = babelTransformFileSync(file, makeModifyImportsEsmBabelOptions(nonEsmDeps.map(d => d.webLocation), onStylesheet));
|
|
353
|
+
tally('babel transform (packages)', performance.now() - esmStart);
|
|
347
354
|
if (result === null) {
|
|
348
355
|
throw new TungstenError(`BabelTransformPackageImports error: sub file babel transform (1) returned null: ${file}`);
|
|
349
356
|
}
|
|
@@ -377,7 +384,9 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
377
384
|
async function babelFileCjs(file, cacheDest, finalDest, packageInfo, nonEsmDeps) {
|
|
378
385
|
//console.log(chalk.yellow`cjs file ${file}`)
|
|
379
386
|
const nonEsmDepsWebPath = nonEsmDeps.map(fi => fi.webLocation);
|
|
380
|
-
|
|
387
|
+
const cjsStart = performance.now();
|
|
388
|
+
let result = babelTransformFileSync(file, makeCjsToEsmBabelOptions(nonEsmDepsWebPath));
|
|
389
|
+
tally('babel transform (packages)', performance.now() - cjsStart);
|
|
381
390
|
if (result === null) {
|
|
382
391
|
throw new TungstenError(`BabelTransformPackageImports error: sub file babel transform (2) returned null: ${file}`);
|
|
383
392
|
}
|
|
@@ -390,10 +399,12 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
390
399
|
});
|
|
391
400
|
//console.log('writing file', intermedCacheLocation)
|
|
392
401
|
await fsPromises.writeFile(intermedCacheLocation, result.code); // rel contains the slash at start
|
|
393
|
-
|
|
402
|
+
const cjsImportsStart = performance.now();
|
|
403
|
+
result = babelTransformSync(result.code, {
|
|
394
404
|
filename: file,
|
|
395
405
|
...makeModifyImportsCjsBabelOptions(nonEsmDepsWebPath)
|
|
396
406
|
});
|
|
407
|
+
tally('babel transform (packages)', performance.now() - cjsImportsStart);
|
|
397
408
|
if (result === null) {
|
|
398
409
|
throw new TungstenError(`BabelTransformPackageImports error: sub file babel transform (3) returned null: ${file}
|
|
399
410
|
`);
|
|
@@ -516,35 +527,64 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
516
527
|
// throw error
|
|
517
528
|
// }
|
|
518
529
|
}
|
|
530
|
+
// Guarded like processFile's processedFilesCache, and for the same reason: the walk below
|
|
531
|
+
// follows dependencies, which form cycles and diamonds. Without this a cycle never terminates
|
|
532
|
+
// and a shared dependency is copied once per path that reaches it.
|
|
533
|
+
const copiedFromCache = new Set();
|
|
519
534
|
async function copyFileFromCache(fileIdentifier, cacheNode) {
|
|
520
|
-
|
|
535
|
+
if (copiedFromCache.has(fileIdentifier)) return;
|
|
536
|
+
copiedFromCache.add(fileIdentifier);
|
|
521
537
|
await fsPromises.mkdir(dirname(cacheNode.finalLocation), {
|
|
522
538
|
recursive: true
|
|
523
539
|
});
|
|
524
540
|
await fsPromises.copyFile(cacheNode.cacheLocation, cacheNode.finalLocation);
|
|
525
541
|
if (cacheNode.dependencies) {
|
|
526
|
-
processCacheDependencies(cacheNode.dependencies);
|
|
542
|
+
await processCacheDependencies(cacheNode.dependencies);
|
|
527
543
|
}
|
|
528
544
|
addToDependencyGraphFromCacheNode(fileIdentifier, cacheNode, cacheNode.dependencies);
|
|
529
545
|
}
|
|
546
|
+
// Only reached for a subtree cachedSubtreeIsUsable() already accepted, so both failures below
|
|
547
|
+
// mean the cache changed during the build. Recompiling from here is not possible - an identifier
|
|
548
|
+
// cannot be resolved back to a source file - and a half-copied package is worse than stopping.
|
|
530
549
|
async function processCacheDependencies(dependencies) {
|
|
531
550
|
for (const dep of dependencies) {
|
|
532
551
|
const cacheNode = opts.oldDependencyGraph[dep];
|
|
533
552
|
if (cacheNode === undefined) {
|
|
534
|
-
throw new TungstenError(`processCacheDependencies() Error: ${dep}
|
|
553
|
+
throw new TungstenError(`processCacheDependencies() Error: ${dep} left the package cache mid-build.` + ` Delete ${packagesCacheLocation} and run again`);
|
|
535
554
|
}
|
|
536
|
-
//const cacheNode = opts.oldDependencyGraph[dep]
|
|
537
555
|
if (existsSync(cacheNode.originalLocation)) {
|
|
538
556
|
await copyFileFromCache(dep, cacheNode);
|
|
539
557
|
} else {
|
|
540
|
-
throw new TungstenError(`processCacheDependencies() Error: source file ${cacheNode.originalLocation}` + ` for ${dep}
|
|
541
|
-
// find the import/require specification
|
|
542
|
-
// resolve with sxy-filing-cabinet
|
|
543
|
-
// resolveFile
|
|
544
|
-
// processFile
|
|
558
|
+
throw new TungstenError(`processCacheDependencies() Error: source file ${cacheNode.originalLocation}` + ` for ${dep} was removed mid-build.` + ` Delete ${packagesCacheLocation} and run again`);
|
|
545
559
|
}
|
|
546
560
|
}
|
|
547
561
|
}
|
|
562
|
+
// A cached file is only reusable if its whole dependency closure is too: processCacheDependencies
|
|
563
|
+
// walks that closure from identifiers alone and has no way to resolve one back to a source file
|
|
564
|
+
// to compile instead, so the entire subtree is checked before any of it is used.
|
|
565
|
+
const subtreeUsable = new Map();
|
|
566
|
+
function cachedSubtreeIsUsable(fileIdentifier, visiting) {
|
|
567
|
+
const settled = subtreeUsable.get(fileIdentifier);
|
|
568
|
+
if (settled !== undefined) return settled;
|
|
569
|
+
// a cycle is taken as usable here, so the rest of the walk decides the subtree
|
|
570
|
+
if (visiting.has(fileIdentifier)) return true;
|
|
571
|
+
const node = opts.oldDependencyGraph[fileIdentifier];
|
|
572
|
+
visiting.add(fileIdentifier);
|
|
573
|
+
// Profiling serves linked packages from the cache too, so a run measures what a real app
|
|
574
|
+
// pays rather than recompiling a linked framework's every file. The cache key is the
|
|
575
|
+
// version, which a linked package changes underneath, so a profiled run can compile stale
|
|
576
|
+
// code after that package is rebuilt until the packages cache is deleted - it warns.
|
|
577
|
+
const usable = node !== undefined && (isProfiling() || cacheKeyIdentifiesContent(node.originalLocation)) && existsSync(node.originalLocation) && existsSync(node.cacheLocation) && (node.dependencies ?? []).every(dep => cachedSubtreeIsUsable(dep, visiting));
|
|
578
|
+
visiting.delete(fileIdentifier);
|
|
579
|
+
subtreeUsable.set(fileIdentifier, usable);
|
|
580
|
+
return usable;
|
|
581
|
+
}
|
|
582
|
+
// The cache key carries the package version, which is only a fingerprint of the content for
|
|
583
|
+
// something installed. A linked package changes underneath an unchanged version, and the graph
|
|
584
|
+
// records no mtime or hash to catch that, so those are always compiled afresh.
|
|
585
|
+
function cacheKeyIdentifiesContent(originalLocation) {
|
|
586
|
+
return slash(originalLocation).includes('/node_modules/');
|
|
587
|
+
}
|
|
548
588
|
const processedFilesCache = {};
|
|
549
589
|
async function processFile(fileInfo, sourceFilename, history) {
|
|
550
590
|
const {
|
|
@@ -554,7 +594,12 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
554
594
|
return processedFilesCache[file];
|
|
555
595
|
} else {
|
|
556
596
|
processedFilesCache[file] = fileInfo.packageInfo;
|
|
557
|
-
|
|
597
|
+
const cacheNode = opts.oldDependencyGraph[fileInfo.fileIdentifier];
|
|
598
|
+
if (cacheNode !== undefined && cachedSubtreeIsUsable(fileInfo.fileIdentifier, new Set())) {
|
|
599
|
+
await copyFileFromCache(fileInfo.fileIdentifier, cacheNode);
|
|
600
|
+
} else {
|
|
601
|
+
await doProcessFile(fileInfo, sourceFilename, history);
|
|
602
|
+
}
|
|
558
603
|
return processedFilesCache[file];
|
|
559
604
|
}
|
|
560
605
|
}
|
|
@@ -725,7 +770,22 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
725
770
|
// const location = source.value
|
|
726
771
|
// }
|
|
727
772
|
// }
|
|
773
|
+
// Resolution is this visitor's whole cost - ~2ms of node_modules walking per bare import -
|
|
774
|
+
// and the same specifier from the same directory resolves identically within a run
|
|
775
|
+
// (tungsten/jsx-runtime, from every component). Keyed on the importer's directory because
|
|
776
|
+
// both resolvers start their walk there. Lives as long as the plugin, like
|
|
777
|
+
// importedPackageFiles, so a package changed in place mid-session is stale in both.
|
|
778
|
+
const resolvedImports = new Map();
|
|
779
|
+
function resolveImportTarget(location, fromDir, requireFrom) {
|
|
780
|
+
const key = `${fromDir}\0${location}`;
|
|
781
|
+
const known = resolvedImports.get(key);
|
|
782
|
+
if (known !== undefined) return known;
|
|
783
|
+
const target = resolveBareImport(location, [fromDir]) ?? requireFrom.resolve(location);
|
|
784
|
+
resolvedImports.set(key, target);
|
|
785
|
+
return target;
|
|
786
|
+
}
|
|
728
787
|
return {
|
|
788
|
+
name: 'BabelTransformPackageImports',
|
|
729
789
|
pre(state) {
|
|
730
790
|
const stateFilename = state.opts.filename;
|
|
731
791
|
if (typeof stateFilename !== 'string') {
|
|
@@ -766,7 +826,7 @@ export function MakeBabelTransformPackageImports(opts) {
|
|
|
766
826
|
// the real file location of the file being imported.
|
|
767
827
|
// User code is served as ESM, so it resolves with the 'import'
|
|
768
828
|
// condition - see resolvePrecinctDependencies()
|
|
769
|
-
const importTarget =
|
|
829
|
+
const importTarget = resolveImportTarget(location, dirname(filename), require);
|
|
770
830
|
// Should do some checking here to show helpful errors about bad imports
|
|
771
831
|
if (importTarget === location) {
|
|
772
832
|
//console.log()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Value<Spec> = Spec extends `${string} ${string}...` ? string[] | undefined : Spec extends `${string} ${string}` ? string | undefined : boolean;
|
|
2
|
+
type Values<Specs> = {
|
|
3
|
+
[Name in keyof Specs]: Value<Specs[Name]>;
|
|
4
|
+
};
|
|
5
|
+
type Options = {
|
|
6
|
+
handledElsewhere?: readonly string[];
|
|
7
|
+
help?: readonly string[];
|
|
8
|
+
};
|
|
9
|
+
export declare function cliArgs<const Specs extends Record<string, string>>(specs: Specs, options?: Options): Values<Specs>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/bin/args.ts"],"names":[],"mappings":"AAQA,KAAK,KAAK,CAAC,IAAI,IACX,IAAI,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,GAAG,MAAM,EAAE,GAAG,SAAS,GACtD,IAAI,SAAS,GAAG,MAAM,IAAI,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,GACnD,OAAO,CAAA;AAErB,KAAK,MAAM,CAAC,KAAK,IAAI;KAAG,IAAI,IAAI,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;CAAE,CAAA;AAElE,KAAK,OAAO,GAAG;IACX,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3B,CAAA;AAED,wBAAgB,OAAO,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9D,KAAK,EAAE,KAAK,EACZ,OAAO,GAAE,OAAY,GACtB,MAAM,CAAC,KAAK,CAAC,CA6Df"}
|
package/dist/bin/args.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { cliError, cliOut } from "../cliOutput.js";
|
|
2
|
+
export function cliArgs(specs, options = {}) {
|
|
3
|
+
// after node and the script come the command word and its arguments
|
|
4
|
+
const [command = '', ...given] = process.argv.slice(2);
|
|
5
|
+
const {
|
|
6
|
+
handledElsewhere = [],
|
|
7
|
+
help = []
|
|
8
|
+
} = options;
|
|
9
|
+
const accepted = [...Object.values(specs), ...handledElsewhere];
|
|
10
|
+
const usage = `Usage: tungsten ${command}` + accepted.map(part => ` [${part}]`).join('');
|
|
11
|
+
if (given.includes('--help') || given.includes('-h')) {
|
|
12
|
+
cliOut([usage, ...help].join('\n'));
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
// a declaration rather than an arrow, so the checks below narrow past its never return
|
|
16
|
+
function fail(message) {
|
|
17
|
+
cliError(`tungsten ${command}: ${message}`);
|
|
18
|
+
cliOut(usage);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
const shapes = Object.values(specs).map(shapeOf);
|
|
22
|
+
const shapeByFlag = new Map(shapes.map(shape => [shape.flag, shape]));
|
|
23
|
+
const flagsGiven = new Set();
|
|
24
|
+
const valuesGiven = new Map();
|
|
25
|
+
const unknown = [];
|
|
26
|
+
const remaining = given.values();
|
|
27
|
+
for (const arg of remaining) {
|
|
28
|
+
const [flag, inlineValue] = splitInlineValue(arg);
|
|
29
|
+
const shape = shapeByFlag.get(flag);
|
|
30
|
+
if (shape === undefined) {
|
|
31
|
+
if (!handledElsewhere.includes(flag)) unknown.push(arg);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (!shape.takesValue) {
|
|
35
|
+
if (inlineValue !== undefined) fail(`${flag} takes no value`);
|
|
36
|
+
flagsGiven.add(flag);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
// "--output dist" takes its value from the same iteration, so the loop never sees it as a flag
|
|
40
|
+
const value = inlineValue ?? remaining.next().value;
|
|
41
|
+
// "--output --watch" is a value left out, not a value named --watch
|
|
42
|
+
if (value === undefined || value.startsWith('--')) fail(`${flag} requires a value`);
|
|
43
|
+
valuesGiven.set(flag, [...(valuesGiven.get(flag) ?? []), value]);
|
|
44
|
+
}
|
|
45
|
+
if (unknown.length > 0) fail(`unknown argument${unknown.length === 1 ? '' : 's'}: ${unknown.join(', ')}`);
|
|
46
|
+
const parsed = {};
|
|
47
|
+
for (const [name, spec] of Object.entries(specs)) {
|
|
48
|
+
const {
|
|
49
|
+
flag,
|
|
50
|
+
takesValue,
|
|
51
|
+
repeats
|
|
52
|
+
} = shapeOf(spec);
|
|
53
|
+
if (takesValue) {
|
|
54
|
+
const values = valuesGiven.get(flag);
|
|
55
|
+
parsed[name] = repeats ? values : values?.at(-1);
|
|
56
|
+
} else {
|
|
57
|
+
// --no-clean names what it turns off, so it reads true until given
|
|
58
|
+
const on = flagsGiven.has(flag);
|
|
59
|
+
parsed[name] = flag.startsWith('--no-') ? !on : on;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return parsed; // eslint-disable-line no-type-assertion/no-type-assertion -- built from specs' own keys
|
|
63
|
+
}
|
|
64
|
+
// '--ignore-dirs <dir>...' -> its flag, that it takes a value, and that it may be given more than once
|
|
65
|
+
function shapeOf(spec) {
|
|
66
|
+
const space = spec.indexOf(' ');
|
|
67
|
+
return {
|
|
68
|
+
flag: space === -1 ? spec : spec.slice(0, space),
|
|
69
|
+
takesValue: space !== -1,
|
|
70
|
+
repeats: spec.endsWith('...')
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// '--output=dist' -> ['--output', 'dist'], '--quiet' -> ['--quiet', undefined]
|
|
74
|
+
function splitInlineValue(arg) {
|
|
75
|
+
const equals = arg.indexOf('=');
|
|
76
|
+
return equals === -1 ? [arg, undefined] : [arg.slice(0, equals), arg.slice(equals + 1)];
|
|
77
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/build.ts"],"names":[],"mappings":"AAqEA,OAAO,EAAE,CAAA"}
|
|
@@ -3,10 +3,20 @@ import chalk from 'chalk-extensions';
|
|
|
3
3
|
import { Framework } from "../../Framework.js";
|
|
4
4
|
import { cliOut, cliNews, cliWarn } from "../../cliOutput.js";
|
|
5
5
|
import { staticSiteFolder } from "../../settings.js";
|
|
6
|
-
import { createTimeProfiler } from "../../timeProfiler.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import { createTimeProfiler, reportRunTotal, reportStartupPhase } from "../../timeProfiler.js";
|
|
7
|
+
import { cliArgs } from "../args.js";
|
|
8
|
+
// first statement in the body, so it closes off the import evaluation above
|
|
9
|
+
reportStartupPhase('load build modules');
|
|
10
|
+
// --help never reaches here - bin/index.ts routes it to buildHelp.ts before this module loads
|
|
11
|
+
const {
|
|
12
|
+
profile,
|
|
13
|
+
quiet
|
|
14
|
+
} = cliArgs({
|
|
15
|
+
profile: '--profile',
|
|
16
|
+
quiet: '--quiet'
|
|
17
|
+
}, {
|
|
18
|
+
handledElsewhere: ['--profile-modules']
|
|
19
|
+
});
|
|
10
20
|
//// prep the app
|
|
11
21
|
const sxyFramework = new Framework();
|
|
12
22
|
sxyFramework.profiler = createTimeProfiler(profile);
|
|
@@ -32,6 +42,7 @@ if (sxyFramework.config.staticSite) {
|
|
|
32
42
|
} else if (!quiet) {
|
|
33
43
|
cliNews(`Production build complete`);
|
|
34
44
|
}
|
|
45
|
+
reportRunTotal('total (build)');
|
|
35
46
|
// The build no longer holds anything open, so it ends by draining the event loop - hard-exiting
|
|
36
47
|
// here used to abort the process outright when an fs-extra copy still had a chmod in flight
|
|
37
48
|
// (libuv `!(handle->flags & UV_HANDLE_CLOSING)`). Safety net only, in case a future change
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// kept out of build.ts so --help does not pay for resolving the build's import tree
|
|
2
2
|
import { cliOut } from "../../cliOutput.js";
|
|
3
|
-
cliOut(`Usage: tungsten build [--profile] [--quiet]
|
|
3
|
+
cliOut(`Usage: tungsten build [--profile] [--profile-modules] [--quiet]
|
|
4
4
|
|
|
5
5
|
Options:
|
|
6
6
|
--profile report the time taken by each build phase
|
|
7
|
+
--profile-modules[=<path substring>]
|
|
8
|
+
report where module load time goes, splitting each import into what
|
|
9
|
+
only it needs and what it shares with its siblings
|
|
7
10
|
--quiet suppress progress output; warnings and errors still print`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/clean.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/clean.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,CAAA"}
|
|
@@ -3,6 +3,8 @@ import chalk from 'chalk-extensions';
|
|
|
3
3
|
import { Framework } from "../../Framework.js";
|
|
4
4
|
import { cliOut } from "../../cliOutput.js";
|
|
5
5
|
import { packageNameCapitalized } from "../../settings.js";
|
|
6
|
+
import { cliArgs } from "../args.js";
|
|
7
|
+
cliArgs({}); // accepts nothing but --help
|
|
6
8
|
//// prep the app
|
|
7
9
|
const sxyFramework = new Framework();
|
|
8
10
|
await sxyFramework.init();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/compile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/compile.ts"],"names":[],"mappings":"AAoRA,OAAO,EAAE,CAAA"}
|
|
@@ -11,92 +11,80 @@ import { createInstanceConfigFile } from "../../build/createInstanceConfigFile.j
|
|
|
11
11
|
import { getUserConfig } from "../../getUserConfig.js";
|
|
12
12
|
import { buildCodeSubPath, assetsFolder, clientFolder, componentCssFolder, devBuildOuterFolder, frameworkCssFolder, packagesCacheFolder, packagesFolder, publicFolder, staticFolder } from "../../settings.js";
|
|
13
13
|
import { cliError, cliNews, cliOut } from "../../cliOutput.js";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
import { createTimeProfiler, reportRunTotal, reportStartupPhase } from "../../timeProfiler.js";
|
|
15
|
+
import { cliArgs } from "../args.js";
|
|
16
|
+
// first statement in the body, so it closes off the import evaluation above
|
|
17
|
+
reportStartupPhase('load compile modules');
|
|
18
|
+
const {
|
|
19
|
+
js,
|
|
20
|
+
css,
|
|
21
|
+
client,
|
|
22
|
+
assets,
|
|
23
|
+
publicFiles,
|
|
24
|
+
all,
|
|
25
|
+
watch,
|
|
26
|
+
clean,
|
|
27
|
+
quiet,
|
|
28
|
+
packages,
|
|
29
|
+
profile,
|
|
30
|
+
output: outputOption,
|
|
31
|
+
readyFile: readyFileOption,
|
|
32
|
+
ignoreDirs,
|
|
33
|
+
ignorePatterns,
|
|
34
|
+
tests
|
|
35
|
+
} = cliArgs({
|
|
36
|
+
js: '--js',
|
|
37
|
+
css: '--css',
|
|
38
|
+
client: '--client',
|
|
39
|
+
assets: '--assets',
|
|
40
|
+
publicFiles: '--public',
|
|
41
|
+
all: '--all',
|
|
42
|
+
watch: '--watch',
|
|
43
|
+
clean: '--no-clean',
|
|
44
|
+
quiet: '--quiet',
|
|
45
|
+
packages: '--packages',
|
|
46
|
+
profile: '--profile',
|
|
47
|
+
output: '--output <dir>',
|
|
48
|
+
readyFile: '--ready-file <file>',
|
|
49
|
+
ignoreDirs: '--ignore-dirs <dir>...',
|
|
50
|
+
ignorePatterns: '--ignore-patterns <pattern>...',
|
|
51
|
+
tests: '--tests'
|
|
52
|
+
}, {
|
|
53
|
+
handledElsewhere: ['--profile-modules'],
|
|
54
|
+
help: ['With no target option (--js, --css, --client, --assets, --public), all targets are compiled.', ' --profile reports the time taken by each compile phase', ' --profile-modules[=<path substring>] reports where module load time goes,', ' splitting each import into what only it needs and what it shares', ' --packages compiles imported packages into the build\'s .packages tree', ' for the dev server to serve. Off by default: compiled code left to', ' node\'s own resolution, as tests use, needs none of it.', ' --ignore-dirs and --ignore-patterns override the config entries of the same name.', ' Repeat either to give several values, or pass an empty value to ignore nothing.', ' --tests also compiles the files the config\'s testPatterns match, which every', ' other compile leaves out.']
|
|
55
|
+
});
|
|
56
|
+
const allTargets = ['js', 'css', 'client', 'assets', 'public'];
|
|
57
|
+
const targetGiven = {
|
|
58
|
+
js,
|
|
59
|
+
css,
|
|
60
|
+
client,
|
|
61
|
+
assets,
|
|
62
|
+
public: publicFiles
|
|
20
63
|
};
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
24
|
-
cliOut(usage);
|
|
25
|
-
cliOut('Targets: --js, --css, --client, --assets, --public');
|
|
26
|
-
cliOut('With no target options, all targets are compiled.');
|
|
27
|
-
cliOut('Options: --output <dir>, --ready-file <file>, --quiet');
|
|
28
|
-
cliOut(' --packages compiles imported packages into the build\'s .packages tree');
|
|
29
|
-
cliOut(' for the dev server to serve. Off by default: compiled code left to');
|
|
30
|
-
cliOut(' node\'s own resolution, as tests use, needs none of it.');
|
|
31
|
-
cliOut(' --ignore-dirs <dir>, --ignore-patterns <pattern>');
|
|
32
|
-
cliOut(' override the config entries of the same name. Repeat the option to');
|
|
33
|
-
cliOut(' give several values, or pass an empty value to ignore nothing.');
|
|
34
|
-
process.exit(0);
|
|
35
|
-
}
|
|
36
|
-
const commandOptions = new Set(['--all', '--watch', '--no-clean', '--quiet', '--packages']);
|
|
37
|
-
const valueOptions = new Set(['--output', '--ready-file', '--ignore-dirs', '--ignore-patterns']);
|
|
38
|
-
// values are collected per option so that the list options can be repeated
|
|
39
|
-
const givenOptionValues = new Map();
|
|
40
|
-
const unknownOptions = [];
|
|
41
|
-
let consumedPosition = -1;
|
|
42
|
-
for (const [position, arg] of args.entries()) {
|
|
43
|
-
if (position === consumedPosition) continue; // already taken as an option value
|
|
44
|
-
if (arg in targetOptions || commandOptions.has(arg)) continue;
|
|
45
|
-
if (valueOptions.has(arg)) {
|
|
46
|
-
const value = args[position + 1];
|
|
47
|
-
if (value === undefined || value.startsWith('--')) {
|
|
48
|
-
cliError(`${arg} requires a value`);
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
const values = givenOptionValues.get(arg);
|
|
52
|
-
if (values === undefined) givenOptionValues.set(arg, [value]);else values.push(value);
|
|
53
|
-
consumedPosition = position + 1;
|
|
54
|
-
} else {
|
|
55
|
-
unknownOptions.push(arg);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (unknownOptions.length > 0) {
|
|
59
|
-
cliError(`Unknown compile option${unknownOptions.length === 1 ? '' : 's'}: ${unknownOptions.join(', ')}`);
|
|
60
|
-
cliOut(usage);
|
|
61
|
-
process.exit(1);
|
|
62
|
-
}
|
|
63
|
-
function optionValue(option) {
|
|
64
|
-
return givenOptionValues.get(option)?.at(-1);
|
|
65
|
-
}
|
|
64
|
+
const requestedTargets = allTargets.filter(target => targetGiven[target]);
|
|
65
|
+
const targets = new Set(all || requestedTargets.length === 0 ? allTargets : requestedTargets);
|
|
66
66
|
// undefined leaves the config entry alone, '' clears it
|
|
67
|
-
function
|
|
68
|
-
const values = givenOptionValues.get(option);
|
|
67
|
+
function configOverride(values) {
|
|
69
68
|
if (values === undefined) return undefined;
|
|
70
69
|
const entries = values.filter(value => value !== '');
|
|
71
70
|
return entries.length === 0 ? '' : entries;
|
|
72
71
|
}
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
const requestedTargets = new Set();
|
|
78
|
-
for (const arg of args) {
|
|
79
|
-
const target = targetOptions[arg];
|
|
80
|
-
if (target !== undefined) requestedTargets.add(target);
|
|
81
|
-
}
|
|
82
|
-
const targets = requestedTargets.size === 0 || args.includes('--all') ? new Set(['js', 'css', 'client', 'assets', 'public']) : requestedTargets;
|
|
83
|
-
const watch = args.includes('--watch');
|
|
84
|
-
const clean = !args.includes('--no-clean');
|
|
85
|
-
const quiet = args.includes('--quiet');
|
|
86
|
-
const compilePackages = args.includes('--packages');
|
|
87
|
-
if (compilePackages && !targets.has('js')) {
|
|
72
|
+
const ignoreDirsOption = configOverride(ignoreDirs);
|
|
73
|
+
const ignorePatternsOption = configOverride(ignorePatterns);
|
|
74
|
+
const profiler = createTimeProfiler(profile);
|
|
75
|
+
if (packages && !targets.has('js')) {
|
|
88
76
|
cliError('--packages applies to the js target, which is not being compiled');
|
|
89
77
|
process.exit(1);
|
|
90
78
|
}
|
|
91
79
|
const projectDir = process.cwd();
|
|
92
|
-
const config = await getUserConfig({
|
|
80
|
+
const config = await profiler.timeProfileAsync('init', () => getUserConfig({
|
|
93
81
|
...(ignoreDirsOption !== undefined ? {
|
|
94
82
|
ignoreDirs: ignoreDirsOption
|
|
95
83
|
} : {}),
|
|
96
84
|
...(ignorePatternsOption !== undefined ? {
|
|
97
85
|
ignorePatterns: ignorePatternsOption
|
|
98
86
|
} : {})
|
|
99
|
-
});
|
|
87
|
+
}));
|
|
100
88
|
const codeLocation = join(projectDir, config.codeDir);
|
|
101
89
|
const relSourceDir = config.sourceDir !== undefined && config.sourceDir !== '' ? config.sourceDir : config.codeDir;
|
|
102
90
|
const sourceLocation = join(projectDir, relSourceDir);
|
|
@@ -144,14 +132,15 @@ if (clean) {
|
|
|
144
132
|
if (targets.has('assets')) cleanTasks.push(removeRecursive(join(buildLocation, assetsFolder)));
|
|
145
133
|
if (targets.has('public')) cleanTasks.push(removeRecursive(join(buildLocation, publicFolder)));
|
|
146
134
|
cliOut(`Cleaning compile output: ${[...targets].join(', ')}`);
|
|
147
|
-
await Promise.all(cleanTasks);
|
|
135
|
+
await profiler.timeProfileAsync('clean', () => Promise.all(cleanTasks));
|
|
148
136
|
}
|
|
149
137
|
const compilationTasks = [];
|
|
150
138
|
let javascriptInitialSuccess = true;
|
|
151
139
|
if (targets.has('js')) {
|
|
152
|
-
const javascriptTask = compileJavascript(projectDir, config, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, 'dev', watch, {
|
|
140
|
+
const javascriptTask = profiler.timeProfileAsync('compile javascript', () => compileJavascript(projectDir, config, codeLocation, sourceLocation, styleImportBase, buildLocation, buildCodeLocation, 'dev', watch, {
|
|
153
141
|
quiet,
|
|
154
|
-
packages
|
|
142
|
+
packages,
|
|
143
|
+
tests,
|
|
155
144
|
packagesCacheLocation,
|
|
156
145
|
onCycleComplete: watch ? async cycle => {
|
|
157
146
|
if (cycle.success) {
|
|
@@ -162,29 +151,31 @@ if (targets.has('js')) {
|
|
|
162
151
|
cliError(`Compile cycle failed: js${cycle.file !== undefined ? ` (${cycle.file})` : ''}`);
|
|
163
152
|
}
|
|
164
153
|
} : undefined
|
|
165
|
-
});
|
|
154
|
+
}));
|
|
166
155
|
compilationTasks.push(javascriptTask.then(result => {
|
|
167
156
|
javascriptInitialSuccess = result.initialSuccess;
|
|
168
157
|
return result;
|
|
169
158
|
}));
|
|
170
159
|
}
|
|
171
160
|
if (targets.has('css')) {
|
|
172
|
-
compilationTasks.push(compileStyles(projectDir, config, styleImportBase, buildLocation, watch));
|
|
161
|
+
compilationTasks.push(profiler.timeProfileAsync('compile styles', () => compileStyles(projectDir, config, styleImportBase, buildLocation, watch)));
|
|
173
162
|
}
|
|
174
163
|
if (targets.has('client')) {
|
|
175
|
-
compilationTasks.push(createInstanceConfigFile(config, 'dev', buildLocation));
|
|
176
|
-
compilationTasks.push(createClientFiles(config, 'dev', buildLocation));
|
|
164
|
+
compilationTasks.push(profiler.timeProfileAsync('create instance config', () => createInstanceConfigFile(config, 'dev', buildLocation)));
|
|
165
|
+
compilationTasks.push(profiler.timeProfileAsync('create client files', () => createClientFiles(config, 'dev', buildLocation)));
|
|
177
166
|
}
|
|
178
167
|
if (targets.has('assets')) {
|
|
179
168
|
// copyAssets resolves to undefined when there is no assets dir - nothing to skip here
|
|
180
|
-
compilationTasks.push(copyAssets(projectDir, config, buildLocation, watch));
|
|
169
|
+
compilationTasks.push(profiler.timeProfileAsync('copy assets', () => copyAssets(projectDir, config, buildLocation, watch)));
|
|
181
170
|
}
|
|
182
171
|
if (targets.has('public')) {
|
|
183
|
-
compilationTasks.push(copyPublicFiles(projectDir, config, buildLocation, watch));
|
|
172
|
+
compilationTasks.push(profiler.timeProfileAsync('copy public files', () => copyPublicFiles(projectDir, config, buildLocation, watch)));
|
|
184
173
|
}
|
|
185
|
-
const compilationResults = await Promise.allSettled(compilationTasks);
|
|
174
|
+
const compilationResults = await profiler.timeProfileAsync('compile targets', () => Promise.allSettled(compilationTasks));
|
|
186
175
|
// after the js task: the package walk that records the stylesheets runs inside it
|
|
187
|
-
if (targets.has('js'))
|
|
176
|
+
if (targets.has('js')) {
|
|
177
|
+
await profiler.timeProfileAsync('write framework css', () => writeFrameworkCss(buildLocation));
|
|
178
|
+
}
|
|
188
179
|
const failures = compilationResults.filter(result => result.status === 'rejected').map(result => result.reason);
|
|
189
180
|
const initialSuccess = failures.length === 0 && javascriptInitialSuccess;
|
|
190
181
|
if (initialSuccess) {
|
|
@@ -194,6 +185,7 @@ if (initialSuccess) {
|
|
|
194
185
|
await clearReadyFile();
|
|
195
186
|
cliError(`Compile failed: ${[...targets].join(', ')}`);
|
|
196
187
|
}
|
|
188
|
+
reportRunTotal('total (compile)');
|
|
197
189
|
if (!watch && !initialSuccess) {
|
|
198
190
|
throw new AggregateError(failures, 'Compilation failed');
|
|
199
191
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/dev.ts"],"names":[],"mappings":"AAuEA,OAAO,EAAE,CAAA"}
|
package/dist/bin/commands/dev.js
CHANGED
|
@@ -2,16 +2,29 @@ import open from 'open';
|
|
|
2
2
|
import { cliOut } from "../../cliOutput.js";
|
|
3
3
|
import { Framework } from "../../Framework.js";
|
|
4
4
|
import { warnOnFrameworkChange } from "../../warnOnFrameworkChange.js";
|
|
5
|
-
import { createTimeProfiler } from "../../timeProfiler.js";
|
|
5
|
+
import { createTimeProfiler, reportRunTotal, reportStartupPhase } from "../../timeProfiler.js";
|
|
6
|
+
import { cliArgs } from "../args.js";
|
|
6
7
|
//import dotenv from 'dotenv'
|
|
7
8
|
//dotenv.config({ path: '.private.env' })
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
9
|
+
// first statement in the body, so it closes off the import evaluation above
|
|
10
|
+
reportStartupPhase('load dev modules');
|
|
11
|
+
const {
|
|
12
|
+
boot,
|
|
13
|
+
profile,
|
|
14
|
+
tests
|
|
15
|
+
} = cliArgs({
|
|
16
|
+
boot: '--no-boot',
|
|
17
|
+
profile: '--profile',
|
|
18
|
+
// also compile the files config.testDirs/testPatterns match - normally only a test compile does
|
|
19
|
+
tests: '--tests'
|
|
20
|
+
}, {
|
|
21
|
+
handledElsewhere: ['--profile-modules']
|
|
22
|
+
});
|
|
11
23
|
//// prep the app
|
|
12
24
|
const sxyFramework = new Framework();
|
|
13
25
|
sxyFramework.profiler = createTimeProfiler(profile);
|
|
14
|
-
|
|
26
|
+
sxyFramework.tests = tests;
|
|
27
|
+
const config = await sxyFramework.init();
|
|
15
28
|
//console.log('framework ready')
|
|
16
29
|
// build for dev
|
|
17
30
|
cliOut('Removing old builds');
|
|
@@ -26,12 +39,14 @@ const devServer = await sxyFramework.createDevServer();
|
|
|
26
39
|
const devServerLocation = await sxyFramework.profiler.timeProfileAsync('start dev server', () => devServer.start());
|
|
27
40
|
// devmon already restarts this process itself on a framework rebuild, so the warning
|
|
28
41
|
// (which just tells you to restart manually) would be redundant noise under it - see devmon.ts.
|
|
29
|
-
if (
|
|
42
|
+
if (config.warnOnFrameworkChange && process.env.__TUNGSTEN_DEVMON !== 'true') {
|
|
30
43
|
warnOnFrameworkChange();
|
|
31
44
|
}
|
|
32
45
|
// do a dummy request to trigger any error immediately during dev
|
|
33
46
|
//axios.get(sxyFramework.devServer.location)
|
|
34
47
|
if (boot) {
|
|
35
48
|
cliOut('Booting to the dev site in your browser');
|
|
36
|
-
open
|
|
37
|
-
|
|
49
|
+
// awaited only so it can be timed - open resolves once the browser process is spawned
|
|
50
|
+
await sxyFramework.profiler.timeProfileAsync('boot browser', () => open(devServerLocation));
|
|
51
|
+
}
|
|
52
|
+
reportRunTotal('total (dev startup)');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devmon.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/devmon.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"devmon.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/devmon.ts"],"names":[],"mappings":"AAiEA,OAAO,EAAE,CAAA"}
|