Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e98ba083e | |||
| e5b2f2ba30 | |||
| f19c7c69af | |||
| 3b2e0bebcd | |||
| 7f5de8797c | |||
| aea86bd8f5 | |||
| ad5e0c1afc | |||
| cb5d827420 | |||
| 5a5f6c6944 | |||
| 54ac7e7188 | |||
| 5f0507b2c7 | |||
| ecfd7600e2 | |||
| 9cf173293d | |||
| 3a53fffe3d | |||
| 8f129527d9 | |||
| 5d9052018e | |||
| 12c5655251 | |||
| 801cab9001 | |||
| 971cb685a7 | |||
| 0900d1a605 | |||
| f0fb99c8ae | |||
| 6d88adcd1e | |||
| 4349571112 | |||
| b3080023ab | |||
| 8b6ae043a2 |
@@ -5,7 +5,7 @@
|
|||||||
"githost": "gitlab.com",
|
"githost": "gitlab.com",
|
||||||
"gitscope": "gitzone",
|
"gitscope": "gitzone",
|
||||||
"gitrepo": "tsbundle",
|
"gitrepo": "tsbundle",
|
||||||
"description": "a bundler using rollup for painless bundling of web projects",
|
"description": "a multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects",
|
||||||
"npmPackagename": "@git.zone/tsbundle",
|
"npmPackagename": "@git.zone/tsbundle",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"projectDomain": "git.zone"
|
"projectDomain": "git.zone"
|
||||||
Vendored
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"json.schemas": [
|
"json.schemas": [
|
||||||
{
|
{
|
||||||
"fileMatch": ["/npmextra.json"],
|
"fileMatch": ["/.smartconfig.json"],
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "ES2022",
|
"module": "ES2022",
|
||||||
"moduleResolution": "node12",
|
"moduleResolution": "node12",
|
||||||
"preserveValueImports": true,
|
"verbatimModuleSyntax": true,
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,91 @@
|
|||||||
# Changelog
|
# 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
|
||||||
|
|
||||||
|
- Use a stable temporary bundle filename instead of a timestamp-based name so repeated base64ts builds produce identical output.
|
||||||
|
- Delete the generated temporary sourcemap alongside the temp bundle to avoid leftover build artifacts.
|
||||||
|
- Add a test covering deterministic base64ts output generation.
|
||||||
|
- Update package scripts to use pnpm for tests and remove the allowimplicitany build flag.
|
||||||
|
|
||||||
|
## 2026-03-24 - 2.10.0 - feat(config)
|
||||||
|
migrate project configuration to smartconfig.json and update bundler dependencies
|
||||||
|
|
||||||
|
- replace npmextra.json with .smartconfig.json and update CLI, init, and custom bundle loading references
|
||||||
|
- rename the smartconfig plugin export and load tsbundle configuration through the new config file
|
||||||
|
- update rolldown output settings to use codeSplitting: false instead of the deprecated inlineDynamicImports option
|
||||||
|
- refresh core build and bundler dependencies including rolldown, rspack, esbuild, TypeScript, and smartfs
|
||||||
|
- revise README documentation to reflect smartconfig.json usage and current bundler capabilities
|
||||||
|
|
||||||
|
## 2026-03-24 - 2.9.3 - fix(config)
|
||||||
|
migrate configuration loading and init output from npmextra.json to smartconfig.json
|
||||||
|
|
||||||
|
- replace @push.rocks/npmextra with @push.rocks/smartconfig
|
||||||
|
- load project configuration via Smartconfig in the custom module
|
||||||
|
- update init wizard to read from and write to smartconfig.json and adjust user-facing messages accordingly
|
||||||
|
|
||||||
|
## 2026-03-11 - 2.9.2 - fix(mod_esbuild)
|
||||||
|
preserve function and class names in esbuild output by enabling keepNames in both dev and prod configs
|
||||||
|
|
||||||
|
- Added keepNames: true to esbuild options in ts/mod_esbuild/index.child.ts for the non-minified/dev build
|
||||||
|
- Added keepNames: true to esbuild options in ts/mod_esbuild/index.child.ts for the minified/production build to improve stack traces, debugging, and runtime reflection
|
||||||
|
|
||||||
|
## 2026-03-05 - 2.9.1 - fix(mod_custom)
|
||||||
|
use absolute smartfs entry.path instead of joining with dirPath when building fullPath
|
||||||
|
|
||||||
|
- entry.path is already absolute (from smartfs); avoid joining it with dirPath which produced incorrect paths
|
||||||
|
- Fixes file copy path construction so plugins.fs.file(fullPath).copy(destPath) uses the correct source path
|
||||||
|
|
||||||
|
## 2026-02-24 - 2.9.0 - feat(exports)
|
||||||
|
expose mod_custom, mod_output and interfaces from entry; make processSingleBundle public
|
||||||
|
|
||||||
|
- Exported ./mod_custom, ./mod_output and ./interfaces from ts/index.ts to expose these modules in the public API.
|
||||||
|
- Changed processSingleBundle in ts/mod_custom/index.ts from private to public to allow programmatic invocation.
|
||||||
|
- Non-breaking API expansion; recommend a minor version bump.
|
||||||
|
|
||||||
|
## 2026-02-24 - 2.8.4 - fix()
|
||||||
|
no changes — empty diff, nothing to commit
|
||||||
|
|
||||||
|
- Diff contained no modifications; no release required
|
||||||
|
|
||||||
|
## 2026-01-23 - 2.8.3 - fix(mod_output)
|
||||||
|
use pattern base dir when computing relative paths for files to serve
|
||||||
|
|
||||||
|
- Compute relativePath using the pattern base directory (dirPath) instead of this.cwd to ensure correct web-serving paths for absolute or relative entry.path values.
|
||||||
|
- File changed: ts/mod_output/index.ts — replaces plugins.path.relative(this.cwd, fullPath) with plugins.path.relative(dirPath, fullPath) and adds clarifying comment.
|
||||||
|
|
||||||
|
## 2026-01-23 - 2.8.2 - fix(mod_output)
|
||||||
|
resolve absolute and relative entry.path correctly when adding files
|
||||||
|
|
||||||
|
- Add check for plugins.path.isAbsolute(entry.path) to avoid incorrectly joining absolute paths with dirPath
|
||||||
|
- Use entry.path directly when it's absolute, otherwise join with dirPath
|
||||||
|
- Ensures correct relativePath calculation and prevents invalid file reads
|
||||||
|
|
||||||
|
## 2026-01-12 - 2.8.1 - fix(readme)
|
||||||
|
document maxLineLength option for base64ts output and add example and tip
|
||||||
|
|
||||||
|
- Add documented `maxLineLength` configuration option (number, default 0 = unlimited) for `base64ts` output.
|
||||||
|
- Include example config showing `maxLineLength: 200`.
|
||||||
|
- Add a tip recommending setting `maxLineLength` to split long base64 strings when using AI tools with line-length limits.
|
||||||
|
|
||||||
|
## 2026-01-12 - 2.8.0 - feat(tsbundle)
|
||||||
|
add configurable maxLineLength for base64ts output and improve build/error handling in child builds
|
||||||
|
|
||||||
|
- Add optional maxLineLength?: number to IBundleConfig to control max characters per line for base64ts output (0 or undefined = unlimited).
|
||||||
|
- Support splitting base64 strings when maxLineLength is specified; generateTypeScript(maxLineLength?) and writeToFile(outputPath, maxLineLength?) updated to accept and apply this setting.
|
||||||
|
- Pass bundleConfig.maxLineLength through in mod_custom so base64ts output respects bundle configuration.
|
||||||
|
- Wrap TsBundle.build in mod_custom with try/catch to log failures and skip output handling when build fails.
|
||||||
|
- tsbundle.class now rejects the bundle promise when the child process exits with a non-zero status.
|
||||||
|
- mod_esbuild child process now awaits builds, exits with appropriate success/failure codes, and formats esbuild errors for clearer console output.
|
||||||
|
|
||||||
## 2026-01-12 - 2.7.4 - fix(deps)
|
## 2026-01-12 - 2.7.4 - fix(deps)
|
||||||
bump @push.rocks/smartcli dependency to ^4.0.20
|
bump @push.rocks/smartcli dependency to ^4.0.20
|
||||||
|
|
||||||
|
|||||||
+21
-24
@@ -1,45 +1,45 @@
|
|||||||
{
|
{
|
||||||
"name": "@git.zone/tsbundle",
|
"name": "@git.zone/tsbundle",
|
||||||
"version": "2.7.4",
|
"version": "2.10.2",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "a multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects",
|
"description": "a multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist_ts/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"author": "Lossless GmbH",
|
"author": "Task Venture Capital GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run build && (tstest test/ --verbose)",
|
"test": "pnpm run build && (tstest test/ --verbose)",
|
||||||
"build": "(tsbuild --web --allowimplicitany)",
|
"build": "(tsbuild --web)",
|
||||||
"buildDocs": "tsdoc"
|
"buildDocs": "tsdoc"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsbundle": "cli.js"
|
"tsbundle": "cli.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsbuild": "^3.1.2",
|
"@git.zone/tsbuild": "^4.4.0",
|
||||||
"@git.zone/tsrun": "^2.0.0",
|
"@git.zone/tsrun": "^2.0.3",
|
||||||
"@git.zone/tstest": "^3.1.3",
|
"@git.zone/tstest": "^3.6.5",
|
||||||
"@types/node": "^24.10.1"
|
"@types/node": "^25.6.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@push.rocks/early": "^4.0.4",
|
"@push.rocks/early": "^4.0.4",
|
||||||
"@push.rocks/npmextra": "^5.1.3",
|
"@push.rocks/smartcli": "^4.0.21",
|
||||||
"@push.rocks/smartcli": "^4.0.20",
|
"@push.rocks/smartconfig": "^6.1.1",
|
||||||
"@push.rocks/smartdelay": "^3.0.5",
|
"@push.rocks/smartdelay": "^3.1.0",
|
||||||
"@push.rocks/smartfs": "^1.1.3",
|
"@push.rocks/smartfs": "^1.5.1",
|
||||||
"@push.rocks/smartinteract": "^2.0.16",
|
"@push.rocks/smartinteract": "^2.0.16",
|
||||||
"@push.rocks/smartlog": "^3.1.8",
|
"@push.rocks/smartlog": "^3.2.2",
|
||||||
"@push.rocks/smartlog-destination-local": "^9.0.2",
|
"@push.rocks/smartlog-destination-local": "^9.0.2",
|
||||||
"@push.rocks/smartpath": "^6.0.0",
|
"@push.rocks/smartpath": "^6.0.0",
|
||||||
"@push.rocks/smartpromise": "^4.2.3",
|
"@push.rocks/smartpromise": "^4.2.4",
|
||||||
"@push.rocks/smartspawn": "^3.0.3",
|
"@push.rocks/smartspawn": "^3.0.4",
|
||||||
"@rspack/core": "^1.6.5",
|
"@rspack/core": "^2.0.2",
|
||||||
"@types/html-minifier": "^4.0.6",
|
"@types/html-minifier": "^4.0.6",
|
||||||
"esbuild": "^0.27.0",
|
"esbuild": "^0.28.0",
|
||||||
"html-minifier": "^4.0.0",
|
"html-minifier": "^4.0.0",
|
||||||
"rolldown": "1.0.0-beta.52",
|
"rolldown": "1.0.0",
|
||||||
"typescript": "5.9.3"
|
"typescript": "6.0.3"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
"dist_ts_web/**/*",
|
"dist_ts_web/**/*",
|
||||||
"assets/**/*",
|
"assets/**/*",
|
||||||
"cli.js",
|
"cli.js",
|
||||||
"npmextra.json",
|
".smartconfig.json",
|
||||||
"readme.md"
|
"readme.md"
|
||||||
],
|
],
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
@@ -64,8 +64,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://gitlab.com/gitzone/tsbundle/issues"
|
"url": "https://gitlab.com/gitzone/tsbundle/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://gitlab.com/gitzone/tsbundle#readme",
|
"homepage": "https://gitlab.com/gitzone/tsbundle#readme"
|
||||||
"pnpm": {
|
|
||||||
"overrides": {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+3238
-4351
File diff suppressed because it is too large
Load Diff
+18
-41
@@ -1,12 +1,15 @@
|
|||||||
# tsbundle Hints and Findings
|
# tsbundle Hints and Findings
|
||||||
|
|
||||||
## Recent Updates (2025-11-23)
|
## Recent Updates (2026-03-24)
|
||||||
|
|
||||||
- Migrated from @push.rocks/smartfile v11 to @push.rocks/smartfs v1.1.0
|
- Upgraded all dependencies to latest versions
|
||||||
- All filesystem operations now use async smartfs API
|
- Migrated from npmextra.json to smartconfig.json (renamed file, updated all references)
|
||||||
- Removed @push.rocks/tapbundle (now imported from @git.zone/tstest/tapbundle)
|
- Renamed `npmextra` import to `smartconfig` in plugins.ts
|
||||||
- All bundlers (esbuild, rolldown, rspack) updated to latest versions
|
- Fixed rolldown deprecation: `inlineDynamicImports` replaced with `codeSplitting: false`
|
||||||
- Removed deprecated rolldown experimental.enableComposingJsPlugins option
|
- Major version bumps: tsbuild ^3.1.2 -> ^4.3.0, TypeScript 5.9.3 -> 6.0.2
|
||||||
|
- Rolldown upgraded from 1.0.0-beta.52 to 1.0.0-rc.11
|
||||||
|
- @rspack/core upgraded from ^1.6.5 to ^1.7.10
|
||||||
|
- @types/node upgraded from ^24.10.1 to ^25.5.0
|
||||||
|
|
||||||
## Bundler Architecture
|
## Bundler Architecture
|
||||||
|
|
||||||
@@ -16,41 +19,16 @@
|
|||||||
|
|
||||||
## Bundler Implementations
|
## Bundler Implementations
|
||||||
|
|
||||||
- **esbuild** (default): Fully implemented, production ready, 3.9K minified
|
- **esbuild** (default): Fully implemented, production ready
|
||||||
- **rolldown**: Implemented and working (beta v1.0.0-beta.51), produces smallest bundles (1.0K minified)
|
- **rolldown**: Implemented and working (1.0.0-rc.11), produces smallest bundles
|
||||||
- **rspack**: Implemented and working (v1.6.4), webpack-compatible API, 6.3K minified
|
- **rspack**: Implemented and working (v1.7.10), webpack-compatible API
|
||||||
- **rollup**: Removed (was never implemented)
|
|
||||||
- **parcel**: Removed (was never implemented)
|
|
||||||
|
|
||||||
## Adding New Bundlers
|
## Configuration
|
||||||
|
|
||||||
To add a new bundler, you need:
|
- Config file: `smartconfig.json` (previously `npmextra.json`)
|
||||||
|
- Config key: `@git.zone/tsbundle` with `bundles` array
|
||||||
1. Update `ICliOptions` interface to include the bundler name
|
- Supports `bundle` and `base64ts` output modes
|
||||||
2. Add case in `getBundlerPath()` switch statement
|
- Interactive init wizard via `tsbundle init`
|
||||||
3. Create `mod_<bundler>/` directory with:
|
|
||||||
- `plugins.ts`: Import and re-export the bundler
|
|
||||||
- `index.child.ts`: Implement TsBundleProcess class with buildTest() and buildProduction()
|
|
||||||
4. Add bundler to package.json dependencies
|
|
||||||
|
|
||||||
## Rolldown Specific Notes
|
|
||||||
|
|
||||||
- Rolldown is in beta (v1.0.0-beta.18) but working well
|
|
||||||
- API: Use `rolldown()` function directly, not `rolldown.rolldown()`
|
|
||||||
- Output options go in the `write()` method, not the initial config
|
|
||||||
- Uses `dir` and `entryFileNames` instead of `file` for output (handles dynamic imports)
|
|
||||||
- Includes `inlineDynamicImports: true` to avoid chunk splitting issues
|
|
||||||
- Produces smaller minified bundles than esbuild (1.5K vs 2.2K in tests)
|
|
||||||
- Supports TypeScript via `resolve.tsconfigFilename`
|
|
||||||
|
|
||||||
## Rspack Specific Notes
|
|
||||||
|
|
||||||
- Rspack v1.3.15 - stable and production ready
|
|
||||||
- Uses webpack-compatible API (callback-based)
|
|
||||||
- Built-in SWC loader for TypeScript transpilation
|
|
||||||
- Produces larger bundles than esbuild/rolldown due to webpack runtime overhead
|
|
||||||
- Best choice if you need webpack compatibility or advanced features
|
|
||||||
- Supports ES modules output via `experiments.outputModule: true`
|
|
||||||
|
|
||||||
## CLI Usage
|
## CLI Usage
|
||||||
|
|
||||||
@@ -61,5 +39,4 @@ To add a new bundler, you need:
|
|||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
||||||
- esbuild recently had splitting and tree-shaking disabled due to issues
|
- Rolldown emits a warning about `preserveValueImports` in tsconfig - this is informational only
|
||||||
- The README still mentions "a bundler using rollup" but uses esbuild by default
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# @git.zone/tsbundle
|
# @git.zone/tsbundle
|
||||||
|
|
||||||
A powerful multi-bundler tool supporting **esbuild**, **rolldown**, and **rspack** for painless bundling of web projects. 🚀
|
A powerful multi-bundler tool supporting **esbuild**, **rolldown**, and **rspack** for painless bundling of web projects.
|
||||||
|
|
||||||
## Issue Reporting and Security
|
## Issue Reporting and Security
|
||||||
|
|
||||||
@@ -10,16 +10,13 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Global installation for CLI usage
|
# Global installation for CLI usage
|
||||||
npm install -g @git.zone/tsbundle
|
pnpm add -g @git.zone/tsbundle
|
||||||
|
|
||||||
# Local installation for project usage
|
# Local installation for project usage
|
||||||
npm install --save-dev @git.zone/tsbundle
|
pnpm add --save-dev @git.zone/tsbundle
|
||||||
|
|
||||||
# Or with pnpm
|
|
||||||
pnpm add -g @git.zone/tsbundle
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Quick Start ⚡
|
## Quick Start
|
||||||
|
|
||||||
### Interactive Setup
|
### Interactive Setup
|
||||||
|
|
||||||
@@ -29,11 +26,11 @@ The easiest way to get started is with the interactive wizard:
|
|||||||
tsbundle init
|
tsbundle init
|
||||||
```
|
```
|
||||||
|
|
||||||
This will guide you through setting up your bundle configuration with preset options:
|
This guides you through setting up your bundle configuration with preset options:
|
||||||
|
|
||||||
- **element** - Web component / element bundle (`./ts_web/index.ts` → `./dist_bundle/bundle.js`)
|
- **element** - Web component / element bundle (`./ts_web/index.ts` -> `./dist_bundle/bundle.js`)
|
||||||
- **website** - Full website with HTML and assets (`./ts_web/index.ts` → `./dist_serve/bundle.js`)
|
- **website** - Full website with HTML and assets (`./ts_web/index.ts` -> `./dist_serve/bundle.js`)
|
||||||
- **npm** - NPM package bundle (`./ts/index.ts` → `./dist_bundle/bundle.js`)
|
- **npm** - NPM package bundle (`./ts/index.ts` -> `./dist_bundle/bundle.js`)
|
||||||
- **custom** - Configure everything manually
|
- **custom** - Configure everything manually
|
||||||
|
|
||||||
### Build Your Bundles
|
### Build Your Bundles
|
||||||
@@ -44,19 +41,19 @@ Once configured, simply run:
|
|||||||
tsbundle
|
tsbundle
|
||||||
```
|
```
|
||||||
|
|
||||||
That's it! Your bundles will be built according to your `npmextra.json` configuration.
|
Your bundles will be built according to your `.smartconfig.json` configuration.
|
||||||
|
|
||||||
## CLI Commands
|
## CLI Commands
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
| `tsbundle` | Build all bundles from `npmextra.json` configuration |
|
| `tsbundle` | Build all bundles from `.smartconfig.json` configuration |
|
||||||
| `tsbundle custom` | Same as above (explicit) |
|
| `tsbundle custom` | Same as above (explicit) |
|
||||||
| `tsbundle init` | Interactive wizard to create/update bundle configuration |
|
| `tsbundle init` | Interactive wizard to create/update bundle configuration |
|
||||||
|
|
||||||
## Configuration 📝
|
## Configuration
|
||||||
|
|
||||||
tsbundle uses `npmextra.json` for configuration. Here's an example:
|
tsbundle uses `.smartconfig.json` for configuration. Here's an example:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -91,6 +88,7 @@ tsbundle uses `npmextra.json` for configuration. Here's an example:
|
|||||||
| `bundler` | `"esbuild"` \| `"rolldown"` \| `"rspack"` | `"esbuild"` | Which bundler to use |
|
| `bundler` | `"esbuild"` \| `"rolldown"` \| `"rspack"` | `"esbuild"` | Which bundler to use |
|
||||||
| `production` | `boolean` | `false` | Enable minification |
|
| `production` | `boolean` | `false` | Enable minification |
|
||||||
| `includeFiles` | `string[]` | `[]` | Glob patterns for additional files (HTML, assets) |
|
| `includeFiles` | `string[]` | `[]` | Glob patterns for additional files (HTML, assets) |
|
||||||
|
| `maxLineLength` | `number` | `0` (unlimited) | For `base64ts` mode: max chars per line in output |
|
||||||
|
|
||||||
### Output Modes
|
### Output Modes
|
||||||
|
|
||||||
@@ -108,20 +106,24 @@ export const files: { path: string; contentBase64: string }[] = [
|
|||||||
];
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
## Available Bundlers 🔧
|
If you're working with AI tools that have line length limitations, set `maxLineLength` (e.g., `200`) to split long base64 strings across multiple lines.
|
||||||
|
|
||||||
tsbundle supports three modern bundlers:
|
## Available Bundlers
|
||||||
|
|
||||||
| Bundler | Speed | Best For |
|
tsbundle supports three modern bundlers, each with different strengths:
|
||||||
|---------|-------|----------|
|
|
||||||
| **esbuild** | ⚡⚡⚡ Blazing fast | Development, quick iterations |
|
| Bundler | Speed | Bundle Size | Best For |
|
||||||
| **rolldown** | ⚡⚡ Fast | Production builds, tree-shaking |
|
|---------|-------|-------------|----------|
|
||||||
| **rspack** | ⚡⚡ Fast | Webpack compatibility |
|
| **esbuild** | Fastest | Medium | Development, quick iterations |
|
||||||
|
| **rolldown** | Fast | Smallest | Production builds, tree-shaking |
|
||||||
|
| **rspack** | Fast | Largest (webpack runtime) | Webpack compatibility |
|
||||||
|
|
||||||
## API Usage
|
## API Usage
|
||||||
|
|
||||||
### TsBundle Class
|
### TsBundle Class
|
||||||
|
|
||||||
|
The core bundling class, usable programmatically:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { TsBundle } from '@git.zone/tsbundle';
|
import { TsBundle } from '@git.zone/tsbundle';
|
||||||
|
|
||||||
@@ -132,15 +134,17 @@ await bundler.build(
|
|||||||
'./src/index.ts', // Entry point
|
'./src/index.ts', // Entry point
|
||||||
'./dist/bundle.js', // Output path
|
'./dist/bundle.js', // Output path
|
||||||
{
|
{
|
||||||
bundler: 'esbuild',
|
bundler: 'esbuild', // 'esbuild' | 'rolldown' | 'rspack'
|
||||||
production: true
|
production: true
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Each bundler runs in a separate child process via `smartspawn.ThreadSimple`, keeping the main process clean and isolated from bundler-specific dependencies.
|
||||||
|
|
||||||
### HtmlHandler Class
|
### HtmlHandler Class
|
||||||
|
|
||||||
Process and minify HTML files:
|
Process and optionally minify HTML files:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { HtmlHandler } from '@git.zone/tsbundle';
|
import { HtmlHandler } from '@git.zone/tsbundle';
|
||||||
@@ -156,7 +160,7 @@ await htmlHandler.processHtml({
|
|||||||
|
|
||||||
### AssetsHandler Class
|
### AssetsHandler Class
|
||||||
|
|
||||||
Handle static assets:
|
Copy static assets between directories:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { AssetsHandler } from '@git.zone/tsbundle';
|
import { AssetsHandler } from '@git.zone/tsbundle';
|
||||||
@@ -169,59 +173,34 @@ await assetsHandler.processAssets({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## Complete Example 🎯
|
### Base64TsOutput Class
|
||||||
|
|
||||||
### 1. Initialize your project
|
Generate TypeScript files with base64-encoded content for embedding:
|
||||||
|
|
||||||
```bash
|
```typescript
|
||||||
tsbundle init
|
import { Base64TsOutput } from '@git.zone/tsbundle';
|
||||||
|
|
||||||
|
const output = new Base64TsOutput(process.cwd());
|
||||||
|
output.addFile('bundle.js', bundleBuffer);
|
||||||
|
await output.addFilesFromGlob('./html/**/*.html');
|
||||||
|
await output.writeToFile('./ts/embedded-bundle.ts', 200); // optional maxLineLength
|
||||||
```
|
```
|
||||||
|
|
||||||
Select "website" preset for a full web application setup.
|
### CustomBundleHandler Class
|
||||||
|
|
||||||
### 2. Your generated config
|
Process multiple bundle configurations from `.smartconfig.json`:
|
||||||
|
|
||||||
```json
|
```typescript
|
||||||
{
|
import { CustomBundleHandler } from '@git.zone/tsbundle';
|
||||||
"@git.zone/tsbundle": {
|
|
||||||
"bundles": [
|
const handler = new CustomBundleHandler(process.cwd());
|
||||||
{
|
const hasConfig = await handler.loadConfig();
|
||||||
"from": "./ts_web/index.ts",
|
if (hasConfig) {
|
||||||
"to": "./dist_serve/bundle.js",
|
await handler.processAllBundles();
|
||||||
"outputMode": "bundle",
|
|
||||||
"bundler": "esbuild",
|
|
||||||
"includeFiles": ["./html/**/*.html", "./assets/**/*"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Create your entry point
|
## Embedding for Deno Compile
|
||||||
|
|
||||||
```typescript
|
|
||||||
// ts_web/index.ts
|
|
||||||
console.log('Hello from tsbundle! 🚀');
|
|
||||||
|
|
||||||
export const app = {
|
|
||||||
version: '1.0.0',
|
|
||||||
init() {
|
|
||||||
console.log('App initialized');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
app.init();
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Build
|
|
||||||
|
|
||||||
```bash
|
|
||||||
tsbundle
|
|
||||||
```
|
|
||||||
|
|
||||||
Your bundle is ready in `./dist_serve/bundle.js` along with any HTML and assets!
|
|
||||||
|
|
||||||
## Embedding for Deno Compile 🦕
|
|
||||||
|
|
||||||
For single-executable scenarios with Deno:
|
For single-executable scenarios with Deno:
|
||||||
|
|
||||||
@@ -241,7 +220,8 @@ Config:
|
|||||||
"outputMode": "base64ts",
|
"outputMode": "base64ts",
|
||||||
"bundler": "esbuild",
|
"bundler": "esbuild",
|
||||||
"production": true,
|
"production": true,
|
||||||
"includeFiles": ["./html/index.html"]
|
"includeFiles": ["./html/index.html"],
|
||||||
|
"maxLineLength": 200
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -260,7 +240,7 @@ const bundleContent = atob(bundle.contentBase64);
|
|||||||
const htmlContent = atob(html.contentBase64);
|
const htmlContent = atob(html.contentBase64);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project Structure Recommendations 📁
|
## Project Structure Recommendations
|
||||||
|
|
||||||
```
|
```
|
||||||
your-project/
|
your-project/
|
||||||
@@ -273,12 +253,12 @@ your-project/
|
|||||||
├── assets/ # Static assets (images, fonts, etc.)
|
├── assets/ # Static assets (images, fonts, etc.)
|
||||||
├── dist_bundle/ # Output for element/npm bundles
|
├── dist_bundle/ # Output for element/npm bundles
|
||||||
├── dist_serve/ # Output for website bundles
|
├── dist_serve/ # Output for website bundles
|
||||||
└── npmextra.json # tsbundle configuration
|
└── .smartconfig.json # tsbundle configuration
|
||||||
```
|
```
|
||||||
|
|
||||||
## License and Legal Information
|
## 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.
|
**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.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||||
import * as tsbundle from '../dist_ts/index.js';
|
import * as tsbundle from '../dist_ts/index.js';
|
||||||
|
import { CustomBundleHandler } from '../dist_ts/mod_custom/index.js';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
@@ -61,6 +62,30 @@ tap.test('should bundle with rspack in production mode', async () => {
|
|||||||
await testBundler('rspack', 'production');
|
await testBundler('rspack', 'production');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('should generate deterministic base64ts output', async () => {
|
||||||
|
const testDir = path.join(process.cwd(), 'test');
|
||||||
|
const outputPath = path.join(testDir, 'dist_manual/base64-output.ts');
|
||||||
|
const bundleConfig = {
|
||||||
|
from: './ts_web/index.ts',
|
||||||
|
to: './dist_manual/base64-output.ts',
|
||||||
|
outputMode: 'base64ts' as const,
|
||||||
|
bundler: 'esbuild' as const,
|
||||||
|
};
|
||||||
|
|
||||||
|
const handler = new CustomBundleHandler(testDir);
|
||||||
|
if (fs.existsSync(outputPath)) {
|
||||||
|
fs.rmSync(outputPath, { force: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
await handler.processSingleBundle(bundleConfig);
|
||||||
|
const firstOutput = fs.readFileSync(outputPath, 'utf8');
|
||||||
|
|
||||||
|
await handler.processSingleBundle(bundleConfig);
|
||||||
|
const secondOutput = fs.readFileSync(outputPath, 'utf8');
|
||||||
|
|
||||||
|
expect(secondOutput).toEqual(firstOutput);
|
||||||
|
});
|
||||||
|
|
||||||
// Test size comparison
|
// Test size comparison
|
||||||
tap.test('should show bundle size comparison', async () => {
|
tap.test('should show bundle size comparison', async () => {
|
||||||
const testDir = path.join(process.cwd(), 'test');
|
const testDir = path.join(process.cwd(), 'test');
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
// Test file to verify decorator functionality
|
// Test file to verify decorator functionality
|
||||||
const decoratedClasses: Function[] = [];
|
const decoratedClasses: Function[] = [];
|
||||||
|
|
||||||
function trackClass(constructor: Function) {
|
function trackClass(value: Function, _context: ClassDecoratorContext) {
|
||||||
decoratedClasses.push(constructor);
|
decoratedClasses.push(value);
|
||||||
return constructor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function logMethod(_target: any, context: ClassMethodDecoratorContext) {
|
function logMethod(method: Function, context: ClassMethodDecoratorContext) {
|
||||||
const methodName = String(context.name);
|
const methodName = String(context.name);
|
||||||
return function (this: any, ...args: any[]) {
|
return function (this: any, ...args: any[]) {
|
||||||
console.log(`Calling method: ${methodName}`);
|
console.log(`Calling method: ${methodName}`);
|
||||||
return (_target as Function).apply(this, args);
|
return method.apply(this, args);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ export class MyElement extends LitElement {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
@property({ type: String })
|
@property({ type: String })
|
||||||
name = 'World';
|
accessor name = 'World';
|
||||||
|
|
||||||
@property({ type: Number })
|
@property({ type: Number })
|
||||||
count = 0;
|
accessor count = 0;
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ const myConst: string = 'hello';
|
|||||||
|
|
||||||
await smartdelay.delayFor(1000);
|
await smartdelay.delayFor(1000);
|
||||||
|
|
||||||
function sealed(constructor: Function) {
|
function sealed(value: Function, _context: ClassDecoratorContext) {
|
||||||
Object.seal(constructor);
|
Object.seal(value);
|
||||||
Object.seal(constructor.prototype);
|
Object.seal(value.prototype);
|
||||||
}
|
}
|
||||||
|
|
||||||
@sealed
|
@sealed
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/tsbundle',
|
name: '@git.zone/tsbundle',
|
||||||
version: '2.7.4',
|
version: '2.10.2',
|
||||||
description: 'a multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects'
|
description: 'a multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,7 @@ early.stop();
|
|||||||
export * from './tsbundle.class.tsbundle.js';
|
export * from './tsbundle.class.tsbundle.js';
|
||||||
export * from './mod_assets/index.js';
|
export * from './mod_assets/index.js';
|
||||||
export * from './mod_html/index.js';
|
export * from './mod_html/index.js';
|
||||||
|
export * from './mod_custom/index.js';
|
||||||
|
export * from './mod_output/index.js';
|
||||||
|
export * from './interfaces/index.js';
|
||||||
export { runCli };
|
export { runCli };
|
||||||
|
|||||||
@@ -17,13 +17,16 @@ export interface IEnvTransportOptions {
|
|||||||
export type TOutputMode = 'bundle' | 'base64ts';
|
export type TOutputMode = 'bundle' | 'base64ts';
|
||||||
export type TBundler = 'esbuild' | 'rolldown' | 'rspack';
|
export type TBundler = 'esbuild' | 'rolldown' | 'rspack';
|
||||||
|
|
||||||
|
export type TIncludeFile = string | { from: string; to: string };
|
||||||
|
|
||||||
export interface IBundleConfig {
|
export interface IBundleConfig {
|
||||||
from: string;
|
from: string;
|
||||||
to: string;
|
to: string;
|
||||||
outputMode?: TOutputMode;
|
outputMode?: TOutputMode;
|
||||||
bundler?: TBundler;
|
bundler?: TBundler;
|
||||||
production?: boolean;
|
production?: boolean;
|
||||||
includeFiles?: string[];
|
includeFiles?: TIncludeFile[];
|
||||||
|
maxLineLength?: number; // For base64ts output: max chars per line. 0 or undefined = unlimited (default)
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITsbundleConfig {
|
export interface ITsbundleConfig {
|
||||||
|
|||||||
+8
-10
@@ -40,29 +40,27 @@ export class AssetsHandler {
|
|||||||
// copies the html
|
// copies the html
|
||||||
public async processAssets(optionsArg?: { from?: string; to?: string }) {
|
public async processAssets(optionsArg?: { from?: string; to?: string }) {
|
||||||
// lets assemble the options
|
// lets assemble the options
|
||||||
optionsArg = {
|
const options = {
|
||||||
...{
|
|
||||||
from: this.defaultFromDirPath,
|
from: this.defaultFromDirPath,
|
||||||
to: this.defaultToDirPath,
|
to: this.defaultToDirPath,
|
||||||
},
|
|
||||||
...(optionsArg || {}),
|
...(optionsArg || {}),
|
||||||
};
|
};
|
||||||
await this.ensureAssetsDir();
|
await this.ensureAssetsDir();
|
||||||
optionsArg.from = plugins.smartpath.transform.toAbsolute(
|
options.from = plugins.smartpath.transform.toAbsolute(
|
||||||
optionsArg.from,
|
options.from,
|
||||||
paths.cwd,
|
paths.cwd,
|
||||||
) as string;
|
) as string;
|
||||||
optionsArg.to = plugins.smartpath.transform.toAbsolute(
|
options.to = plugins.smartpath.transform.toAbsolute(
|
||||||
optionsArg.to,
|
options.to,
|
||||||
paths.cwd,
|
paths.cwd,
|
||||||
) as string;
|
) as string;
|
||||||
|
|
||||||
// lets clean the target directory
|
// 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) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-11
@@ -9,18 +9,18 @@ const TEMP_DIR = '.nogit/tsbundle-temp';
|
|||||||
|
|
||||||
export class CustomBundleHandler {
|
export class CustomBundleHandler {
|
||||||
private cwd: string;
|
private cwd: string;
|
||||||
private config: interfaces.ITsbundleConfig;
|
private config!: interfaces.ITsbundleConfig;
|
||||||
|
|
||||||
constructor(cwd: string = paths.cwd) {
|
constructor(cwd: string = paths.cwd) {
|
||||||
this.cwd = cwd;
|
this.cwd = cwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load configuration from npmextra.json
|
* Load configuration from .smartconfig.json
|
||||||
*/
|
*/
|
||||||
public async loadConfig(): Promise<boolean> {
|
public async loadConfig(): Promise<boolean> {
|
||||||
const npmextraInstance = new plugins.npmextra.Npmextra(this.cwd);
|
const smartconfigInstance = new plugins.smartconfig.Smartconfig(this.cwd);
|
||||||
this.config = npmextraInstance.dataFor<interfaces.ITsbundleConfig>('@git.zone/tsbundle', {
|
this.config = smartconfigInstance.dataFor<interfaces.ITsbundleConfig>('@git.zone/tsbundle', {
|
||||||
bundles: [],
|
bundles: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -48,19 +48,20 @@ export class CustomBundleHandler {
|
|||||||
/**
|
/**
|
||||||
* Process a single bundle configuration
|
* Process a single bundle configuration
|
||||||
*/
|
*/
|
||||||
private async processSingleBundle(bundleConfig: interfaces.IBundleConfig): Promise<void> {
|
public async processSingleBundle(bundleConfig: interfaces.IBundleConfig): Promise<void> {
|
||||||
const outputMode = bundleConfig.outputMode || 'bundle';
|
const outputMode = bundleConfig.outputMode || 'bundle';
|
||||||
const bundler = bundleConfig.bundler || 'esbuild';
|
const bundler = bundleConfig.bundler || 'esbuild';
|
||||||
|
|
||||||
// Determine temp output path
|
// Determine temp output path
|
||||||
const tempDir = plugins.path.join(this.cwd, TEMP_DIR);
|
const tempDir = plugins.path.join(this.cwd, TEMP_DIR);
|
||||||
const tempBundlePath = plugins.path.join(tempDir, `bundle-${Date.now()}.js`);
|
const tempBundlePath = plugins.path.join(tempDir, 'bundle.js');
|
||||||
|
|
||||||
// Ensure temp directory exists
|
// Ensure temp directory exists
|
||||||
await plugins.fs.directory(tempDir).create();
|
await plugins.fs.directory(tempDir).create();
|
||||||
|
|
||||||
// Build the bundle to temp location
|
// Build the bundle to temp location
|
||||||
const tsbundle = new TsBundle();
|
const tsbundle = new TsBundle();
|
||||||
|
try {
|
||||||
await tsbundle.build(
|
await tsbundle.build(
|
||||||
this.cwd,
|
this.cwd,
|
||||||
bundleConfig.from,
|
bundleConfig.from,
|
||||||
@@ -70,6 +71,11 @@ export class CustomBundleHandler {
|
|||||||
production: bundleConfig.production || false,
|
production: bundleConfig.production || false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error(`\n\x1b[31m❌ Bundle failed: ${bundleConfig.from} -> ${bundleConfig.to}\x1b[0m`);
|
||||||
|
// Don't re-print error details - they were already shown by the child process
|
||||||
|
return; // Skip output handling since build failed
|
||||||
|
}
|
||||||
|
|
||||||
if (outputMode === 'base64ts') {
|
if (outputMode === 'base64ts') {
|
||||||
await this.handleBase64TsOutput(bundleConfig, tempBundlePath);
|
await this.handleBase64TsOutput(bundleConfig, tempBundlePath);
|
||||||
@@ -82,6 +88,11 @@ export class CustomBundleHandler {
|
|||||||
if (tempFileExists) {
|
if (tempFileExists) {
|
||||||
await plugins.fs.file(tempBundlePath).delete();
|
await plugins.fs.file(tempBundlePath).delete();
|
||||||
}
|
}
|
||||||
|
const tempSourceMapPath = `${tempBundlePath}.map`;
|
||||||
|
const tempSourceMapExists = await plugins.fs.file(tempSourceMapPath).exists();
|
||||||
|
if (tempSourceMapExists) {
|
||||||
|
await plugins.fs.file(tempSourceMapPath).delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,13 +110,17 @@ export class CustomBundleHandler {
|
|||||||
|
|
||||||
// Add included files
|
// Add included files
|
||||||
if (bundleConfig.includeFiles && bundleConfig.includeFiles.length > 0) {
|
if (bundleConfig.includeFiles && bundleConfig.includeFiles.length > 0) {
|
||||||
for (const pattern of bundleConfig.includeFiles) {
|
for (const entry of bundleConfig.includeFiles) {
|
||||||
await base64Output.addFilesFromGlob(pattern);
|
if (typeof entry === 'string') {
|
||||||
|
await base64Output.addFilesFromGlob(entry);
|
||||||
|
} else {
|
||||||
|
await base64Output.addFileWithServePath(entry.from, entry.to);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the TypeScript output
|
// Write the TypeScript output
|
||||||
await base64Output.writeToFile(bundleConfig.to);
|
await base64Output.writeToFile(bundleConfig.to, bundleConfig.maxLineLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,7 +144,8 @@ export class CustomBundleHandler {
|
|||||||
const htmlHandler = new HtmlHandler();
|
const htmlHandler = new HtmlHandler();
|
||||||
const outputDir = plugins.path.dirname(toPath);
|
const outputDir = plugins.path.dirname(toPath);
|
||||||
|
|
||||||
for (const pattern of bundleConfig.includeFiles) {
|
for (const entry of bundleConfig.includeFiles) {
|
||||||
|
const pattern = typeof entry === 'string' ? entry : entry.from;
|
||||||
await this.copyIncludedFiles(pattern, outputDir);
|
await this.copyIncludedFiles(pattern, outputDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,7 +181,8 @@ export class CustomBundleHandler {
|
|||||||
|
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (!entry.isDirectory && regex.test(entry.name)) {
|
if (!entry.isDirectory && regex.test(entry.name)) {
|
||||||
const fullPath = plugins.path.join(dirPath, entry.path);
|
// entry.path is already absolute from smartfs
|
||||||
|
const fullPath = entry.path;
|
||||||
const relativePath = plugins.path.relative(this.cwd, fullPath);
|
const relativePath = plugins.path.relative(this.cwd, fullPath);
|
||||||
const destPath = plugins.path.join(outputDir, plugins.path.basename(entry.path));
|
const destPath = plugins.path.join(outputDir, plugins.path.basename(entry.path));
|
||||||
await plugins.fs.directory(plugins.path.dirname(destPath)).create();
|
await plugins.fs.directory(plugins.path.dirname(destPath)).create();
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export class TsBundleProcess {
|
|||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
target: 'es2022',
|
target: 'es2022',
|
||||||
|
keepNames: true,
|
||||||
entryNames: plugins.path.parse(toArg).name,
|
entryNames: plugins.path.parse(toArg).name,
|
||||||
outdir: plugins.path.parse(toArg).dir,
|
outdir: plugins.path.parse(toArg).dir,
|
||||||
splitting: false,
|
splitting: false,
|
||||||
@@ -67,6 +68,7 @@ export class TsBundleProcess {
|
|||||||
format: 'esm',
|
format: 'esm',
|
||||||
target: 'es2022',
|
target: 'es2022',
|
||||||
minify: true,
|
minify: true,
|
||||||
|
keepNames: true,
|
||||||
entryNames: plugins.path.parse(toArg).name,
|
entryNames: plugins.path.parse(toArg).name,
|
||||||
outdir: plugins.path.parse(toArg).dir,
|
outdir: plugins.path.parse(toArg).dir,
|
||||||
tsconfig: paths.tsconfigPath,
|
tsconfig: paths.tsconfigPath,
|
||||||
@@ -79,10 +81,13 @@ export class TsBundleProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
|
try {
|
||||||
console.log('running spawned compilation process');
|
console.log('running spawned compilation process');
|
||||||
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
|
const transportOptionsJson = process.env.transportOptions;
|
||||||
process.env.transportOptions,
|
if (!transportOptionsJson) {
|
||||||
);
|
throw new Error('Missing transportOptions environment variable');
|
||||||
|
}
|
||||||
|
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(transportOptionsJson);
|
||||||
console.log('=======> ESBUILD');
|
console.log('=======> ESBUILD');
|
||||||
console.log(transportOptions);
|
console.log(transportOptions);
|
||||||
process.chdir(transportOptions.cwd);
|
process.chdir(transportOptions.cwd);
|
||||||
@@ -90,7 +95,7 @@ const run = async () => {
|
|||||||
const tsbundleProcessInstance = new TsBundleProcess();
|
const tsbundleProcessInstance = new TsBundleProcess();
|
||||||
if (transportOptions.mode === 'test') {
|
if (transportOptions.mode === 'test') {
|
||||||
console.log('building for test:');
|
console.log('building for test:');
|
||||||
tsbundleProcessInstance.buildTest(
|
await tsbundleProcessInstance.buildTest(
|
||||||
plugins.smartpath.transform.makeAbsolute(
|
plugins.smartpath.transform.makeAbsolute(
|
||||||
transportOptions.from,
|
transportOptions.from,
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
@@ -103,7 +108,7 @@ const run = async () => {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log('building for production:');
|
console.log('building for production:');
|
||||||
tsbundleProcessInstance.buildProduction(
|
await tsbundleProcessInstance.buildProduction(
|
||||||
plugins.smartpath.transform.makeAbsolute(
|
plugins.smartpath.transform.makeAbsolute(
|
||||||
transportOptions.from,
|
transportOptions.from,
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
@@ -115,6 +120,29 @@ const run = async () => {
|
|||||||
transportOptions.argv,
|
transportOptions.argv,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
process.exit(0);
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('\n\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m');
|
||||||
|
console.error('\x1b[31m❌ BUILD FAILED\x1b[0m');
|
||||||
|
console.error('\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
||||||
|
|
||||||
|
if (error.errors && Array.isArray(error.errors)) {
|
||||||
|
// esbuild errors - format them nicely
|
||||||
|
console.error(`Found ${error.errors.length} error(s):\n`);
|
||||||
|
for (const err of error.errors) {
|
||||||
|
const file = err.location?.file || 'unknown';
|
||||||
|
const line = err.location?.line || '?';
|
||||||
|
const column = err.location?.column || '?';
|
||||||
|
console.error(` \x1b[36m${file}\x1b[0m:\x1b[33m${line}\x1b[0m:\x1b[33m${column}\x1b[0m`);
|
||||||
|
console.error(` ${err.text}\n`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(error.message || error);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error('\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
run();
|
run();
|
||||||
|
|||||||
+10
-12
@@ -21,30 +21,28 @@ export class HtmlHandler {
|
|||||||
to?: string;
|
to?: string;
|
||||||
minify?: boolean;
|
minify?: boolean;
|
||||||
}) {
|
}) {
|
||||||
optionsArg = {
|
const options = {
|
||||||
...{
|
|
||||||
from: this.defaultFromPath,
|
from: this.defaultFromPath,
|
||||||
to: this.defaultToPath,
|
to: this.defaultToPath,
|
||||||
minify: false,
|
minify: false,
|
||||||
},
|
|
||||||
...optionsArg,
|
...optionsArg,
|
||||||
};
|
};
|
||||||
if (await this.checkIfExists()) {
|
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(
|
options.from = plugins.smartpath.transform.toAbsolute(
|
||||||
optionsArg.from,
|
options.from,
|
||||||
paths.cwd,
|
paths.cwd,
|
||||||
) as string;
|
) as string;
|
||||||
optionsArg.to = plugins.smartpath.transform.toAbsolute(
|
options.to = plugins.smartpath.transform.toAbsolute(
|
||||||
optionsArg.to,
|
options.to,
|
||||||
paths.cwd,
|
paths.cwd,
|
||||||
) as string;
|
) as string;
|
||||||
let fileString = (await plugins.fs
|
let fileString = (await plugins.fs
|
||||||
.file(optionsArg.from)
|
.file(options.from)
|
||||||
.encoding('utf8')
|
.encoding('utf8')
|
||||||
.read()) as string;
|
.read()) as string;
|
||||||
if (optionsArg.minify) {
|
if (options.minify) {
|
||||||
fileString = plugins.htmlMinifier.minify(fileString, {
|
fileString = plugins.htmlMinifier.minify(fileString, {
|
||||||
minifyCSS: true,
|
minifyCSS: true,
|
||||||
minifyJS: true,
|
minifyJS: true,
|
||||||
@@ -56,9 +54,9 @@ export class HtmlHandler {
|
|||||||
removeComments: true,
|
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.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!`);
|
console.log(`html processing succeeded!`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-21
@@ -36,20 +36,20 @@ const PRESETS: Record<string, { description: string; config: interfaces.IBundleC
|
|||||||
|
|
||||||
export class InitHandler {
|
export class InitHandler {
|
||||||
private cwd: string;
|
private cwd: string;
|
||||||
private npmextraPath: string;
|
private smartconfigPath: string;
|
||||||
|
|
||||||
constructor(cwd: string = paths.cwd) {
|
constructor(cwd: string = paths.cwd) {
|
||||||
this.cwd = cwd;
|
this.cwd = cwd;
|
||||||
this.npmextraPath = plugins.path.join(this.cwd, 'npmextra.json');
|
this.smartconfigPath = plugins.path.join(this.cwd, '.smartconfig.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load existing npmextra.json or create empty config
|
* Load existing .smartconfig.json or create empty config
|
||||||
*/
|
*/
|
||||||
private async loadExistingConfig(): Promise<any> {
|
private async loadExistingConfig(): Promise<any> {
|
||||||
const fileExists = await plugins.fs.file(this.npmextraPath).exists();
|
const fileExists = await plugins.fs.file(this.smartconfigPath).exists();
|
||||||
if (fileExists) {
|
if (fileExists) {
|
||||||
const content = (await plugins.fs.file(this.npmextraPath).encoding('utf8').read()) as string;
|
const content = (await plugins.fs.file(this.smartconfigPath).encoding('utf8').read()) as string;
|
||||||
try {
|
try {
|
||||||
return JSON.parse(content);
|
return JSON.parse(content);
|
||||||
} catch {
|
} catch {
|
||||||
@@ -60,12 +60,12 @@ export class InitHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save config to npmextra.json
|
* Save config to .smartconfig.json
|
||||||
*/
|
*/
|
||||||
private async saveConfig(config: any): Promise<void> {
|
private async saveConfig(config: any): Promise<void> {
|
||||||
const content = JSON.stringify(config, null, 2);
|
const content = JSON.stringify(config, null, 2);
|
||||||
await plugins.fs.file(this.npmextraPath).encoding('utf8').write(content);
|
await plugins.fs.file(this.smartconfigPath).encoding('utf8').write(content);
|
||||||
console.log(`\n✅ Configuration saved to npmextra.json`);
|
console.log(`\n✅ Configuration saved to .smartconfig.json`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -73,15 +73,15 @@ export class InitHandler {
|
|||||||
*/
|
*/
|
||||||
public async runWizard(): Promise<void> {
|
public async runWizard(): Promise<void> {
|
||||||
console.log('\n🚀 tsbundle configuration wizard\n');
|
console.log('\n🚀 tsbundle configuration wizard\n');
|
||||||
console.log('This wizard will help you configure bundle settings in npmextra.json.\n');
|
console.log('This wizard will help you configure bundle settings in .smartconfig.json.\n');
|
||||||
|
|
||||||
const npmextraJson = await this.loadExistingConfig();
|
const smartconfigJson = await this.loadExistingConfig();
|
||||||
|
|
||||||
if (!npmextraJson['@git.zone/tsbundle']) {
|
if (!smartconfigJson['@git.zone/tsbundle']) {
|
||||||
npmextraJson['@git.zone/tsbundle'] = { bundles: [] };
|
smartconfigJson['@git.zone/tsbundle'] = { bundles: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingBundles = npmextraJson['@git.zone/tsbundle'].bundles || [];
|
const existingBundles = smartconfigJson['@git.zone/tsbundle'].bundles || [];
|
||||||
|
|
||||||
if (existingBundles.length > 0) {
|
if (existingBundles.length > 0) {
|
||||||
console.log(`Found ${existingBundles.length} existing bundle configuration(s):\n`);
|
console.log(`Found ${existingBundles.length} existing bundle configuration(s):\n`);
|
||||||
@@ -95,7 +95,7 @@ export class InitHandler {
|
|||||||
while (addMore) {
|
while (addMore) {
|
||||||
const bundle = await this.configureSingleBundle();
|
const bundle = await this.configureSingleBundle();
|
||||||
if (bundle) {
|
if (bundle) {
|
||||||
npmextraJson['@git.zone/tsbundle'].bundles.push(bundle);
|
smartconfigJson['@git.zone/tsbundle'].bundles.push(bundle);
|
||||||
console.log(`\n✅ Bundle configuration added!`);
|
console.log(`\n✅ Bundle configuration added!`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,10 +112,10 @@ export class InitHandler {
|
|||||||
addMore = answers.getAnswerFor('addAnother');
|
addMore = answers.getAnswerFor('addAnother');
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.saveConfig(npmextraJson);
|
await this.saveConfig(smartconfigJson);
|
||||||
|
|
||||||
console.log('\n📋 Final configuration:\n');
|
console.log('\n📋 Final configuration:\n');
|
||||||
const bundles = npmextraJson['@git.zone/tsbundle'].bundles;
|
const bundles = smartconfigJson['@git.zone/tsbundle'].bundles;
|
||||||
bundles.forEach((bundle: interfaces.IBundleConfig, i: number) => {
|
bundles.forEach((bundle: interfaces.IBundleConfig, i: number) => {
|
||||||
console.log(` Bundle ${i + 1}:`);
|
console.log(` Bundle ${i + 1}:`);
|
||||||
console.log(` From: ${bundle.from}`);
|
console.log(` From: ${bundle.from}`);
|
||||||
@@ -123,7 +123,8 @@ export class InitHandler {
|
|||||||
console.log(` Mode: ${bundle.outputMode || 'bundle'}`);
|
console.log(` Mode: ${bundle.outputMode || 'bundle'}`);
|
||||||
console.log(` Bundler: ${bundle.bundler || 'esbuild'}`);
|
console.log(` Bundler: ${bundle.bundler || 'esbuild'}`);
|
||||||
if (bundle.includeFiles && bundle.includeFiles.length > 0) {
|
if (bundle.includeFiles && bundle.includeFiles.length > 0) {
|
||||||
console.log(` Include: ${bundle.includeFiles.join(', ')}`);
|
const display = bundle.includeFiles.map(f => typeof f === 'string' ? f : `${f.from} -> ${f.to}`);
|
||||||
|
console.log(` Include: ${display.join(', ')}`);
|
||||||
}
|
}
|
||||||
console.log('');
|
console.log('');
|
||||||
});
|
});
|
||||||
@@ -168,7 +169,8 @@ export class InitHandler {
|
|||||||
console.log(` Mode: ${preset.config.outputMode}`);
|
console.log(` Mode: ${preset.config.outputMode}`);
|
||||||
console.log(` Bundler: ${preset.config.bundler}`);
|
console.log(` Bundler: ${preset.config.bundler}`);
|
||||||
if (preset.config.includeFiles && preset.config.includeFiles.length > 0) {
|
if (preset.config.includeFiles && preset.config.includeFiles.length > 0) {
|
||||||
console.log(` Include: ${preset.config.includeFiles.join(', ')}`);
|
const display = preset.config.includeFiles.map(f => typeof f === 'string' ? f : `${f.from} -> ${f.to}`);
|
||||||
|
console.log(` Include: ${display.join(', ')}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmInteract = new plugins.smartinteract.SmartInteract();
|
const confirmInteract = new plugins.smartinteract.SmartInteract();
|
||||||
@@ -293,14 +295,14 @@ export class InitHandler {
|
|||||||
/**
|
/**
|
||||||
* Configure files to include
|
* Configure files to include
|
||||||
*/
|
*/
|
||||||
private async configureIncludeFiles(prefill?: string[]): Promise<string[]> {
|
private async configureIncludeFiles(prefill?: interfaces.TIncludeFile[]): Promise<interfaces.TIncludeFile[]> {
|
||||||
const includeFiles: string[] = [];
|
const includeFiles: interfaces.TIncludeFile[] = [];
|
||||||
let addMore = true;
|
let addMore = true;
|
||||||
|
|
||||||
// If we have prefilled values, show them first
|
// If we have prefilled values, show them first
|
||||||
if (prefill && prefill.length > 0) {
|
if (prefill && prefill.length > 0) {
|
||||||
console.log('\nPre-configured include patterns:');
|
console.log('\nPre-configured include patterns:');
|
||||||
prefill.forEach((p) => console.log(` - ${p}`));
|
prefill.forEach((p) => console.log(` - ${typeof p === 'string' ? p : `${p.from} -> ${p.to}`}`));
|
||||||
|
|
||||||
const keepInteract = new plugins.smartinteract.SmartInteract();
|
const keepInteract = new plugins.smartinteract.SmartInteract();
|
||||||
keepInteract.addQuestions([
|
keepInteract.addQuestions([
|
||||||
|
|||||||
+37
-9
@@ -22,6 +22,20 @@ export class Base64TsOutput {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a file with a custom serve path
|
||||||
|
*/
|
||||||
|
public async addFileWithServePath(fromPath: string, servePath: string): Promise<void> {
|
||||||
|
const absolutePath = plugins.smartpath.transform.toAbsolute(fromPath, this.cwd) as string;
|
||||||
|
const fileExists = await plugins.fs.file(absolutePath).exists();
|
||||||
|
if (!fileExists) {
|
||||||
|
console.log(`File does not exist: ${absolutePath}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const content = await plugins.fs.file(absolutePath).read();
|
||||||
|
this.addFile(servePath, content);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add files matching a glob pattern
|
* Add files matching a glob pattern
|
||||||
*/
|
*/
|
||||||
@@ -56,8 +70,12 @@ export class Base64TsOutput {
|
|||||||
|
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (!entry.isDirectory && regex.test(entry.name)) {
|
if (!entry.isDirectory && regex.test(entry.name)) {
|
||||||
const fullPath = plugins.path.join(dirPath, entry.path);
|
// entry.path may be absolute or relative - handle both cases
|
||||||
const relativePath = plugins.path.relative(this.cwd, fullPath);
|
const fullPath = plugins.path.isAbsolute(entry.path)
|
||||||
|
? entry.path
|
||||||
|
: plugins.path.join(dirPath, entry.path);
|
||||||
|
// Use path relative to pattern's base dir (not cwd) for web serving
|
||||||
|
const relativePath = plugins.path.relative(dirPath, fullPath);
|
||||||
const content = await plugins.fs.file(fullPath).read();
|
const content = await plugins.fs.file(fullPath).read();
|
||||||
this.addFile(relativePath, content);
|
this.addFile(relativePath, content);
|
||||||
}
|
}
|
||||||
@@ -77,18 +95,26 @@ export class Base64TsOutput {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate TypeScript file content
|
* Generate TypeScript file content
|
||||||
|
* @param maxLineLength - Max chars per line for base64 strings. 0 or undefined = unlimited (default)
|
||||||
*/
|
*/
|
||||||
public generateTypeScript(): string {
|
public generateTypeScript(maxLineLength?: number): string {
|
||||||
const MAX_LINE_LENGTH = 200;
|
// Default behavior: no line splitting (unlimited)
|
||||||
|
if (!maxLineLength || maxLineLength <= 0) {
|
||||||
|
const filesJson = JSON.stringify(this.files, null, 2);
|
||||||
|
return `// Auto-generated by tsbundle - do not edit
|
||||||
|
export const files: { path: string; contentBase64: string }[] = ${filesJson};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split base64 strings into chunks when maxLineLength is specified
|
||||||
const formatBase64 = (base64: string): string => {
|
const formatBase64 = (base64: string): string => {
|
||||||
if (base64.length <= MAX_LINE_LENGTH) {
|
if (base64.length <= maxLineLength) {
|
||||||
return `"${base64}"`;
|
return `"${base64}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const chunks: string[] = [];
|
const chunks: string[] = [];
|
||||||
for (let i = 0; i < base64.length; i += MAX_LINE_LENGTH) {
|
for (let i = 0; i < base64.length; i += maxLineLength) {
|
||||||
chunks.push(base64.slice(i, i + MAX_LINE_LENGTH));
|
chunks.push(base64.slice(i, i + maxLineLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
return `"" +\n "${chunks.join('" +\n "')}"`;
|
return `"" +\n "${chunks.join('" +\n "')}"`;
|
||||||
@@ -110,12 +136,14 @@ ${filesFormatted}
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the TypeScript file to disk
|
* Write the TypeScript file to disk
|
||||||
|
* @param outputPath - Output file path
|
||||||
|
* @param maxLineLength - Max chars per line for base64 strings. 0 or undefined = unlimited (default)
|
||||||
*/
|
*/
|
||||||
public async writeToFile(outputPath: string): Promise<void> {
|
public async writeToFile(outputPath: string, maxLineLength?: number): Promise<void> {
|
||||||
const absolutePath = plugins.smartpath.transform.toAbsolute(outputPath, this.cwd) as string;
|
const absolutePath = plugins.smartpath.transform.toAbsolute(outputPath, this.cwd) as string;
|
||||||
const outputDir = plugins.path.dirname(absolutePath);
|
const outputDir = plugins.path.dirname(absolutePath);
|
||||||
await plugins.fs.directory(outputDir).create();
|
await plugins.fs.directory(outputDir).create();
|
||||||
const content = this.generateTypeScript();
|
const content = this.generateTypeScript(maxLineLength);
|
||||||
await plugins.fs.file(absolutePath).encoding('utf8').write(content);
|
await plugins.fs.file(absolutePath).encoding('utf8').write(content);
|
||||||
console.log(`Generated base64ts output: ${outputPath}`);
|
console.log(`Generated base64ts output: ${outputPath}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export class TsBundleProcess {
|
|||||||
entryFileNames: outputFilename,
|
entryFileNames: outputFilename,
|
||||||
format: 'es',
|
format: 'es',
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
inlineDynamicImports: true,
|
codeSplitting: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,16 +83,18 @@ export class TsBundleProcess {
|
|||||||
format: 'es',
|
format: 'es',
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
minify: true,
|
minify: true,
|
||||||
inlineDynamicImports: true,
|
codeSplitting: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
console.log('running spawned compilation process');
|
console.log('running spawned compilation process');
|
||||||
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
|
const transportOptionsJson = process.env.transportOptions;
|
||||||
process.env.transportOptions,
|
if (!transportOptionsJson) {
|
||||||
);
|
throw new Error('Missing transportOptions environment variable');
|
||||||
|
}
|
||||||
|
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(transportOptionsJson);
|
||||||
console.log('=======> ROLLDOWN');
|
console.log('=======> ROLLDOWN');
|
||||||
console.log(transportOptions);
|
console.log(transportOptions);
|
||||||
process.chdir(transportOptions.cwd);
|
process.chdir(transportOptions.cwd);
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export class TsBundleProcess {
|
|||||||
output: {
|
output: {
|
||||||
path: outputDir,
|
path: outputDir,
|
||||||
filename: outputFilename,
|
filename: outputFilename,
|
||||||
|
module: true,
|
||||||
library: {
|
library: {
|
||||||
type: 'module' as const,
|
type: 'module' as const,
|
||||||
},
|
},
|
||||||
@@ -86,9 +87,6 @@ export class TsBundleProcess {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
experiments: {
|
|
||||||
outputModule: true,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -98,6 +96,10 @@ export class TsBundleProcess {
|
|||||||
reject(err);
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!stats) {
|
||||||
|
reject(new Error('Rspack did not return stats'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (stats.hasErrors()) {
|
if (stats.hasErrors()) {
|
||||||
console.error(stats.toString());
|
console.error(stats.toString());
|
||||||
@@ -140,6 +142,7 @@ export class TsBundleProcess {
|
|||||||
output: {
|
output: {
|
||||||
path: outputDir,
|
path: outputDir,
|
||||||
filename: outputFilename,
|
filename: outputFilename,
|
||||||
|
module: true,
|
||||||
library: {
|
library: {
|
||||||
type: 'module' as const,
|
type: 'module' as const,
|
||||||
},
|
},
|
||||||
@@ -184,9 +187,6 @@ export class TsBundleProcess {
|
|||||||
usedExports: true,
|
usedExports: true,
|
||||||
sideEffects: true,
|
sideEffects: true,
|
||||||
},
|
},
|
||||||
experiments: {
|
|
||||||
outputModule: true,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -196,6 +196,10 @@ export class TsBundleProcess {
|
|||||||
reject(err);
|
reject(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!stats) {
|
||||||
|
reject(new Error('Rspack did not return stats'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (stats.hasErrors()) {
|
if (stats.hasErrors()) {
|
||||||
console.error(stats.toString());
|
console.error(stats.toString());
|
||||||
@@ -221,9 +225,11 @@ export class TsBundleProcess {
|
|||||||
|
|
||||||
const run = async () => {
|
const run = async () => {
|
||||||
console.log('running spawned compilation process');
|
console.log('running spawned compilation process');
|
||||||
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
|
const transportOptionsJson = process.env.transportOptions;
|
||||||
process.env.transportOptions,
|
if (!transportOptionsJson) {
|
||||||
);
|
throw new Error('Missing transportOptions environment variable');
|
||||||
|
}
|
||||||
|
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(transportOptionsJson);
|
||||||
console.log('=======> RSPACK');
|
console.log('=======> RSPACK');
|
||||||
console.log(transportOptions);
|
console.log(transportOptions);
|
||||||
process.chdir(transportOptions.cwd);
|
process.chdir(transportOptions.cwd);
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@ import * as path from 'path';
|
|||||||
export { path };
|
export { path };
|
||||||
|
|
||||||
// pushrocks scope
|
// pushrocks scope
|
||||||
import * as npmextra from '@push.rocks/npmextra';
|
import * as smartconfig from '@push.rocks/smartconfig';
|
||||||
import * as smartcli from '@push.rocks/smartcli';
|
import * as smartcli from '@push.rocks/smartcli';
|
||||||
import * as smartfs from '@push.rocks/smartfs';
|
import * as smartfs from '@push.rocks/smartfs';
|
||||||
import * as smartinteract from '@push.rocks/smartinteract';
|
import * as smartinteract from '@push.rocks/smartinteract';
|
||||||
@@ -15,7 +15,7 @@ import * as smartpromise from '@push.rocks/smartpromise';
|
|||||||
import * as smartspawn from '@push.rocks/smartspawn';
|
import * as smartspawn from '@push.rocks/smartspawn';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
npmextra,
|
smartconfig,
|
||||||
smartcli,
|
smartcli,
|
||||||
smartfs,
|
smartfs,
|
||||||
smartinteract,
|
smartinteract,
|
||||||
|
|||||||
@@ -45,7 +45,11 @@ export class TsBundle {
|
|||||||
);
|
);
|
||||||
const childProcess = await threadsimple.start();
|
const childProcess = await threadsimple.start();
|
||||||
childProcess.on('exit', (status) => {
|
childProcess.on('exit', (status) => {
|
||||||
|
if (status !== 0) {
|
||||||
|
done.reject(new Error(`Bundle build failed with exit code ${status}`));
|
||||||
|
} else {
|
||||||
done.resolve();
|
done.resolve();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
await done.promise;
|
await done.promise;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ import { runInit } from './mod_init/index.js';
|
|||||||
export const runCli = async () => {
|
export const runCli = async () => {
|
||||||
const tsBundleCli = new plugins.smartcli.Smartcli();
|
const tsBundleCli = new plugins.smartcli.Smartcli();
|
||||||
|
|
||||||
// Default command: run custom bundles from npmextra.json
|
// Default command: run custom bundles from .smartconfig.json
|
||||||
tsBundleCli.standardCommand().subscribe(async (argvArg) => {
|
tsBundleCli.standardCommand().subscribe(async (argvArg) => {
|
||||||
await runCustomBundles();
|
await runCustomBundles();
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-3
@@ -4,9 +4,7 @@
|
|||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
"moduleResolution": "NodeNext",
|
"moduleResolution": "NodeNext",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"verbatimModuleSyntax": true,
|
"verbatimModuleSyntax": true
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {}
|
|
||||||
},
|
},
|
||||||
"exclude": ["dist_*/**/*.d.ts"]
|
"exclude": ["dist_*/**/*.d.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user