fix(config): update .smartconfig.json handling and harden bundler runtime compatibility

This commit is contained in:
2026-05-09 12:34:00 +00:00
parent f19c7c69af
commit e5b2f2ba30
18 changed files with 2712 additions and 3190 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"json.schemas": [
{
"fileMatch": ["/smartconfig.json"],
"fileMatch": ["/.smartconfig.json"],
"schema": {
"type": "object",
"properties": {
+1 -1
View File
@@ -3,7 +3,7 @@
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "node12",
"preserveValueImports": true,
"verbatimModuleSyntax": true,
"esModuleInterop": true
}
}
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## 2026-05-09 - 2.10.2 - fix(config)
update .smartconfig.json handling and harden bundler runtime compatibility
- switch init, CLI, docs, and custom config loading references from smartconfig.json to .smartconfig.json
- add guards for missing transportOptions and missing rspack stats in spawned bundler processes
- align TypeScript and test fixtures with newer decorator and module syntax requirements
- adjust rspack module output configuration and refactor asset/html option handling for safer processing
## 2026-04-30 - 2.10.1 - fix(mod_custom)
make base64ts bundle output deterministic and clean up generated temp sourcemaps
+17 -20
View File
@@ -6,7 +6,7 @@
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"type": "module",
"author": "Lossless GmbH",
"author": "Task Venture Capital GmbH",
"license": "MIT",
"scripts": {
"test": "pnpm run build && (tstest test/ --verbose)",
@@ -17,29 +17,29 @@
"tsbundle": "cli.js"
},
"devDependencies": {
"@git.zone/tsbuild": "^4.3.0",
"@git.zone/tsrun": "^2.0.1",
"@git.zone/tstest": "^3.5.1",
"@types/node": "^25.5.0"
"@git.zone/tsbuild": "^4.4.0",
"@git.zone/tsrun": "^2.0.3",
"@git.zone/tstest": "^3.6.5",
"@types/node": "^25.6.2"
},
"dependencies": {
"@push.rocks/early": "^4.0.4",
"@push.rocks/smartconfig": "^6.0.1",
"@push.rocks/smartcli": "^4.0.20",
"@push.rocks/smartdelay": "^3.0.5",
"@push.rocks/smartfs": "^1.5.0",
"@push.rocks/smartcli": "^4.0.21",
"@push.rocks/smartconfig": "^6.1.1",
"@push.rocks/smartdelay": "^3.1.0",
"@push.rocks/smartfs": "^1.5.1",
"@push.rocks/smartinteract": "^2.0.16",
"@push.rocks/smartlog": "^3.2.1",
"@push.rocks/smartlog": "^3.2.2",
"@push.rocks/smartlog-destination-local": "^9.0.2",
"@push.rocks/smartpath": "^6.0.0",
"@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smartspawn": "^3.0.3",
"@rspack/core": "^1.7.10",
"@push.rocks/smartpromise": "^4.2.4",
"@push.rocks/smartspawn": "^3.0.4",
"@rspack/core": "^2.0.2",
"@types/html-minifier": "^4.0.6",
"esbuild": "^0.27.4",
"esbuild": "^0.28.0",
"html-minifier": "^4.0.0",
"rolldown": "1.0.0-rc.11",
"typescript": "6.0.2"
"rolldown": "1.0.0",
"typescript": "6.0.3"
},
"files": [
"ts/**/*",
@@ -64,8 +64,5 @@
"bugs": {
"url": "https://gitlab.com/gitzone/tsbundle/issues"
},
"homepage": "https://gitlab.com/gitzone/tsbundle#readme",
"pnpm": {
"overrides": {}
}
"homepage": "https://gitlab.com/gitzone/tsbundle#readme"
}
+2613 -3101
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -41,19 +41,19 @@ Once configured, simply run:
tsbundle
```
Your bundles will be built according to your `smartconfig.json` configuration.
Your bundles will be built according to your `.smartconfig.json` configuration.
## CLI Commands
| Command | Description |
|---------|-------------|
| `tsbundle` | Build all bundles from `smartconfig.json` configuration |
| `tsbundle` | Build all bundles from `.smartconfig.json` configuration |
| `tsbundle custom` | Same as above (explicit) |
| `tsbundle init` | Interactive wizard to create/update bundle configuration |
## Configuration
tsbundle uses `smartconfig.json` for configuration. Here's an example:
tsbundle uses `.smartconfig.json` for configuration. Here's an example:
```json
{
@@ -188,7 +188,7 @@ await output.writeToFile('./ts/embedded-bundle.ts', 200); // optional maxLineLen
### CustomBundleHandler Class
Process multiple bundle configurations from `smartconfig.json`:
Process multiple bundle configurations from `.smartconfig.json`:
```typescript
import { CustomBundleHandler } from '@git.zone/tsbundle';
@@ -253,12 +253,12 @@ your-project/
├── assets/ # Static assets (images, fonts, etc.)
├── dist_bundle/ # Output for element/npm bundles
├── dist_serve/ # Output for website bundles
└── smartconfig.json # tsbundle configuration
└── .smartconfig.json # tsbundle configuration
```
## License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./license) file.
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
+4 -5
View File
@@ -1,16 +1,15 @@
// Test file to verify decorator functionality
const decoratedClasses: Function[] = [];
function trackClass(constructor: Function) {
decoratedClasses.push(constructor);
return constructor;
function trackClass(value: Function, _context: ClassDecoratorContext) {
decoratedClasses.push(value);
}
function logMethod(_target: any, context: ClassMethodDecoratorContext) {
function logMethod(method: Function, context: ClassMethodDecoratorContext) {
const methodName = String(context.name);
return function (this: any, ...args: any[]) {
console.log(`Calling method: ${methodName}`);
return (_target as Function).apply(this, args);
return method.apply(this, args);
};
}
+2 -2
View File
@@ -11,10 +11,10 @@ export class MyElement extends LitElement {
`;
@property({ type: String })
name = 'World';
accessor name = 'World';
@property({ type: Number })
count = 0;
accessor count = 0;
render() {
return html`
+3 -3
View File
@@ -4,9 +4,9 @@ const myConst: string = 'hello';
await smartdelay.delayFor(1000);
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
function sealed(value: Function, _context: ClassDecoratorContext) {
Object.seal(value);
Object.seal(value.prototype);
}
@sealed
+1 -1
View File
@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@git.zone/tsbundle',
version: '2.10.1',
version: '2.10.2',
description: 'a multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects'
}
+10 -12
View File
@@ -40,29 +40,27 @@ export class AssetsHandler {
// copies the html
public async processAssets(optionsArg?: { from?: string; to?: string }) {
// lets assemble the options
optionsArg = {
...{
from: this.defaultFromDirPath,
to: this.defaultToDirPath,
},
const options = {
from: this.defaultFromDirPath,
to: this.defaultToDirPath,
...(optionsArg || {}),
};
await this.ensureAssetsDir();
optionsArg.from = plugins.smartpath.transform.toAbsolute(
optionsArg.from,
options.from = plugins.smartpath.transform.toAbsolute(
options.from,
paths.cwd,
) as string;
optionsArg.to = plugins.smartpath.transform.toAbsolute(
optionsArg.to,
options.to = plugins.smartpath.transform.toAbsolute(
options.to,
paths.cwd,
) as string;
// lets clean the target directory
const toExists = await plugins.fs.directory(optionsArg.to).exists();
const toExists = await plugins.fs.directory(options.to).exists();
if (toExists) {
await plugins.fs.directory(optionsArg.to).delete();
await plugins.fs.directory(options.to).delete();
}
await this.copyDirectoryRecursive(optionsArg.from, optionsArg.to);
await this.copyDirectoryRecursive(options.from, options.to);
}
}
+1 -1
View File
@@ -16,7 +16,7 @@ export class CustomBundleHandler {
}
/**
* Load configuration from smartconfig.json
* Load configuration from .smartconfig.json
*/
public async loadConfig(): Promise<boolean> {
const smartconfigInstance = new plugins.smartconfig.Smartconfig(this.cwd);
+5 -3
View File
@@ -83,9 +83,11 @@ export class TsBundleProcess {
const run = async () => {
try {
console.log('running spawned compilation process');
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
process.env.transportOptions,
);
const transportOptionsJson = process.env.transportOptions;
if (!transportOptionsJson) {
throw new Error('Missing transportOptions environment variable');
}
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(transportOptionsJson);
console.log('=======> ESBUILD');
console.log(transportOptions);
process.chdir(transportOptions.cwd);
+13 -15
View File
@@ -21,30 +21,28 @@ export class HtmlHandler {
to?: string;
minify?: boolean;
}) {
optionsArg = {
...{
from: this.defaultFromPath,
to: this.defaultToPath,
minify: false,
},
const options = {
from: this.defaultFromPath,
to: this.defaultToPath,
minify: false,
...optionsArg,
};
if (await this.checkIfExists()) {
console.log(`${optionsArg.from} replaces file at ${optionsArg.to}`);
console.log(`${options.from} replaces file at ${options.to}`);
}
optionsArg.from = plugins.smartpath.transform.toAbsolute(
optionsArg.from,
options.from = plugins.smartpath.transform.toAbsolute(
options.from,
paths.cwd,
) as string;
optionsArg.to = plugins.smartpath.transform.toAbsolute(
optionsArg.to,
options.to = plugins.smartpath.transform.toAbsolute(
options.to,
paths.cwd,
) as string;
let fileString = (await plugins.fs
.file(optionsArg.from)
.file(options.from)
.encoding('utf8')
.read()) as string;
if (optionsArg.minify) {
if (options.minify) {
fileString = plugins.htmlMinifier.minify(fileString, {
minifyCSS: true,
minifyJS: true,
@@ -56,9 +54,9 @@ export class HtmlHandler {
removeComments: true,
});
}
const toDir = plugins.path.dirname(optionsArg.to);
const toDir = plugins.path.dirname(options.to);
await plugins.fs.directory(toDir).create();
await plugins.fs.file(optionsArg.to).encoding('utf8').write(fileString);
await plugins.fs.file(options.to).encoding('utf8').write(fileString);
console.log(`html processing succeeded!`);
}
}
+5 -5
View File
@@ -40,11 +40,11 @@ export class InitHandler {
constructor(cwd: string = paths.cwd) {
this.cwd = cwd;
this.smartconfigPath = plugins.path.join(this.cwd, 'smartconfig.json');
this.smartconfigPath = plugins.path.join(this.cwd, '.smartconfig.json');
}
/**
* Load existing smartconfig.json or create empty config
* Load existing .smartconfig.json or create empty config
*/
private async loadExistingConfig(): Promise<any> {
const fileExists = await plugins.fs.file(this.smartconfigPath).exists();
@@ -60,12 +60,12 @@ export class InitHandler {
}
/**
* Save config to smartconfig.json
* Save config to .smartconfig.json
*/
private async saveConfig(config: any): Promise<void> {
const content = JSON.stringify(config, null, 2);
await plugins.fs.file(this.smartconfigPath).encoding('utf8').write(content);
console.log(`\n✅ Configuration saved to smartconfig.json`);
console.log(`\n✅ Configuration saved to .smartconfig.json`);
}
/**
@@ -73,7 +73,7 @@ export class InitHandler {
*/
public async runWizard(): Promise<void> {
console.log('\n🚀 tsbundle configuration wizard\n');
console.log('This wizard will help you configure bundle settings in smartconfig.json.\n');
console.log('This wizard will help you configure bundle settings in .smartconfig.json.\n');
const smartconfigJson = await this.loadExistingConfig();
+5 -3
View File
@@ -90,9 +90,11 @@ export class TsBundleProcess {
const run = async () => {
console.log('running spawned compilation process');
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
process.env.transportOptions,
);
const transportOptionsJson = process.env.transportOptions;
if (!transportOptionsJson) {
throw new Error('Missing transportOptions environment variable');
}
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(transportOptionsJson);
console.log('=======> ROLLDOWN');
console.log(transportOptions);
process.chdir(transportOptions.cwd);
+15 -9
View File
@@ -52,6 +52,7 @@ export class TsBundleProcess {
output: {
path: outputDir,
filename: outputFilename,
module: true,
library: {
type: 'module' as const,
},
@@ -86,9 +87,6 @@ export class TsBundleProcess {
},
],
},
experiments: {
outputModule: true,
},
};
return new Promise((resolve, reject) => {
@@ -98,6 +96,10 @@ export class TsBundleProcess {
reject(err);
return;
}
if (!stats) {
reject(new Error('Rspack did not return stats'));
return;
}
if (stats.hasErrors()) {
console.error(stats.toString());
@@ -140,6 +142,7 @@ export class TsBundleProcess {
output: {
path: outputDir,
filename: outputFilename,
module: true,
library: {
type: 'module' as const,
},
@@ -184,9 +187,6 @@ export class TsBundleProcess {
usedExports: true,
sideEffects: true,
},
experiments: {
outputModule: true,
},
};
return new Promise((resolve, reject) => {
@@ -196,6 +196,10 @@ export class TsBundleProcess {
reject(err);
return;
}
if (!stats) {
reject(new Error('Rspack did not return stats'));
return;
}
if (stats.hasErrors()) {
console.error(stats.toString());
@@ -221,9 +225,11 @@ export class TsBundleProcess {
const run = async () => {
console.log('running spawned compilation process');
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
process.env.transportOptions,
);
const transportOptionsJson = process.env.transportOptions;
if (!transportOptionsJson) {
throw new Error('Missing transportOptions environment variable');
}
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(transportOptionsJson);
console.log('=======> RSPACK');
console.log(transportOptions);
process.chdir(transportOptions.cwd);
+1 -1
View File
@@ -5,7 +5,7 @@ import { runInit } from './mod_init/index.js';
export const runCli = async () => {
const tsBundleCli = new plugins.smartcli.Smartcli();
// Default command: run custom bundles from smartconfig.json
// Default command: run custom bundles from .smartconfig.json
tsBundleCli.standardCommand().subscribe(async (argvArg) => {
await runCustomBundles();
});