@steambrew/ttc 3.0.1 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +2 -1
- package/dist/index.js +84 -10
- package/package.json +2 -1
- package/src/check-health.ts +3 -2
- package/src/index.ts +6 -3
- package/src/logger.ts +5 -0
- package/src/plugin-json.d.ts +16 -0
- package/src/query-parser.ts +10 -2
- package/src/static-embed.ts +3 -1
- package/src/transpiler.ts +73 -4
package/dist/index.js
CHANGED
|
@@ -13,18 +13,18 @@ import terser from '@rollup/plugin-terser';
|
|
|
13
13
|
import typescript from '@rollup/plugin-typescript';
|
|
14
14
|
import url from '@rollup/plugin-url';
|
|
15
15
|
import nodePolyfills from 'rollup-plugin-polyfill-node';
|
|
16
|
-
import { rollup } from 'rollup';
|
|
16
|
+
import { watch, rollup } from 'rollup';
|
|
17
17
|
import { minify_sync } from 'terser';
|
|
18
18
|
import scss from 'rollup-plugin-scss';
|
|
19
19
|
import * as sass from 'sass';
|
|
20
20
|
import dotenv from 'dotenv';
|
|
21
21
|
import injectProcessEnv from 'rollup-plugin-inject-process-env';
|
|
22
|
+
import { performance } from 'perf_hooks';
|
|
22
23
|
import * as parser from '@babel/parser';
|
|
23
24
|
import { createFilter } from '@rollup/pluginutils';
|
|
24
25
|
import * as glob from 'glob';
|
|
25
26
|
import MagicString from 'magic-string';
|
|
26
27
|
import _traverse from '@babel/traverse';
|
|
27
|
-
import { performance as performance$1 } from 'perf_hooks';
|
|
28
28
|
|
|
29
29
|
const version = JSON.parse(readFileSync(path.resolve(dirname(fileURLToPath(import.meta.url)), '../package.json'), 'utf8')).version;
|
|
30
30
|
const Logger = {
|
|
@@ -59,6 +59,10 @@ const Logger = {
|
|
|
59
59
|
meta.push(`${envCount} env var${envCount > 1 ? 's' : ''}`);
|
|
60
60
|
console.log(`${chalk.green('Finished')} ${buildType} in ${elapsed} ` + chalk.dim('(' + meta.join(', ') + ')'));
|
|
61
61
|
},
|
|
62
|
+
failed({ elapsedMs, buildType }) {
|
|
63
|
+
const elapsed = `${(elapsedMs / 1000).toFixed(2)}s`;
|
|
64
|
+
console.error(`${chalk.red('Failed')} ${buildType} in ${elapsed} ` + chalk.dim(`(ttc v${version})`));
|
|
65
|
+
},
|
|
62
66
|
};
|
|
63
67
|
|
|
64
68
|
const PrintParamHelp = () => {
|
|
@@ -69,6 +73,7 @@ const PrintParamHelp = () => {
|
|
|
69
73
|
'options:',
|
|
70
74
|
' --build <dev|prod> build type (prod enables minification)',
|
|
71
75
|
' --target <path> plugin directory (default: current directory)',
|
|
76
|
+
' --watch enable watch mode for continuous rebuilding',
|
|
72
77
|
' --no-update skip update check',
|
|
73
78
|
' --help show this message',
|
|
74
79
|
'',
|
|
@@ -80,7 +85,7 @@ var BuildType;
|
|
|
80
85
|
BuildType[BuildType["ProdBuild"] = 1] = "ProdBuild";
|
|
81
86
|
})(BuildType || (BuildType = {}));
|
|
82
87
|
const ValidateParameters = (args) => {
|
|
83
|
-
let typeProp = BuildType.DevBuild, targetProp = process.cwd(), isMillennium = false;
|
|
88
|
+
let typeProp = BuildType.DevBuild, targetProp = process.cwd(), isMillennium = false, watch = false;
|
|
84
89
|
if (args.includes('--help')) {
|
|
85
90
|
PrintParamHelp();
|
|
86
91
|
process.exit();
|
|
@@ -116,11 +121,15 @@ const ValidateParameters = (args) => {
|
|
|
116
121
|
if (args[i] == '--millennium-internal') {
|
|
117
122
|
isMillennium = true;
|
|
118
123
|
}
|
|
124
|
+
if (args[i] === '--watch') {
|
|
125
|
+
watch = true;
|
|
126
|
+
}
|
|
119
127
|
}
|
|
120
128
|
return {
|
|
121
129
|
type: typeProp,
|
|
122
130
|
targetPlugin: targetProp,
|
|
123
|
-
isMillennium
|
|
131
|
+
isMillennium,
|
|
132
|
+
watch,
|
|
124
133
|
};
|
|
125
134
|
};
|
|
126
135
|
|
|
@@ -415,6 +424,7 @@ function constSysfsExpr(options = {}) {
|
|
|
415
424
|
fileName: path.relative(searchBasePath, singleFilePath),
|
|
416
425
|
};
|
|
417
426
|
embeddedContent = JSON.stringify(fileInfo);
|
|
427
|
+
this.addWatchFile(singleFilePath);
|
|
418
428
|
}
|
|
419
429
|
catch (fileError) {
|
|
420
430
|
let message = String(fileError instanceof Error ? fileError.message : fileError ?? 'Unknown file read error');
|
|
@@ -438,6 +448,7 @@ function constSysfsExpr(options = {}) {
|
|
|
438
448
|
filePath: fullPath,
|
|
439
449
|
fileName: path.relative(searchBasePath, fullPath),
|
|
440
450
|
});
|
|
451
|
+
this.addWatchFile(fullPath);
|
|
441
452
|
}
|
|
442
453
|
catch (fileError) {
|
|
443
454
|
let message = String(fileError instanceof Error ? fileError.message : fileError ?? 'Unknown file read error');
|
|
@@ -554,6 +565,8 @@ function stripPluginPrefix(message) {
|
|
|
554
565
|
message = message.replace(/^@?[\w-]+\/[\w-]+\s+/, '');
|
|
555
566
|
return message;
|
|
556
567
|
}
|
|
568
|
+
class BuildFailedError extends Error {
|
|
569
|
+
}
|
|
557
570
|
class MillenniumBuild {
|
|
558
571
|
isExternal(id) {
|
|
559
572
|
const hint = this.forbidden.get(id);
|
|
@@ -563,6 +576,25 @@ class MillenniumBuild {
|
|
|
563
576
|
}
|
|
564
577
|
return this.externals.has(id);
|
|
565
578
|
}
|
|
579
|
+
async watchConfig(input, sysfsPlugin, isMillennium) {
|
|
580
|
+
return {
|
|
581
|
+
input,
|
|
582
|
+
plugins: await this.plugins(sysfsPlugin),
|
|
583
|
+
onwarn: (warning) => {
|
|
584
|
+
const msg = stripPluginPrefix(warning.message);
|
|
585
|
+
const loc = logLocation(warning);
|
|
586
|
+
if (warning.plugin === 'typescript') {
|
|
587
|
+
Logger.error(msg, loc);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
Logger.warn(msg, loc);
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
context: 'window',
|
|
594
|
+
external: (id) => this.isExternal(id),
|
|
595
|
+
output: this.output(isMillennium),
|
|
596
|
+
};
|
|
597
|
+
}
|
|
566
598
|
async build(input, sysfsPlugin, isMillennium) {
|
|
567
599
|
let hasErrors = false;
|
|
568
600
|
const config = {
|
|
@@ -585,7 +617,7 @@ class MillenniumBuild {
|
|
|
585
617
|
};
|
|
586
618
|
await (await rollup(config)).write(config.output);
|
|
587
619
|
if (hasErrors)
|
|
588
|
-
|
|
620
|
+
throw new BuildFailedError();
|
|
589
621
|
}
|
|
590
622
|
}
|
|
591
623
|
class FrontendBuild extends MillenniumBuild {
|
|
@@ -679,10 +711,47 @@ class WebkitBuild extends MillenniumBuild {
|
|
|
679
711
|
};
|
|
680
712
|
}
|
|
681
713
|
}
|
|
682
|
-
|
|
714
|
+
function RunWatchMode(frontendConfig, webkitConfig) {
|
|
715
|
+
const configs = webkitConfig ? [frontendConfig, webkitConfig] : [frontendConfig];
|
|
716
|
+
const watcher = watch(configs);
|
|
717
|
+
console.log(chalk.blueBright.bold('watch'), 'watching for file changes...');
|
|
718
|
+
watcher.on('event', async (event) => {
|
|
719
|
+
if (event.code === 'BUNDLE_START') {
|
|
720
|
+
const label = event.output.some((f) => f.includes('index.js')) ? 'frontend' : 'webkit';
|
|
721
|
+
console.log(chalk.yellowBright.bold('watch'), `rebuilding ${label}...`);
|
|
722
|
+
}
|
|
723
|
+
else if (event.code === 'BUNDLE_END') {
|
|
724
|
+
const label = event.output.some((f) => f.includes('index.js')) ? 'frontend' : 'webkit';
|
|
725
|
+
console.log(chalk.greenBright.bold('watch'), `${label} built in ${chalk.green(`${event.duration}ms`)}`);
|
|
726
|
+
await event.result.close();
|
|
727
|
+
}
|
|
728
|
+
else if (event.code === 'ERROR') {
|
|
729
|
+
const err = event.error;
|
|
730
|
+
const msg = stripPluginPrefix(err?.message ?? String(err));
|
|
731
|
+
Logger.error(msg, logLocation(err));
|
|
732
|
+
if (event.result)
|
|
733
|
+
await event.result.close();
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
const shutdown = () => {
|
|
737
|
+
console.log(chalk.yellowBright.bold('watch'), 'stopping...');
|
|
738
|
+
watcher.close();
|
|
739
|
+
process.exit(0);
|
|
740
|
+
};
|
|
741
|
+
process.on('SIGINT', shutdown);
|
|
742
|
+
process.on('SIGUSR2', shutdown);
|
|
743
|
+
}
|
|
744
|
+
const TranspilerPluginComponent = async (pluginJson, props) => {
|
|
683
745
|
const webkitDir = './webkit/index.tsx';
|
|
684
746
|
const frontendDir = getFrontendDir(pluginJson);
|
|
685
747
|
const sysfs = constSysfsExpr();
|
|
748
|
+
const isMillennium = props.isMillennium ?? false;
|
|
749
|
+
if (props.watch) {
|
|
750
|
+
const frontendConfig = await new FrontendBuild(frontendDir, props).watchConfig(resolveEntryFile(frontendDir), sysfs.plugin, isMillennium);
|
|
751
|
+
const webkitConfig = fs.existsSync(webkitDir) ? await new WebkitBuild(props).watchConfig(webkitDir, sysfs.plugin, isMillennium) : null;
|
|
752
|
+
RunWatchMode(frontendConfig, webkitConfig);
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
686
755
|
try {
|
|
687
756
|
await new FrontendBuild(frontendDir, props).build(resolveEntryFile(frontendDir), sysfs.plugin, isMillennium);
|
|
688
757
|
if (fs.existsSync(webkitDir)) {
|
|
@@ -696,7 +765,10 @@ const TranspilerPluginComponent = async (isMillennium, pluginJson, props) => {
|
|
|
696
765
|
});
|
|
697
766
|
}
|
|
698
767
|
catch (exception) {
|
|
699
|
-
|
|
768
|
+
if (!(exception instanceof BuildFailedError)) {
|
|
769
|
+
Logger.error(stripPluginPrefix(exception?.message ?? String(exception)), logLocation(exception));
|
|
770
|
+
}
|
|
771
|
+
Logger.failed({ elapsedMs: performance.now() - global.PerfStartTime, buildType: props.minify ? 'prod' : 'dev' });
|
|
700
772
|
process.exit(1);
|
|
701
773
|
}
|
|
702
774
|
};
|
|
@@ -717,16 +789,18 @@ const StartCompilerModule = () => {
|
|
|
717
789
|
.then((json) => {
|
|
718
790
|
const props = {
|
|
719
791
|
minify: bTersePlugin,
|
|
720
|
-
pluginName: json
|
|
792
|
+
pluginName: json.name,
|
|
793
|
+
watch: parameters.watch || false,
|
|
794
|
+
isMillennium: bIsMillennium,
|
|
721
795
|
};
|
|
722
|
-
TranspilerPluginComponent(
|
|
796
|
+
TranspilerPluginComponent(json, props);
|
|
723
797
|
})
|
|
724
798
|
.catch(() => {
|
|
725
799
|
process.exit();
|
|
726
800
|
});
|
|
727
801
|
};
|
|
728
802
|
const Initialize = () => {
|
|
729
|
-
global.PerfStartTime = performance
|
|
803
|
+
global.PerfStartTime = performance.now();
|
|
730
804
|
// Check for --no-update flag
|
|
731
805
|
if (process.argv.includes('--no-update')) {
|
|
732
806
|
StartCompilerModule();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steambrew/ttc",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "rollup -c",
|
|
12
|
+
"dev": "rollup -c -w",
|
|
12
13
|
"prepare": "bun run build"
|
|
13
14
|
},
|
|
14
15
|
"publishConfig": {
|
package/src/check-health.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { existsSync, readFile } from 'fs';
|
|
3
3
|
import { Logger } from './logger';
|
|
4
|
+
import { PluginJson } from './plugin-json';
|
|
4
5
|
|
|
5
|
-
export const ValidatePlugin = (bIsMillennium: boolean, target: string): Promise<
|
|
6
|
-
return new Promise<
|
|
6
|
+
export const ValidatePlugin = (bIsMillennium: boolean, target: string): Promise<PluginJson> => {
|
|
7
|
+
return new Promise<PluginJson>((resolve, reject) => {
|
|
7
8
|
if (!existsSync(target)) {
|
|
8
9
|
Logger.error(`target path does not exist: ${target}`);
|
|
9
10
|
reject();
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { BuildType, ValidateParameters } from './query-parser';
|
|
9
9
|
import { CheckForUpdates } from './version-control';
|
|
10
10
|
import { ValidatePlugin } from './check-health';
|
|
11
|
+
import { PluginJson } from './plugin-json';
|
|
11
12
|
import { TranspilerPluginComponent, TranspilerProps } from './transpiler';
|
|
12
13
|
import { performance } from 'perf_hooks';
|
|
13
14
|
|
|
@@ -25,13 +26,15 @@ const StartCompilerModule = () => {
|
|
|
25
26
|
const bTersePlugin = parameters.type == BuildType.ProdBuild;
|
|
26
27
|
|
|
27
28
|
ValidatePlugin(bIsMillennium, parameters.targetPlugin)
|
|
28
|
-
.then((json:
|
|
29
|
+
.then((json: PluginJson) => {
|
|
29
30
|
const props: TranspilerProps = {
|
|
30
31
|
minify: bTersePlugin,
|
|
31
|
-
pluginName: json
|
|
32
|
+
pluginName: json.name,
|
|
33
|
+
watch: parameters.watch || false,
|
|
34
|
+
isMillennium: bIsMillennium,
|
|
32
35
|
};
|
|
33
36
|
|
|
34
|
-
TranspilerPluginComponent(
|
|
37
|
+
TranspilerPluginComponent(json, props);
|
|
35
38
|
})
|
|
36
39
|
.catch(() => {
|
|
37
40
|
process.exit();
|
package/src/logger.ts
CHANGED
|
@@ -44,6 +44,11 @@ const Logger = {
|
|
|
44
44
|
if (envCount) meta.push(`${envCount} env var${envCount > 1 ? 's' : ''}`);
|
|
45
45
|
console.log(`${chalk.green('Finished')} ${buildType} in ${elapsed} ` + chalk.dim('(' + meta.join(', ') + ')'));
|
|
46
46
|
},
|
|
47
|
+
|
|
48
|
+
failed({ elapsedMs, buildType }: Pick<DoneOptions, 'elapsedMs' | 'buildType'>) {
|
|
49
|
+
const elapsed = `${(elapsedMs / 1000).toFixed(2)}s`;
|
|
50
|
+
console.error(`${chalk.red('Failed')} ${buildType} in ${elapsed} ` + chalk.dim(`(ttc v${version})`));
|
|
51
|
+
},
|
|
47
52
|
};
|
|
48
53
|
|
|
49
54
|
export { Logger };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generated from https://raw.githubusercontent.com/SteamClientHomebrew/Millennium/main/src/sys/plugin-schema.json
|
|
3
|
+
*/
|
|
4
|
+
export interface PluginJson {
|
|
5
|
+
backend?: string;
|
|
6
|
+
common_name?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
frontend?: string;
|
|
9
|
+
include?: string[];
|
|
10
|
+
name: string;
|
|
11
|
+
splash_image?: string;
|
|
12
|
+
thumbnail?: string;
|
|
13
|
+
useBackend?: boolean;
|
|
14
|
+
venv?: string;
|
|
15
|
+
version?: string;
|
|
16
|
+
}
|
package/src/query-parser.ts
CHANGED
|
@@ -9,6 +9,7 @@ export const PrintParamHelp = () => {
|
|
|
9
9
|
'options:',
|
|
10
10
|
' --build <dev|prod> build type (prod enables minification)',
|
|
11
11
|
' --target <path> plugin directory (default: current directory)',
|
|
12
|
+
' --watch enable watch mode for continuous rebuilding',
|
|
12
13
|
' --no-update skip update check',
|
|
13
14
|
' --help show this message',
|
|
14
15
|
'',
|
|
@@ -25,12 +26,14 @@ export interface ParameterProps {
|
|
|
25
26
|
type: BuildType;
|
|
26
27
|
targetPlugin: string; // path
|
|
27
28
|
isMillennium?: boolean;
|
|
29
|
+
watch?: boolean;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export const ValidateParameters = (args: Array<string>): ParameterProps => {
|
|
31
33
|
let typeProp: BuildType = BuildType.DevBuild,
|
|
32
34
|
targetProp: string = process.cwd(),
|
|
33
|
-
isMillennium: boolean = false
|
|
35
|
+
isMillennium: boolean = false,
|
|
36
|
+
watch: boolean = false;
|
|
34
37
|
|
|
35
38
|
if (args.includes('--help')) {
|
|
36
39
|
PrintParamHelp();
|
|
@@ -73,11 +76,16 @@ export const ValidateParameters = (args: Array<string>): ParameterProps => {
|
|
|
73
76
|
if (args[i] == '--millennium-internal') {
|
|
74
77
|
isMillennium = true;
|
|
75
78
|
}
|
|
79
|
+
|
|
80
|
+
if (args[i] === '--watch') {
|
|
81
|
+
watch = true;
|
|
82
|
+
}
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
return {
|
|
79
86
|
type: typeProp,
|
|
80
87
|
targetPlugin: targetProp,
|
|
81
|
-
isMillennium
|
|
88
|
+
isMillennium,
|
|
89
|
+
watch,
|
|
82
90
|
};
|
|
83
91
|
};
|
package/src/static-embed.ts
CHANGED
|
@@ -206,7 +206,8 @@ export default function constSysfsExpr(options: EmbedPluginOptions = {}): SysfsP
|
|
|
206
206
|
fileName: path.relative(searchBasePath, singleFilePath),
|
|
207
207
|
};
|
|
208
208
|
embeddedContent = JSON.stringify(fileInfo);
|
|
209
|
-
|
|
209
|
+
this.addWatchFile(singleFilePath);
|
|
210
|
+
} catch (fileError: unknown) {
|
|
210
211
|
let message = String(fileError instanceof Error ? fileError.message : fileError ?? 'Unknown file read error');
|
|
211
212
|
this.error(`Error reading file ${singleFilePath}: ${message}`, node.loc?.start.index);
|
|
212
213
|
return;
|
|
@@ -230,6 +231,7 @@ export default function constSysfsExpr(options: EmbedPluginOptions = {}): SysfsP
|
|
|
230
231
|
filePath: fullPath,
|
|
231
232
|
fileName: path.relative(searchBasePath, fullPath),
|
|
232
233
|
});
|
|
234
|
+
this.addWatchFile(fullPath);
|
|
233
235
|
} catch (fileError: unknown) {
|
|
234
236
|
let message = String(fileError instanceof Error ? fileError.message : fileError ?? 'Unknown file read error');
|
|
235
237
|
this.warn(`Error reading file ${fullPath}: ${message}`);
|
package/src/transpiler.ts
CHANGED
|
@@ -7,7 +7,8 @@ import terser from '@rollup/plugin-terser';
|
|
|
7
7
|
import typescript from '@rollup/plugin-typescript';
|
|
8
8
|
import url from '@rollup/plugin-url';
|
|
9
9
|
import nodePolyfills from 'rollup-plugin-polyfill-node';
|
|
10
|
-
import
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
import { InputPluginOption, OutputBundle, OutputOptions, Plugin, RollupOptions, rollup, watch as rollupWatch } from 'rollup';
|
|
11
12
|
import { minify_sync } from 'terser';
|
|
12
13
|
import scss from 'rollup-plugin-scss';
|
|
13
14
|
import * as sass from 'sass';
|
|
@@ -16,8 +17,10 @@ import path from 'path';
|
|
|
16
17
|
import { pathToFileURL } from 'url';
|
|
17
18
|
import dotenv from 'dotenv';
|
|
18
19
|
import injectProcessEnv from 'rollup-plugin-inject-process-env';
|
|
20
|
+
import { performance } from 'perf_hooks';
|
|
19
21
|
import { ExecutePluginModule, InitializePlugins } from './plugin-api';
|
|
20
22
|
import { Logger } from './logger';
|
|
23
|
+
import { PluginJson } from './plugin-json';
|
|
21
24
|
import constSysfsExpr from './static-embed';
|
|
22
25
|
|
|
23
26
|
const env = dotenv.config().parsed ?? {};
|
|
@@ -41,6 +44,8 @@ declare const __call_server_method__: (methodName: string, kwargs: any) => any;
|
|
|
41
44
|
export interface TranspilerProps {
|
|
42
45
|
minify: boolean;
|
|
43
46
|
pluginName: string;
|
|
47
|
+
watch?: boolean;
|
|
48
|
+
isMillennium?: boolean;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
enum BuildTarget {
|
|
@@ -129,6 +134,8 @@ function stripPluginPrefix(message: string): string {
|
|
|
129
134
|
return message;
|
|
130
135
|
}
|
|
131
136
|
|
|
137
|
+
class BuildFailedError extends Error {}
|
|
138
|
+
|
|
132
139
|
abstract class MillenniumBuild {
|
|
133
140
|
protected abstract readonly externals: ReadonlySet<string>;
|
|
134
141
|
protected abstract readonly forbidden: ReadonlyMap<string, string>;
|
|
@@ -144,6 +151,25 @@ abstract class MillenniumBuild {
|
|
|
144
151
|
return this.externals.has(id);
|
|
145
152
|
}
|
|
146
153
|
|
|
154
|
+
async watchConfig(input: string, sysfsPlugin: InputPluginOption, isMillennium: boolean): Promise<RollupOptions> {
|
|
155
|
+
return {
|
|
156
|
+
input,
|
|
157
|
+
plugins: await this.plugins(sysfsPlugin),
|
|
158
|
+
onwarn: (warning) => {
|
|
159
|
+
const msg = stripPluginPrefix(warning.message);
|
|
160
|
+
const loc = logLocation(warning);
|
|
161
|
+
if (warning.plugin === 'typescript') {
|
|
162
|
+
Logger.error(msg, loc);
|
|
163
|
+
} else {
|
|
164
|
+
Logger.warn(msg, loc);
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
context: 'window',
|
|
168
|
+
external: (id) => this.isExternal(id),
|
|
169
|
+
output: this.output(isMillennium),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
147
173
|
async build(input: string, sysfsPlugin: InputPluginOption, isMillennium: boolean): Promise<void> {
|
|
148
174
|
let hasErrors = false;
|
|
149
175
|
|
|
@@ -167,7 +193,7 @@ abstract class MillenniumBuild {
|
|
|
167
193
|
|
|
168
194
|
await (await rollup(config)).write(config.output as OutputOptions);
|
|
169
195
|
|
|
170
|
-
if (hasErrors)
|
|
196
|
+
if (hasErrors) throw new BuildFailedError();
|
|
171
197
|
}
|
|
172
198
|
}
|
|
173
199
|
|
|
@@ -273,10 +299,50 @@ class WebkitBuild extends MillenniumBuild {
|
|
|
273
299
|
}
|
|
274
300
|
}
|
|
275
301
|
|
|
276
|
-
|
|
302
|
+
function RunWatchMode(frontendConfig: RollupOptions, webkitConfig: RollupOptions | null): void {
|
|
303
|
+
const configs = webkitConfig ? [frontendConfig, webkitConfig] : [frontendConfig];
|
|
304
|
+
const watcher = rollupWatch(configs);
|
|
305
|
+
|
|
306
|
+
console.log(chalk.blueBright.bold('watch'), 'watching for file changes...');
|
|
307
|
+
|
|
308
|
+
watcher.on('event', async (event) => {
|
|
309
|
+
if (event.code === 'BUNDLE_START') {
|
|
310
|
+
const label = (event.output as readonly string[]).some((f) => f.includes('index.js')) ? 'frontend' : 'webkit';
|
|
311
|
+
console.log(chalk.yellowBright.bold('watch'), `rebuilding ${label}...`);
|
|
312
|
+
} else if (event.code === 'BUNDLE_END') {
|
|
313
|
+
const label = (event.output as readonly string[]).some((f) => f.includes('index.js')) ? 'frontend' : 'webkit';
|
|
314
|
+
console.log(chalk.greenBright.bold('watch'), `${label} built in ${chalk.green(`${event.duration}ms`)}`);
|
|
315
|
+
await event.result.close();
|
|
316
|
+
} else if (event.code === 'ERROR') {
|
|
317
|
+
const err = event.error;
|
|
318
|
+
const msg = stripPluginPrefix(err?.message ?? String(err));
|
|
319
|
+
Logger.error(msg, logLocation(err as any));
|
|
320
|
+
if (event.result) await event.result.close();
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
const shutdown = () => {
|
|
325
|
+
console.log(chalk.yellowBright.bold('watch'), 'stopping...');
|
|
326
|
+
watcher.close();
|
|
327
|
+
process.exit(0);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
process.on('SIGINT', shutdown);
|
|
331
|
+
process.on('SIGUSR2', shutdown);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export const TranspilerPluginComponent = async (pluginJson: PluginJson, props: TranspilerProps) => {
|
|
277
335
|
const webkitDir = './webkit/index.tsx';
|
|
278
336
|
const frontendDir = getFrontendDir(pluginJson);
|
|
279
337
|
const sysfs = constSysfsExpr();
|
|
338
|
+
const isMillennium = props.isMillennium ?? false;
|
|
339
|
+
|
|
340
|
+
if (props.watch) {
|
|
341
|
+
const frontendConfig = await new FrontendBuild(frontendDir, props).watchConfig(resolveEntryFile(frontendDir), sysfs.plugin, isMillennium);
|
|
342
|
+
const webkitConfig = fs.existsSync(webkitDir) ? await new WebkitBuild(props).watchConfig(webkitDir, sysfs.plugin, isMillennium) : null;
|
|
343
|
+
RunWatchMode(frontendConfig, webkitConfig);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
280
346
|
|
|
281
347
|
try {
|
|
282
348
|
await new FrontendBuild(frontendDir, props).build(resolveEntryFile(frontendDir), sysfs.plugin, isMillennium);
|
|
@@ -292,7 +358,10 @@ export const TranspilerPluginComponent = async (isMillennium: boolean, pluginJso
|
|
|
292
358
|
envCount: Object.keys(env).length || undefined,
|
|
293
359
|
});
|
|
294
360
|
} catch (exception: any) {
|
|
295
|
-
|
|
361
|
+
if (!(exception instanceof BuildFailedError)) {
|
|
362
|
+
Logger.error(stripPluginPrefix(exception?.message ?? String(exception)), logLocation(exception));
|
|
363
|
+
}
|
|
364
|
+
Logger.failed({ elapsedMs: performance.now() - global.PerfStartTime, buildType: props.minify ? 'prod' : 'dev' });
|
|
296
365
|
process.exit(1);
|
|
297
366
|
}
|
|
298
367
|
};
|