Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6dd7d6e093 | |||
| cd53bdb6f4 |
66
.gitea/workflows/default_nottags.yaml
Normal file
66
.gitea/workflows/default_nottags.yaml
Normal file
@@ -0,0 +1,66 @@
|
||||
name: Default (not tags)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
|
||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
|
||||
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
|
||||
|
||||
jobs:
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install pnpm and npmci
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
|
||||
- name: Run npm prepare
|
||||
run: npmci npm prepare
|
||||
|
||||
- name: Audit production dependencies
|
||||
run: |
|
||||
npmci command npm config set registry https://registry.npmjs.org
|
||||
npmci command pnpm audit --audit-level=high --prod
|
||||
continue-on-error: true
|
||||
|
||||
- name: Audit development dependencies
|
||||
run: |
|
||||
npmci command npm config set registry https://registry.npmjs.org
|
||||
npmci command pnpm audit --audit-level=high --dev
|
||||
continue-on-error: true
|
||||
|
||||
test:
|
||||
if: ${{ always() }}
|
||||
needs: security
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Test stable
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
npmci npm test
|
||||
|
||||
- name: Test build
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
npmci npm build
|
||||
124
.gitea/workflows/default_tags.yaml
Normal file
124
.gitea/workflows/default_tags.yaml
Normal file
@@ -0,0 +1,124 @@
|
||||
name: Default (tags)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
env:
|
||||
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
|
||||
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
|
||||
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
|
||||
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
|
||||
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}
|
||||
NPMCI_URL_CLOUDLY: ${{secrets.NPMCI_URL_CLOUDLY}}
|
||||
|
||||
jobs:
|
||||
security:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
npmci npm prepare
|
||||
|
||||
- name: Audit production dependencies
|
||||
run: |
|
||||
npmci command npm config set registry https://registry.npmjs.org
|
||||
npmci command pnpm audit --audit-level=high --prod
|
||||
continue-on-error: true
|
||||
|
||||
- name: Audit development dependencies
|
||||
run: |
|
||||
npmci command npm config set registry https://registry.npmjs.org
|
||||
npmci command pnpm audit --audit-level=high --dev
|
||||
continue-on-error: true
|
||||
|
||||
test:
|
||||
if: ${{ always() }}
|
||||
needs: security
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
npmci npm prepare
|
||||
|
||||
- name: Test stable
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
npmci npm test
|
||||
|
||||
- name: Test build
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
npmci npm build
|
||||
|
||||
release:
|
||||
needs: test
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
npmci npm prepare
|
||||
|
||||
- name: Release
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm publish
|
||||
|
||||
metadata:
|
||||
needs: test
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ env.IMAGE }}
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
pnpm install -g pnpm
|
||||
pnpm install -g @ship.zone/npmci
|
||||
npmci npm prepare
|
||||
|
||||
- name: Code quality
|
||||
run: |
|
||||
npmci command npm install -g typescript
|
||||
npmci npm install
|
||||
|
||||
- name: Trigger
|
||||
run: npmci trigger
|
||||
|
||||
- name: Build docs and upload artifacts
|
||||
run: |
|
||||
npmci node install stable
|
||||
npmci npm install
|
||||
pnpm install -g @git.zone/tsdoc
|
||||
npmci command tsdoc
|
||||
continue-on-error: true
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -3,7 +3,6 @@
|
||||
# artifacts
|
||||
coverage/
|
||||
public/
|
||||
pages/
|
||||
|
||||
# installs
|
||||
node_modules/
|
||||
@@ -17,4 +16,8 @@ node_modules/
|
||||
dist/
|
||||
dist_*/
|
||||
|
||||
# custom
|
||||
# AI
|
||||
.claude/
|
||||
.serena/
|
||||
|
||||
#------# custom
|
||||
31
changelog.md
31
changelog.md
@@ -1,12 +1,27 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-11-23 - 2.6.0 - feat(core)
|
||||
Integrate Rolldown as optional bundler, migrate filesystem to smartfs, and update bundler/tooling
|
||||
|
||||
- Add optional 'rolldown' bundler and wiring in TsBundle (supports --bundler=rolldown)
|
||||
- Migrate filesystem usage from @push.rocks/smartfile to @push.rocks/smartfs and provide a shared async SmartFs instance
|
||||
- Refactor HtmlHandler and AssetsHandler to use async smartfs APIs and improve HTML/asset processing (create dirs, write files, delete/replace targets)
|
||||
- Update bundler child processes to read tsconfig async for alias resolution and normalize argument handling
|
||||
- Bump dev and runtime dependencies: tsbuild, tsrun, tstest, rolldown, rspack, esbuild, typescript and related packages
|
||||
- Add repository/metadata fields and pnpm section to package.json
|
||||
- Add CI workflow definitions (.gitea/workflows) and docs build script (buildDocs)
|
||||
- Update TypeScript config target to ES2022, adjust module settings and baseUrl/paths
|
||||
- Small test and formatting fixes (test runners, HTML test, decorator test output formatting)
|
||||
|
||||
## 2025-11-17 - 2.5.2 - fix(tsconfig)
|
||||
|
||||
Update TypeScript configs to ES2022 and remove deprecated compiler flags
|
||||
|
||||
- assets/tsconfig.json: set target and module to ES2022 (was ES2020)
|
||||
- assets/tsconfig.json and tsconfig.json: remove experimentalDecorators and useDefineForClassFields flags to align with updated TS setup
|
||||
|
||||
## 2025-06-26 - 2.5.1 - fix(readme)
|
||||
|
||||
Update license and legal information section in readme
|
||||
|
||||
- Replaced contribution guidelines with detailed legal and trademark information
|
||||
@@ -14,6 +29,7 @@ Update license and legal information section in readme
|
||||
- Added company information for Task Venture Capital GmbH
|
||||
|
||||
## 2025-06-26 - 2.5.0 - feat(documentation)
|
||||
|
||||
Improve README with comprehensive installation, usage, and API reference details
|
||||
|
||||
- Updated installation instructions for both global and local setups
|
||||
@@ -23,12 +39,14 @@ Improve README with comprehensive installation, usage, and API reference details
|
||||
- Reorganized content to improve clarity and best practices guidance
|
||||
|
||||
## 2025-06-26 - 2.4.1 - fix(tests)
|
||||
|
||||
Improve decorator tests and add LitElement component tests for better validation
|
||||
|
||||
- Refactored test-decorators.ts to robustly verify that the sealed decorator prevents prototype modifications
|
||||
- Added test-lit.ts to ensure LitElement component renders correctly and increments counter on click
|
||||
|
||||
## 2025-06-19 - 2.4.0 - feat(bundler)
|
||||
|
||||
Introduce rspack bundler support and update multi-bundler workflow
|
||||
|
||||
- Added full support for rspack with its own implementation in ts/mod_rspack
|
||||
@@ -38,6 +56,7 @@ Introduce rspack bundler support and update multi-bundler workflow
|
||||
- Adjusted output configuration for esbuild and rolldown for dynamic naming and inline dynamic imports
|
||||
|
||||
## 2025-06-19 - 2.3.0 - feat(bundler)
|
||||
|
||||
Integrate rolldown bundler support and update bundler selection logic
|
||||
|
||||
- Added rolldown dependency to package.json
|
||||
@@ -47,39 +66,46 @@ Integrate rolldown bundler support and update bundler selection logic
|
||||
- Revised readme and hints documentation for rolldown usage
|
||||
|
||||
## 2025-01-29 - 2.2.5 - fix(mod_assets)
|
||||
|
||||
Fix async handling in asset processing
|
||||
|
||||
- Ensured that the empty directory operation is awaited in the asset processing workflow.
|
||||
|
||||
## 2025-01-29 - 2.2.4 - fix(mod_assets)
|
||||
|
||||
Fix logging message in ensureAssetsDir to correctly state when directory is created
|
||||
|
||||
- Corrected logging output in ensureAssetsDir method to indicate directory creation.
|
||||
|
||||
## 2025-01-29 - 2.2.3 - fix(mod_assets)
|
||||
|
||||
Fix issue with asset directory copy
|
||||
|
||||
- Updated dependency '@push.rocks/smartfile' to version '^11.2.0'
|
||||
- Ensure target directory is properly replaced when copying assets
|
||||
|
||||
## 2025-01-29 - 2.2.2 - fix(dependencies)
|
||||
|
||||
Update smartfile dependency and fix spacing issue in assets module
|
||||
|
||||
- Updated @push.rocks/smartfile from ^11.1.6 to ^11.1.8
|
||||
- Fixed a spacing issue in the processAssets function within the assets module
|
||||
|
||||
## 2025-01-29 - 2.2.1 - fix(index)
|
||||
|
||||
Export mod_assets for programmatic use
|
||||
|
||||
- Added export for mod_assets/index in ts/index.ts to make it usable programmatically.
|
||||
|
||||
## 2025-01-29 - 2.2.0 - feat(AssetsHandler)
|
||||
|
||||
Add asset handling to the CLI workflow
|
||||
|
||||
- Introduced AssetsHandler class for managing asset directories and files.
|
||||
- Updated tsbundle.cli.ts to include asset processing in the 'website' command.
|
||||
|
||||
## 2025-01-28 - 2.1.1 - fix(core)
|
||||
|
||||
Update dependencies and remove GitLab CI configuration.
|
||||
|
||||
- Updated several devDependencies to newer versions for improved stability and performance.
|
||||
@@ -87,24 +113,27 @@ Update dependencies and remove GitLab CI configuration.
|
||||
- Removed the .gitlab-ci.yml file, which could suggest a change in continuous integration setup.
|
||||
|
||||
## 2024-10-27 - 2.1.0 - feat(mod_esbuild)
|
||||
|
||||
Add alias support to esbuild bundling process
|
||||
|
||||
- Updated dependencies in package.json to latest versions.
|
||||
- Improved build process by adding alias resolution based on tsconfig.json settings in esbuild.
|
||||
|
||||
## 2022-05-04 - 2.0.0-2.0.1 - Breaking and Fix Changes
|
||||
|
||||
Released version 2.0.0 with breaking changes and subsequent fixes.
|
||||
|
||||
- BREAKING CHANGE(core): Removed parcel and rollup
|
||||
- fix(core): Addressed initial issues in new major version
|
||||
|
||||
## 2023-10-03 - 2.0.10 - Fix Updates
|
||||
|
||||
Ongoing updates and improvements.
|
||||
|
||||
- fix(core): General updates and enhancements
|
||||
|
||||
## 2024-01-10 - 2.0.11-2.0.15 - Minor Fixes
|
||||
|
||||
Cumulative fixes and updates from recent releases.
|
||||
|
||||
- fix(core): Continuous improvement cycle across versions
|
||||
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
"npmGlobalTools": [],
|
||||
"npmAccessLevel": "public"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
package.json
41
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@git.zone/tsbundle",
|
||||
"version": "2.5.2",
|
||||
"version": "2.6.0",
|
||||
"private": false,
|
||||
"description": "a multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects",
|
||||
"main": "dist_ts/index.js",
|
||||
@@ -10,34 +10,34 @@
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "npm run build && (tstest test/ --verbose)",
|
||||
"build": "(tsbuild --web --allowimplicitany)"
|
||||
"build": "(tsbuild --web --allowimplicitany)",
|
||||
"buildDocs": "tsdoc"
|
||||
},
|
||||
"bin": {
|
||||
"tsbundle": "cli.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@git.zone/tsbuild": "^2.6.4",
|
||||
"@git.zone/tsrun": "^1.3.3",
|
||||
"@git.zone/tstest": "^2.3.1",
|
||||
"@push.rocks/tapbundle": "^6.0.3",
|
||||
"@git.zone/tsbuild": "^3.1.0",
|
||||
"@git.zone/tsrun": "^2.0.0",
|
||||
"@git.zone/tstest": "^3.1.3",
|
||||
"@types/node": "^22.12.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@push.rocks/early": "^4.0.4",
|
||||
"@push.rocks/smartcli": "^4.0.11",
|
||||
"@push.rocks/smartcli": "^4.0.19",
|
||||
"@push.rocks/smartdelay": "^3.0.5",
|
||||
"@push.rocks/smartfile": "^11.2.5",
|
||||
"@push.rocks/smartfs": "^1.1.0",
|
||||
"@push.rocks/smartlog": "^3.1.8",
|
||||
"@push.rocks/smartlog-destination-local": "^9.0.2",
|
||||
"@push.rocks/smartpath": "^5.0.18",
|
||||
"@push.rocks/smartpath": "^6.0.0",
|
||||
"@push.rocks/smartpromise": "^4.2.3",
|
||||
"@push.rocks/smartspawn": "^3.0.3",
|
||||
"@types/html-minifier": "^4.0.5",
|
||||
"esbuild": "^0.25.5",
|
||||
"@rspack/core": "^1.6.4",
|
||||
"@types/html-minifier": "^4.0.6",
|
||||
"esbuild": "^0.27.0",
|
||||
"html-minifier": "^4.0.0",
|
||||
"rolldown": "^1.0.0-beta.18",
|
||||
"@rspack/core": "^1.1.8",
|
||||
"typescript": "5.8.3"
|
||||
"rolldown": "1.0.0-beta.51",
|
||||
"typescript": "5.9.3"
|
||||
},
|
||||
"files": [
|
||||
"ts/**/*",
|
||||
@@ -54,5 +54,16 @@
|
||||
"browserslist": [
|
||||
"last 1 chrome versions"
|
||||
],
|
||||
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
|
||||
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitlab.com/gitzone/tsbundle.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://gitlab.com/gitzone/tsbundle/issues"
|
||||
},
|
||||
"homepage": "https://gitlab.com/gitzone/tsbundle#readme",
|
||||
"pnpm": {
|
||||
"overrides": {}
|
||||
}
|
||||
}
|
||||
|
||||
7446
pnpm-lock.yaml
generated
7446
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,31 @@
|
||||
# tsbundle Hints and Findings
|
||||
|
||||
## Recent Updates (2025-11-23)
|
||||
|
||||
- Migrated from @push.rocks/smartfile v11 to @push.rocks/smartfs v1.1.0
|
||||
- All filesystem operations now use async smartfs API
|
||||
- Removed @push.rocks/tapbundle (now imported from @git.zone/tstest/tapbundle)
|
||||
- All bundlers (esbuild, rolldown, rspack) updated to latest versions
|
||||
- Removed deprecated rolldown experimental.enableComposingJsPlugins option
|
||||
|
||||
## Bundler Architecture
|
||||
|
||||
- tsbundle uses a child process architecture where each bundler runs in a separate process
|
||||
- Configuration is passed via environment variables as JSON (IEnvTransportOptions)
|
||||
- The main class `TsBundle` spawns child processes using `smartspawn.ThreadSimple`
|
||||
|
||||
## Bundler Implementations
|
||||
- **esbuild** (default): Fully implemented, production ready, 2.2K minified
|
||||
- **rolldown**: Implemented and working (beta), produces smallest bundles (1.5K minified)
|
||||
- **rspack**: Implemented and working, webpack-compatible API, 6.1K minified
|
||||
|
||||
- **esbuild** (default): Fully implemented, production ready, 3.9K minified
|
||||
- **rolldown**: Implemented and working (beta v1.0.0-beta.51), produces smallest bundles (1.0K minified)
|
||||
- **rspack**: Implemented and working (v1.6.4), webpack-compatible API, 6.3K minified
|
||||
- **rollup**: Removed (was never implemented)
|
||||
- **parcel**: Removed (was never implemented)
|
||||
|
||||
## Adding New Bundlers
|
||||
|
||||
To add a new bundler, you need:
|
||||
|
||||
1. Update `ICliOptions` interface to include the bundler name
|
||||
2. Add case in `getBundlerPath()` switch statement
|
||||
3. Create `mod_<bundler>/` directory with:
|
||||
@@ -22,6 +34,7 @@ To add a new bundler, you need:
|
||||
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
|
||||
@@ -31,6 +44,7 @@ To add a new bundler, you need:
|
||||
- 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
|
||||
@@ -39,11 +53,13 @@ To add a new bundler, you need:
|
||||
- Supports ES modules output via `experiments.outputModule: true`
|
||||
|
||||
## CLI Usage
|
||||
|
||||
- Default bundler: `tsbundle` (uses esbuild)
|
||||
- Specify bundler: `tsbundle --bundler=rolldown` or `tsbundle --bundler=rspack`
|
||||
- Production mode: `tsbundle --production`
|
||||
- Combined: `tsbundle --bundler=rolldown --production`
|
||||
|
||||
## Known Issues
|
||||
|
||||
- esbuild recently had splitting and tree-shaking disabled due to issues
|
||||
- The README still mentions "a bundler using rollup" but uses esbuild by default
|
||||
- The README still mentions "a bundler using rollup" but uses esbuild by default
|
||||
|
||||
93
readme.md
93
readme.md
@@ -2,6 +2,10 @@
|
||||
|
||||
A powerful multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects.
|
||||
|
||||
## Issue Reporting and Security
|
||||
|
||||
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
@@ -41,22 +45,17 @@ const bundler = new TsBundle();
|
||||
|
||||
// Basic usage
|
||||
await bundler.build(
|
||||
process.cwd(), // working directory
|
||||
'./src/index.ts', // entry point
|
||||
'./dist/bundle.js', // output file
|
||||
{ bundler: 'esbuild' } // options
|
||||
process.cwd(), // working directory
|
||||
'./src/index.ts', // entry point
|
||||
'./dist/bundle.js', // output file
|
||||
{ bundler: 'esbuild' }, // options
|
||||
);
|
||||
|
||||
// Production build with rolldown
|
||||
await bundler.build(
|
||||
process.cwd(),
|
||||
'./src/index.ts',
|
||||
'./dist/bundle.min.js',
|
||||
{
|
||||
bundler: 'rolldown',
|
||||
production: true
|
||||
}
|
||||
);
|
||||
await bundler.build(process.cwd(), './src/index.ts', './dist/bundle.min.js', {
|
||||
bundler: 'rolldown',
|
||||
production: true,
|
||||
});
|
||||
```
|
||||
|
||||
## Available Bundlers
|
||||
@@ -141,9 +140,9 @@ await bundler.build(
|
||||
```typescript
|
||||
interface ICliOptions {
|
||||
bundler: 'esbuild' | 'rolldown' | 'rspack'; // Bundler to use
|
||||
production?: boolean; // Enable production optimizations
|
||||
commonjs?: boolean; // Output CommonJS format
|
||||
skiplibcheck?: boolean; // Skip TypeScript lib checking
|
||||
production?: boolean; // Enable production optimizations
|
||||
commonjs?: boolean; // Output CommonJS format
|
||||
skiplibcheck?: boolean; // Skip TypeScript lib checking
|
||||
}
|
||||
```
|
||||
|
||||
@@ -161,9 +160,9 @@ const exists = await htmlHandler.checkIfExists();
|
||||
|
||||
// Process HTML with options
|
||||
await htmlHandler.processHtml({
|
||||
from: './src/index.html', // Source HTML (default: './html/index.html')
|
||||
to: './dist/index.html', // Output HTML (default: './dist_serve/index.html')
|
||||
minify: true // Enable minification
|
||||
from: './src/index.html', // Source HTML (default: './html/index.html')
|
||||
to: './dist/index.html', // Output HTML (default: './dist_serve/index.html')
|
||||
minify: true, // Enable minification
|
||||
});
|
||||
```
|
||||
|
||||
@@ -181,8 +180,8 @@ await assetsHandler.ensureAssetsDir();
|
||||
|
||||
// Copy and process assets
|
||||
await assetsHandler.processAssets({
|
||||
from: './src/assets', // Source directory (default: './assets')
|
||||
to: './dist/assets' // Output directory (default: './dist_serve/assets')
|
||||
from: './src/assets', // Source directory (default: './assets')
|
||||
to: './dist/assets', // Output directory (default: './dist_serve/assets')
|
||||
});
|
||||
```
|
||||
|
||||
@@ -197,31 +196,26 @@ async function buildWebApp() {
|
||||
const bundler = new TsBundle();
|
||||
const htmlHandler = new HtmlHandler();
|
||||
const assetsHandler = new AssetsHandler();
|
||||
|
||||
|
||||
// Bundle the JavaScript
|
||||
await bundler.build(
|
||||
process.cwd(),
|
||||
'./src/app.ts',
|
||||
'./dist/app.js',
|
||||
{
|
||||
bundler: 'rolldown',
|
||||
production: true
|
||||
}
|
||||
);
|
||||
|
||||
await bundler.build(process.cwd(), './src/app.ts', './dist/app.js', {
|
||||
bundler: 'rolldown',
|
||||
production: true,
|
||||
});
|
||||
|
||||
// Process HTML
|
||||
await htmlHandler.processHtml({
|
||||
from: './src/index.html',
|
||||
to: './dist/index.html',
|
||||
minify: true
|
||||
minify: true,
|
||||
});
|
||||
|
||||
|
||||
// Copy assets
|
||||
await assetsHandler.processAssets({
|
||||
from: './src/assets',
|
||||
to: './dist/assets'
|
||||
to: './dist/assets',
|
||||
});
|
||||
|
||||
|
||||
console.log('Build complete!');
|
||||
}
|
||||
|
||||
@@ -238,16 +232,13 @@ async function buildMultipleEntries() {
|
||||
const entries = [
|
||||
{ from: './src/main.ts', to: './dist/main.js' },
|
||||
{ from: './src/admin.ts', to: './dist/admin.js' },
|
||||
{ from: './src/worker.ts', to: './dist/worker.js' }
|
||||
{ from: './src/worker.ts', to: './dist/worker.js' },
|
||||
];
|
||||
|
||||
|
||||
for (const entry of entries) {
|
||||
await bundler.build(
|
||||
process.cwd(),
|
||||
entry.from,
|
||||
entry.to,
|
||||
{ bundler: 'esbuild' }
|
||||
);
|
||||
await bundler.build(process.cwd(), entry.from, entry.to, {
|
||||
bundler: 'esbuild',
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -264,11 +255,11 @@ await bundler.build(
|
||||
process.cwd(),
|
||||
'./src/index.ts',
|
||||
isDev ? './dist/dev/bundle.js' : './dist/prod/bundle.min.js',
|
||||
{
|
||||
bundler: isDev ? 'esbuild' : 'rolldown', // esbuild for speed in dev
|
||||
production: !isDev, // minify in production
|
||||
commonjs: false // use ES modules
|
||||
}
|
||||
{
|
||||
bundler: isDev ? 'esbuild' : 'rolldown', // esbuild for speed in dev
|
||||
production: !isDev, // minify in production
|
||||
commonjs: false, // use ES modules
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
@@ -293,7 +284,7 @@ tsbundle works best with the following TypeScript configuration:
|
||||
|
||||
1. **Entry Points**: Keep your entry points in `ts_web/` for web bundles or `ts/` for library bundles
|
||||
2. **Output Structure**: Use `dist_bundle/` for bundled files and `dist_serve/` for web-ready files
|
||||
3. **Bundler Selection**:
|
||||
3. **Bundler Selection**:
|
||||
- Use `esbuild` for development (fastest)
|
||||
- Use `rolldown` or `rspack` for production (better optimization)
|
||||
4. **Assets**: Place static assets in the `assets/` directory
|
||||
@@ -316,4 +307,4 @@ Registered at District court Bremen HRB 35230 HB, Germany
|
||||
|
||||
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
|
||||
|
||||
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
||||
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
**Command to reread CLAUDE.md**: `cat ~/.claude/CLAUDE.md`
|
||||
|
||||
## Objective
|
||||
|
||||
Add Rolldown as an optional bundler to tsbundle while keeping esbuild as the default bundler. This allows users to experiment with Rolldown using `--bundler=rolldown` flag.
|
||||
|
||||
## Current State
|
||||
|
||||
- tsbundle currently only uses esbuild despite having interfaces for multiple bundlers
|
||||
- The bundler selection logic exists but always returns esbuild
|
||||
- mod_rollup and mod_parcel directories exist but are empty
|
||||
@@ -14,23 +16,26 @@ Add Rolldown as an optional bundler to tsbundle while keeping esbuild as the def
|
||||
## Implementation Tasks
|
||||
|
||||
### Phase 1: Core Infrastructure
|
||||
|
||||
- [x] Update `ts/interfaces/index.ts` to include 'rolldown' in bundler union type
|
||||
- [x] Fix `getBundlerPath()` in `ts/tsbundle.class.tsbundle.ts` to properly route bundlers
|
||||
- [x] Remove hardcoded `bundler: 'esbuild'` from transportOptions (line 26)
|
||||
- [x] Add rolldown dependency to package.json: `"rolldown": "^1.0.0-beta.18"`
|
||||
|
||||
### Phase 2: CLI Support
|
||||
|
||||
- [x] Check if `ts/tsbundle.cli.ts` already parses --bundler option
|
||||
- [x] Ensure default bundler is 'esbuild' when not specified
|
||||
- [x] Verify CLI passes bundler option correctly to TsBundle class
|
||||
|
||||
### Phase 3: Rolldown Module Implementation
|
||||
|
||||
- [x] Create `ts/mod_rolldown/` directory
|
||||
- [x] Create `ts/mod_rolldown/plugins.ts`:
|
||||
```typescript
|
||||
export * from '../plugins.js';
|
||||
import { rolldown } from 'rolldown';
|
||||
export { rolldown }
|
||||
export { rolldown };
|
||||
```
|
||||
- [x] Create `ts/mod_rolldown/index.child.ts` with:
|
||||
- TsBundleProcess class
|
||||
@@ -40,6 +45,7 @@ Add Rolldown as an optional bundler to tsbundle while keeping esbuild as the def
|
||||
- run() function to read transportOptions and execute
|
||||
|
||||
### Phase 4: Feature Parity
|
||||
|
||||
- [x] Implement TypeScript compilation via rolldown
|
||||
- [x] Ensure source map generation works
|
||||
- [x] Support tsconfig path aliases
|
||||
@@ -48,6 +54,7 @@ Add Rolldown as an optional bundler to tsbundle while keeping esbuild as the def
|
||||
- [x] Handle bundle: true behavior
|
||||
|
||||
### Phase 5: Testing
|
||||
|
||||
- [x] Test default behavior (should use esbuild)
|
||||
- [x] Test `--bundler=esbuild` explicit selection
|
||||
- [x] Test `--bundler=rolldown` selection
|
||||
@@ -57,19 +64,21 @@ Add Rolldown as an optional bundler to tsbundle while keeping esbuild as the def
|
||||
## Technical Specifications
|
||||
|
||||
### Rolldown Configuration Mapping
|
||||
| esbuild option | rolldown equivalent |
|
||||
|----------------|-------------------|
|
||||
| bundle: true | bundle: true |
|
||||
| sourcemap: true | sourcemap: true |
|
||||
| format: 'esm' | format: 'es' |
|
||||
|
||||
| esbuild option | rolldown equivalent |
|
||||
| ---------------- | ----------------------------------- |
|
||||
| bundle: true | bundle: true |
|
||||
| sourcemap: true | sourcemap: true |
|
||||
| format: 'esm' | format: 'es' |
|
||||
| target: 'es2022' | (use default, no direct equivalent) |
|
||||
| minify: true | minify: true |
|
||||
| entryPoints | input |
|
||||
| outfile | output.file |
|
||||
| tsconfig | resolve.tsconfigFilename |
|
||||
| alias | resolve.alias |
|
||||
| minify: true | minify: true |
|
||||
| entryPoints | input |
|
||||
| outfile | output.file |
|
||||
| tsconfig | resolve.tsconfigFilename |
|
||||
| alias | resolve.alias |
|
||||
|
||||
### CLI Usage
|
||||
|
||||
```bash
|
||||
# Default (uses esbuild)
|
||||
tsbundle
|
||||
@@ -82,12 +91,14 @@ tsbundle --production --bundler=rolldown
|
||||
```
|
||||
|
||||
## Risks and Mitigation
|
||||
|
||||
1. **Rolldown is beta** - Keep esbuild as default, mark rolldown as experimental
|
||||
2. **API differences** - Abstract common interface, handle bundler-specific logic
|
||||
3. **Missing features** - Document any limitations in README
|
||||
4. **Breaking changes** - None, as esbuild remains default
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [x] Can build with esbuild (default behavior unchanged)
|
||||
- [x] Can build with rolldown via --bundler flag
|
||||
- [x] Both bundlers produce working ESM output
|
||||
@@ -96,9 +107,11 @@ tsbundle --production --bundler=rolldown
|
||||
- [ ] All existing tests pass
|
||||
|
||||
## Implementation Status
|
||||
|
||||
✅ **COMPLETED** - Rolldown has been successfully integrated as an optional bundler.
|
||||
|
||||
### Test Results:
|
||||
|
||||
- esbuild (default): Working correctly, 2.2K minified
|
||||
- rolldown: Working correctly, 1.5K minified (better compression!)
|
||||
- Both bundlers support all required features
|
||||
@@ -106,7 +119,8 @@ tsbundle --production --bundler=rolldown
|
||||
- Production and test modes work for both
|
||||
|
||||
## Future Considerations
|
||||
|
||||
- Once Rolldown reaches v1.0.0 stable, consider making it default
|
||||
- Implement rollup and parcel modules using same pattern
|
||||
- Add performance benchmarks comparing bundlers
|
||||
- Consider adding --watch mode support
|
||||
- Consider adding --watch mode support
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
|
||||
<!--Lets make sure we support older browsers-->
|
||||
<script src=" https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/icon?family=Material+Icons"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
|
||||
<!--Lets avoid a rescaling flicker due to default body margins-->
|
||||
<style>
|
||||
@@ -62,13 +65,11 @@
|
||||
}
|
||||
</style>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
We need JavaScript to run properly!
|
||||
</div>
|
||||
<div class="header">We need JavaScript to run properly!</div>
|
||||
<div class="content">
|
||||
This site is being built using lit-element (made by Google). This technology works with
|
||||
JavaScript. Subsequently this website does not work as intended by Lossless GmbH without
|
||||
JavaScript.
|
||||
This site is being built using lit-element (made by Google). This
|
||||
technology works with JavaScript. Subsequently this website does not
|
||||
work as intended by Lossless GmbH without JavaScript.
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
|
||||
@@ -7,7 +7,7 @@ function sealed(constructor: Function) {
|
||||
@sealed
|
||||
class TestClass {
|
||||
name = 'test';
|
||||
|
||||
|
||||
modify() {
|
||||
this.name = 'modified';
|
||||
}
|
||||
@@ -31,11 +31,14 @@ try {
|
||||
|
||||
// Test that we can't add to prototype
|
||||
try {
|
||||
(TestClass.prototype as any).newMethod = function() {};
|
||||
(TestClass.prototype as any).newMethod = function () {};
|
||||
console.log('Prototype is NOT sealed (unexpected)');
|
||||
} catch (e) {
|
||||
console.log('Prototype is sealed (expected)');
|
||||
}
|
||||
|
||||
console.log('Is TestClass sealed?', Object.isSealed(TestClass));
|
||||
console.log('Is TestClass.prototype sealed?', Object.isSealed(TestClass.prototype));
|
||||
console.log(
|
||||
'Is TestClass.prototype sealed?',
|
||||
Object.isSealed(TestClass.prototype),
|
||||
);
|
||||
|
||||
32
test/test.ts
32
test/test.ts
@@ -3,16 +3,19 @@ import * as tsbundle from '../dist_ts/index.js';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const testBundler = async (bundlerName: 'esbuild' | 'rolldown' | 'rspack', mode: 'test' | 'production') => {
|
||||
const testBundler = async (
|
||||
bundlerName: 'esbuild' | 'rolldown' | 'rspack',
|
||||
mode: 'test' | 'production',
|
||||
) => {
|
||||
const outputFile = `./dist_manual/${bundlerName}-${mode}.js`;
|
||||
const testDir = path.join(process.cwd(), 'test');
|
||||
|
||||
|
||||
// Clean up output directory
|
||||
const outputDir = path.join(testDir, 'dist_manual');
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
|
||||
// Clean up output file if exists
|
||||
const outputPath = path.join(testDir, outputFile);
|
||||
if (fs.existsSync(outputPath)) {
|
||||
@@ -20,19 +23,14 @@ const testBundler = async (bundlerName: 'esbuild' | 'rolldown' | 'rspack', mode:
|
||||
}
|
||||
|
||||
const tsbundleInstance = new tsbundle.TsBundle();
|
||||
await tsbundleInstance.build(
|
||||
testDir,
|
||||
'./ts_web/index.ts',
|
||||
outputFile,
|
||||
{
|
||||
bundler: bundlerName,
|
||||
production: mode === 'production'
|
||||
}
|
||||
);
|
||||
await tsbundleInstance.build(testDir, './ts_web/index.ts', outputFile, {
|
||||
bundler: bundlerName,
|
||||
production: mode === 'production',
|
||||
});
|
||||
|
||||
// Verify output file was created
|
||||
expect(fs.existsSync(outputPath)).toBeTrue();
|
||||
|
||||
|
||||
console.log(`✅ ${bundlerName} ${mode} mode: success`);
|
||||
};
|
||||
|
||||
@@ -69,7 +67,7 @@ tap.test('should show bundle size comparison', async () => {
|
||||
const sizes: Record<string, { test: number; production: number }> = {
|
||||
esbuild: { test: 0, production: 0 },
|
||||
rolldown: { test: 0, production: 0 },
|
||||
rspack: { test: 0, production: 0 }
|
||||
rspack: { test: 0, production: 0 },
|
||||
};
|
||||
|
||||
for (const bundler of ['esbuild', 'rolldown', 'rspack'] as const) {
|
||||
@@ -89,10 +87,12 @@ tap.test('should show bundle size comparison', async () => {
|
||||
for (const bundler of ['esbuild', 'rolldown', 'rspack'] as const) {
|
||||
const testSize = (sizes[bundler].test / 1024).toFixed(1) + ' KB';
|
||||
const prodSize = (sizes[bundler].production / 1024).toFixed(1) + ' KB';
|
||||
console.log(`│ ${bundler.padEnd(11)} │ ${testSize.padEnd(10)} │ ${prodSize.padEnd(12)} │`);
|
||||
console.log(
|
||||
`│ ${bundler.padEnd(11)} │ ${testSize.padEnd(10)} │ ${prodSize.padEnd(12)} │`,
|
||||
);
|
||||
}
|
||||
console.log('└─────────────┴────────────┴──────────────┘');
|
||||
|
||||
|
||||
// Verify all sizes are reasonable
|
||||
for (const bundler of ['esbuild', 'rolldown', 'rspack'] as const) {
|
||||
expect(sizes[bundler].test).toBeGreaterThan(0);
|
||||
|
||||
@@ -19,6 +19,4 @@ class BugReport {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
console.log(myConst);
|
||||
|
||||
@@ -19,9 +19,7 @@ export class MyElement extends LitElement {
|
||||
render() {
|
||||
return html`
|
||||
<h1>Hello, ${this.name}!</h1>
|
||||
<button @click=${this._onClick}>
|
||||
Click Count: ${this.count}
|
||||
</button>
|
||||
<button @click=${this._onClick}>Click Count: ${this.count}</button>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -34,4 +32,4 @@ export class MyElement extends LitElement {
|
||||
const element = new MyElement();
|
||||
console.log('Element created:', element);
|
||||
console.log('Element name:', element.name);
|
||||
console.log('Element count:', element.count);
|
||||
console.log('Element count:', element.count);
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@git.zone/tsbundle',
|
||||
version: '2.5.2',
|
||||
version: '2.6.0',
|
||||
description: 'a multi-bundler tool supporting esbuild, rolldown, and rspack for painless bundling of web projects'
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ export interface ICliOptions {
|
||||
commonjs?: boolean;
|
||||
skiplibcheck?: boolean;
|
||||
production?: boolean;
|
||||
bundler: 'esbuild' | 'rolldown' | 'rspack'
|
||||
bundler: 'esbuild' | 'rolldown' | 'rspack';
|
||||
}
|
||||
|
||||
export interface IEnvTransportOptions {
|
||||
cwd: string;
|
||||
from: string;
|
||||
to: string;
|
||||
mode: 'test' | 'production',
|
||||
argv: ICliOptions
|
||||
mode: 'test' | 'production';
|
||||
argv: ICliOptions;
|
||||
}
|
||||
|
||||
@@ -3,38 +3,66 @@ import * as paths from '../paths.js';
|
||||
|
||||
export class AssetsHandler {
|
||||
public defaultFromDirPath: string = plugins.path.join(paths.cwd, './assets');
|
||||
public defaultToDirPath: string = plugins.path.join(paths.cwd, './dist_serve/assets');
|
||||
public defaultToDirPath: string = plugins.path.join(
|
||||
paths.cwd,
|
||||
'./dist_serve/assets',
|
||||
);
|
||||
|
||||
public async ensureAssetsDir() {
|
||||
const assetsDirExists = await plugins.smartfile.fs.isDirectory(this.defaultFromDirPath);
|
||||
if (!assetsDirExists) {
|
||||
await plugins.smartfile.fs.ensureDir(this.defaultFromDirPath);
|
||||
const dirExists = await plugins.fs
|
||||
.directory(this.defaultFromDirPath)
|
||||
.exists();
|
||||
if (!dirExists) {
|
||||
await plugins.fs.directory(this.defaultFromDirPath).create();
|
||||
console.log(`created assets directory at ${this.defaultFromDirPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
// copies the assets directory recursively
|
||||
private async copyDirectoryRecursive(from: string, to: string) {
|
||||
const entries = await plugins.fs.directory(from).recursive().list();
|
||||
await plugins.fs.directory(to).create();
|
||||
|
||||
for (const entry of entries) {
|
||||
const fromPath = plugins.path.join(from, entry.path);
|
||||
const toPath = plugins.path.join(to, entry.path);
|
||||
|
||||
if (entry.isDirectory) {
|
||||
await plugins.fs.directory(toPath).create();
|
||||
} else {
|
||||
const toDir = plugins.path.dirname(toPath);
|
||||
await plugins.fs.directory(toDir).create();
|
||||
await plugins.fs.file(fromPath).copy(toPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copies the html
|
||||
public async processAssets(optionsArg?: {
|
||||
from?: string;
|
||||
to?: string;
|
||||
}) {
|
||||
public async processAssets(optionsArg?: { from?: string; to?: string }) {
|
||||
// lets assemble the options
|
||||
optionsArg = {
|
||||
... {
|
||||
...{
|
||||
from: this.defaultFromDirPath,
|
||||
to: this.defaultToDirPath,
|
||||
},
|
||||
...(optionsArg || {})
|
||||
...(optionsArg || {}),
|
||||
};
|
||||
await this.ensureAssetsDir();
|
||||
optionsArg.from = plugins.smartpath.transform.toAbsolute(
|
||||
optionsArg.from,
|
||||
paths.cwd,
|
||||
) as string;
|
||||
optionsArg.to = plugins.smartpath.transform.toAbsolute(
|
||||
optionsArg.to,
|
||||
paths.cwd,
|
||||
) as string;
|
||||
|
||||
// lets clean the target directory
|
||||
const toExists = await plugins.fs.directory(optionsArg.to).exists();
|
||||
if (toExists) {
|
||||
await plugins.fs.directory(optionsArg.to).delete();
|
||||
}
|
||||
await this.ensureAssetsDir()
|
||||
optionsArg.from = plugins.smartpath.transform.toAbsolute(optionsArg.from, paths.cwd) as string;
|
||||
optionsArg.to = plugins.smartpath.transform.toAbsolute(optionsArg.to, paths.cwd) as string;
|
||||
|
||||
// lets clean theh target directory
|
||||
await plugins.smartfile.fs.ensureEmptyDir(optionsArg.to);
|
||||
|
||||
plugins.smartfile.fs.copySync(optionsArg.from, optionsArg.to, {
|
||||
replaceTargetDir: true,
|
||||
});
|
||||
await this.copyDirectoryRecursive(optionsArg.from, optionsArg.to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,16 @@ export class TsBundleProcess {
|
||||
public async getAliases() {
|
||||
try {
|
||||
const aliasObject: Record<string, string> = {};
|
||||
const localTsConfig = plugins.smartfile.fs.toObjectSync(
|
||||
plugins.path.join(paths.cwd, 'tsconfig.json')
|
||||
);
|
||||
if (localTsConfig.compilerOptions && localTsConfig.compilerOptions.paths) {
|
||||
const tsconfigPath = plugins.path.join(paths.cwd, 'tsconfig.json');
|
||||
const tsconfigContent = await plugins.fs
|
||||
.file(tsconfigPath)
|
||||
.encoding('utf8')
|
||||
.read();
|
||||
const localTsConfig = JSON.parse(tsconfigContent as string);
|
||||
if (
|
||||
localTsConfig.compilerOptions &&
|
||||
localTsConfig.compilerOptions.paths
|
||||
) {
|
||||
for (const alias of Object.keys(localTsConfig.compilerOptions.paths)) {
|
||||
const aliasPath = localTsConfig.compilerOptions.paths[alias][0];
|
||||
aliasObject[alias] = aliasPath;
|
||||
@@ -75,7 +81,7 @@ export class TsBundleProcess {
|
||||
const run = async () => {
|
||||
console.log('running spawned compilation process');
|
||||
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
|
||||
process.env.transportOptions
|
||||
process.env.transportOptions,
|
||||
);
|
||||
console.log('=======> ESBUILD');
|
||||
console.log(transportOptions);
|
||||
@@ -85,16 +91,28 @@ const run = async () => {
|
||||
if (transportOptions.mode === 'test') {
|
||||
console.log('building for test:');
|
||||
tsbundleProcessInstance.buildTest(
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.from, process.cwd()),
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.to, process.cwd()),
|
||||
transportOptions.argv
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.from,
|
||||
process.cwd(),
|
||||
),
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.to,
|
||||
process.cwd(),
|
||||
),
|
||||
transportOptions.argv,
|
||||
);
|
||||
} else {
|
||||
console.log('building for production:');
|
||||
tsbundleProcessInstance.buildProduction(
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.from, process.cwd()),
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.to, process.cwd()),
|
||||
transportOptions.argv
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.from,
|
||||
process.cwd(),
|
||||
),
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.to,
|
||||
process.cwd(),
|
||||
),
|
||||
transportOptions.argv,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,6 +2,4 @@ export * from '../plugins.js';
|
||||
|
||||
import esbuild from 'esbuild';
|
||||
|
||||
export {
|
||||
esbuild
|
||||
}
|
||||
export { esbuild };
|
||||
|
||||
@@ -2,11 +2,17 @@ import * as plugins from './plugins.js';
|
||||
import * as paths from '../paths.js';
|
||||
|
||||
export class HtmlHandler {
|
||||
public defaultFromPath: string = plugins.path.join(paths.htmlDir, 'index.html');
|
||||
public defaultToPath: string = plugins.path.join(paths.distServeDir, 'index.html');
|
||||
public defaultFromPath: string = plugins.path.join(
|
||||
paths.htmlDir,
|
||||
'index.html',
|
||||
);
|
||||
public defaultToPath: string = plugins.path.join(
|
||||
paths.distServeDir,
|
||||
'index.html',
|
||||
);
|
||||
|
||||
public async checkIfExists() {
|
||||
return plugins.smartfile.fs.fileExists(this.defaultFromPath);
|
||||
return await plugins.fs.file(this.defaultFromPath).exists();
|
||||
}
|
||||
|
||||
// copies the html
|
||||
@@ -16,19 +22,28 @@ export class HtmlHandler {
|
||||
minify?: boolean;
|
||||
}) {
|
||||
optionsArg = {
|
||||
... {
|
||||
...{
|
||||
from: this.defaultFromPath,
|
||||
to: this.defaultToPath,
|
||||
minify: false,
|
||||
},
|
||||
...optionsArg
|
||||
}
|
||||
...optionsArg,
|
||||
};
|
||||
if (await this.checkIfExists()) {
|
||||
console.log(`${optionsArg.from} replaces file at ${optionsArg.to}`);
|
||||
}
|
||||
optionsArg.from = plugins.smartpath.transform.toAbsolute(optionsArg.from, paths.cwd) as string;
|
||||
optionsArg.to = plugins.smartpath.transform.toAbsolute(optionsArg.to, paths.cwd) as string;
|
||||
let fileString = plugins.smartfile.fs.toStringSync(optionsArg.from);
|
||||
optionsArg.from = plugins.smartpath.transform.toAbsolute(
|
||||
optionsArg.from,
|
||||
paths.cwd,
|
||||
) as string;
|
||||
optionsArg.to = plugins.smartpath.transform.toAbsolute(
|
||||
optionsArg.to,
|
||||
paths.cwd,
|
||||
) as string;
|
||||
let fileString = (await plugins.fs
|
||||
.file(optionsArg.from)
|
||||
.encoding('utf8')
|
||||
.read()) as string;
|
||||
if (optionsArg.minify) {
|
||||
fileString = plugins.htmlMinifier.minify(fileString, {
|
||||
minifyCSS: true,
|
||||
@@ -41,7 +56,9 @@ export class HtmlHandler {
|
||||
removeComments: true,
|
||||
});
|
||||
}
|
||||
await plugins.smartfile.memory.toFs(fileString, optionsArg.to);
|
||||
const toDir = plugins.path.dirname(optionsArg.to);
|
||||
await plugins.fs.directory(toDir).create();
|
||||
await plugins.fs.file(optionsArg.to).encoding('utf8').write(fileString);
|
||||
console.log(`html processing succeeded!`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,4 @@ export * from '../plugins.js';
|
||||
|
||||
import * as htmlMinifier from 'html-minifier';
|
||||
|
||||
export {
|
||||
htmlMinifier
|
||||
}
|
||||
export { htmlMinifier };
|
||||
|
||||
@@ -11,10 +11,16 @@ export class TsBundleProcess {
|
||||
public async getAliases() {
|
||||
try {
|
||||
const aliasObject: Record<string, string> = {};
|
||||
const localTsConfig = plugins.smartfile.fs.toObjectSync(
|
||||
plugins.path.join(paths.cwd, 'tsconfig.json')
|
||||
);
|
||||
if (localTsConfig.compilerOptions && localTsConfig.compilerOptions.paths) {
|
||||
const tsconfigPath = plugins.path.join(paths.cwd, 'tsconfig.json');
|
||||
const tsconfigContent = await plugins.fs
|
||||
.file(tsconfigPath)
|
||||
.encoding('utf8')
|
||||
.read();
|
||||
const localTsConfig = JSON.parse(tsconfigContent as string);
|
||||
if (
|
||||
localTsConfig.compilerOptions &&
|
||||
localTsConfig.compilerOptions.paths
|
||||
) {
|
||||
for (const alias of Object.keys(localTsConfig.compilerOptions.paths)) {
|
||||
const aliasPath = localTsConfig.compilerOptions.paths[alias][0];
|
||||
aliasObject[alias] = aliasPath;
|
||||
@@ -38,10 +44,10 @@ export class TsBundleProcess {
|
||||
tsconfigFilename: paths.tsconfigPath,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const outputDir = plugins.path.dirname(toArg);
|
||||
const outputFilename = plugins.path.basename(toArg);
|
||||
|
||||
|
||||
await result.write({
|
||||
dir: outputDir,
|
||||
entryFileNames: outputFilename,
|
||||
@@ -59,21 +65,18 @@ export class TsBundleProcess {
|
||||
console.log('rolldown specific:');
|
||||
console.log(`from: ${fromArg}`);
|
||||
console.log(`to: ${toArg}`);
|
||||
|
||||
|
||||
const result = await plugins.rolldown({
|
||||
input: fromArg,
|
||||
resolve: {
|
||||
alias: await this.getAliases(),
|
||||
tsconfigFilename: paths.tsconfigPath,
|
||||
},
|
||||
experimental: {
|
||||
enableComposingJsPlugins: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const outputDir = plugins.path.dirname(toArg);
|
||||
const outputFilename = plugins.path.basename(toArg);
|
||||
|
||||
|
||||
await result.write({
|
||||
dir: outputDir,
|
||||
entryFileNames: outputFilename,
|
||||
@@ -88,7 +91,7 @@ export class TsBundleProcess {
|
||||
const run = async () => {
|
||||
console.log('running spawned compilation process');
|
||||
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
|
||||
process.env.transportOptions
|
||||
process.env.transportOptions,
|
||||
);
|
||||
console.log('=======> ROLLDOWN');
|
||||
console.log(transportOptions);
|
||||
@@ -98,18 +101,30 @@ const run = async () => {
|
||||
if (transportOptions.mode === 'test') {
|
||||
console.log('building for test:');
|
||||
await tsbundleProcessInstance.buildTest(
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.from, process.cwd()),
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.to, process.cwd()),
|
||||
transportOptions.argv
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.from,
|
||||
process.cwd(),
|
||||
),
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.to,
|
||||
process.cwd(),
|
||||
),
|
||||
transportOptions.argv,
|
||||
);
|
||||
} else {
|
||||
console.log('building for production:');
|
||||
await tsbundleProcessInstance.buildProduction(
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.from, process.cwd()),
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.to, process.cwd()),
|
||||
transportOptions.argv
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.from,
|
||||
process.cwd(),
|
||||
),
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.to,
|
||||
process.cwd(),
|
||||
),
|
||||
transportOptions.argv,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
run();
|
||||
run();
|
||||
|
||||
@@ -2,4 +2,4 @@ export * from '../plugins.js';
|
||||
|
||||
import { rolldown } from 'rolldown';
|
||||
|
||||
export { rolldown }
|
||||
export { rolldown };
|
||||
|
||||
@@ -11,14 +11,23 @@ export class TsBundleProcess {
|
||||
public async getAliases() {
|
||||
try {
|
||||
const aliasObject: Record<string, string> = {};
|
||||
const localTsConfig = plugins.smartfile.fs.toObjectSync(
|
||||
plugins.path.join(paths.cwd, 'tsconfig.json')
|
||||
);
|
||||
if (localTsConfig.compilerOptions && localTsConfig.compilerOptions.paths) {
|
||||
const tsconfigPath = plugins.path.join(paths.cwd, 'tsconfig.json');
|
||||
const tsconfigContent = await plugins.fs
|
||||
.file(tsconfigPath)
|
||||
.encoding('utf8')
|
||||
.read();
|
||||
const localTsConfig = JSON.parse(tsconfigContent as string);
|
||||
if (
|
||||
localTsConfig.compilerOptions &&
|
||||
localTsConfig.compilerOptions.paths
|
||||
) {
|
||||
for (const alias of Object.keys(localTsConfig.compilerOptions.paths)) {
|
||||
const aliasPath = localTsConfig.compilerOptions.paths[alias][0];
|
||||
// Convert TypeScript path to absolute path for rspack
|
||||
aliasObject[alias.replace('/*', '')] = plugins.path.resolve(paths.cwd, aliasPath.replace('/*', ''));
|
||||
aliasObject[alias.replace('/*', '')] = plugins.path.resolve(
|
||||
paths.cwd,
|
||||
aliasPath.replace('/*', ''),
|
||||
);
|
||||
}
|
||||
}
|
||||
return aliasObject;
|
||||
@@ -34,7 +43,7 @@ export class TsBundleProcess {
|
||||
const aliases = await this.getAliases();
|
||||
const outputDir = plugins.path.dirname(toArg);
|
||||
const outputFilename = plugins.path.basename(toArg);
|
||||
|
||||
|
||||
const config = {
|
||||
mode: 'development' as const,
|
||||
entry: {
|
||||
@@ -96,13 +105,15 @@ export class TsBundleProcess {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false,
|
||||
}));
|
||||
console.log(
|
||||
stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false,
|
||||
}),
|
||||
);
|
||||
|
||||
resolve(undefined);
|
||||
});
|
||||
@@ -116,11 +127,11 @@ export class TsBundleProcess {
|
||||
console.log('rspack specific:');
|
||||
console.log(`from: ${fromArg}`);
|
||||
console.log(`to: ${toArg}`);
|
||||
|
||||
|
||||
const aliases = await this.getAliases();
|
||||
const outputDir = plugins.path.dirname(toArg);
|
||||
const outputFilename = plugins.path.basename(toArg);
|
||||
|
||||
|
||||
const config = {
|
||||
mode: 'production' as const,
|
||||
entry: {
|
||||
@@ -192,13 +203,15 @@ export class TsBundleProcess {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false,
|
||||
}));
|
||||
console.log(
|
||||
stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false,
|
||||
chunks: false,
|
||||
chunkModules: false,
|
||||
}),
|
||||
);
|
||||
|
||||
resolve(undefined);
|
||||
});
|
||||
@@ -209,7 +222,7 @@ export class TsBundleProcess {
|
||||
const run = async () => {
|
||||
console.log('running spawned compilation process');
|
||||
const transportOptions: interfaces.IEnvTransportOptions = JSON.parse(
|
||||
process.env.transportOptions
|
||||
process.env.transportOptions,
|
||||
);
|
||||
console.log('=======> RSPACK');
|
||||
console.log(transportOptions);
|
||||
@@ -219,18 +232,30 @@ const run = async () => {
|
||||
if (transportOptions.mode === 'test') {
|
||||
console.log('building for test:');
|
||||
await tsbundleProcessInstance.buildTest(
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.from, process.cwd()),
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.to, process.cwd()),
|
||||
transportOptions.argv
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.from,
|
||||
process.cwd(),
|
||||
),
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.to,
|
||||
process.cwd(),
|
||||
),
|
||||
transportOptions.argv,
|
||||
);
|
||||
} else {
|
||||
console.log('building for production:');
|
||||
await tsbundleProcessInstance.buildProduction(
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.from, process.cwd()),
|
||||
plugins.smartpath.transform.makeAbsolute(transportOptions.to, process.cwd()),
|
||||
transportOptions.argv
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.from,
|
||||
process.cwd(),
|
||||
),
|
||||
plugins.smartpath.transform.makeAbsolute(
|
||||
transportOptions.to,
|
||||
process.cwd(),
|
||||
),
|
||||
transportOptions.argv,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
run();
|
||||
run();
|
||||
|
||||
@@ -2,4 +2,4 @@ export * from '../plugins.js';
|
||||
|
||||
import { rspack } from '@rspack/core';
|
||||
|
||||
export { rspack }
|
||||
export { rspack };
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as plugins from './plugins.js';
|
||||
export const cwd = process.cwd();
|
||||
export const packageDir = plugins.path.join(
|
||||
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
||||
'../'
|
||||
'../',
|
||||
);
|
||||
export const htmlDir = plugins.path.join(cwd, './html');
|
||||
export const distServeDir = plugins.path.join(cwd, './dist_serve');
|
||||
|
||||
@@ -5,7 +5,7 @@ export { path };
|
||||
|
||||
// pushrocks scope
|
||||
import * as smartcli from '@push.rocks/smartcli';
|
||||
import * as smartfile from '@push.rocks/smartfile';
|
||||
import * as smartfs from '@push.rocks/smartfs';
|
||||
import * as smartlog from '@push.rocks/smartlog';
|
||||
import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local';
|
||||
import * as smartpath from '@push.rocks/smartpath';
|
||||
@@ -14,10 +14,13 @@ import * as smartspawn from '@push.rocks/smartspawn';
|
||||
|
||||
export {
|
||||
smartcli,
|
||||
smartfile,
|
||||
smartfs,
|
||||
smartlog,
|
||||
smartlogDestinationLocal,
|
||||
smartpath,
|
||||
smartpromise,
|
||||
smartspawn,
|
||||
};
|
||||
|
||||
// Create a shared SmartFs instance using Node provider
|
||||
export const fs = new smartfs.SmartFs(new smartfs.SmartFsProviderNode());
|
||||
|
||||
@@ -3,12 +3,11 @@ import * as interfaces from './interfaces/index.js';
|
||||
import { logger } from './tsbundle.logging.js';
|
||||
|
||||
export class TsBundle {
|
||||
|
||||
public async build(
|
||||
cwdArg: string,
|
||||
fromArg: string = './ts_web/index.ts',
|
||||
toArg: string = './dist_bundle/bundle.js',
|
||||
argvArg: interfaces.ICliOptions
|
||||
argvArg: interfaces.ICliOptions,
|
||||
) {
|
||||
const done = plugins.smartpromise.defer();
|
||||
const getBundlerPath = () => {
|
||||
@@ -21,20 +20,20 @@ export class TsBundle {
|
||||
default:
|
||||
return './mod_esbuild/index.child.js';
|
||||
}
|
||||
}
|
||||
};
|
||||
const transportOptions: interfaces.IEnvTransportOptions = {
|
||||
cwd: cwdArg,
|
||||
from: fromArg,
|
||||
to: toArg,
|
||||
mode: argvArg && argvArg.production ? 'production' : 'test',
|
||||
argv: {
|
||||
...argvArg
|
||||
}
|
||||
}
|
||||
argv: {
|
||||
...argvArg,
|
||||
},
|
||||
};
|
||||
const threadsimple = new plugins.smartspawn.ThreadSimple(
|
||||
plugins.path.join(
|
||||
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
||||
getBundlerPath()
|
||||
getBundlerPath(),
|
||||
),
|
||||
[],
|
||||
{
|
||||
@@ -42,7 +41,7 @@ export class TsBundle {
|
||||
...process.env,
|
||||
transportOptions: JSON.stringify(transportOptions),
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
const childProcess = await threadsimple.start();
|
||||
childProcess.on('exit', (status) => {
|
||||
|
||||
@@ -18,7 +18,7 @@ export const runCli = async () => {
|
||||
process.cwd(),
|
||||
'./ts_web/index.ts',
|
||||
'./dist_bundle/bundle.js',
|
||||
argvArg
|
||||
argvArg,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ export const runCli = async () => {
|
||||
process.cwd(),
|
||||
'./ts/index.ts',
|
||||
'./dist_bundle/bundle.js',
|
||||
argvArg
|
||||
argvArg,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -42,9 +42,18 @@ export const runCli = async () => {
|
||||
process.cwd(),
|
||||
'./ts_web/index.ts',
|
||||
'./dist_serve/bundle.js',
|
||||
argvArg
|
||||
argvArg,
|
||||
);
|
||||
const htmlFiles = await plugins.smartfile.fs.listFiles('./html', /\.html/);
|
||||
const htmlDirPath = plugins.path.join(process.cwd(), './html');
|
||||
let htmlFiles: string[] = [];
|
||||
const htmlDirExists = await plugins.fs.directory(htmlDirPath).exists();
|
||||
if (htmlDirExists) {
|
||||
const entries = await plugins.fs
|
||||
.directory(htmlDirPath)
|
||||
.filter(/\.html$/)
|
||||
.list();
|
||||
htmlFiles = entries.map((entry) => entry.path);
|
||||
}
|
||||
for (const htmlFile of htmlFiles) {
|
||||
await htmlHandler.processHtml({
|
||||
from: `./html/${htmlFile}`,
|
||||
|
||||
@@ -12,4 +12,6 @@ export const logger = new plugins.smartlog.Smartlog({
|
||||
minimumLogLevel: 'silly',
|
||||
});
|
||||
|
||||
logger.addLogDestination(new plugins.smartlogDestinationLocal.DestinationLocal());
|
||||
logger.addLogDestination(
|
||||
new plugins.smartlogDestinationLocal.DestinationLocal(),
|
||||
);
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"verbatimModuleSyntax": true
|
||||
"verbatimModuleSyntax": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {}
|
||||
},
|
||||
"exclude": [
|
||||
"dist_*/**/*.d.ts"
|
||||
]
|
||||
"exclude": ["dist_*/**/*.d.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user