bimba-cli 0.5.19 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +15 -5
- package/package.json +1 -1
- package/plugin.js +10 -6
- package/serve.js +6 -5
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
3
|
import { parseArgs } from "util";
|
|
4
|
-
import { imbaPlugin, stats, cache } from './plugin.js'
|
|
4
|
+
import { imbaPlugin, stats, cache, setTarget } from './plugin.js'
|
|
5
5
|
import {theme} from './utils.js';
|
|
6
6
|
import fs from 'fs'
|
|
7
7
|
import path from 'path';
|
|
@@ -23,6 +23,7 @@ try {
|
|
|
23
23
|
minify: { type: 'boolean' },
|
|
24
24
|
splitting: { type: 'boolean' },
|
|
25
25
|
target: { type: 'string' },
|
|
26
|
+
external: { type: 'string', multiple: true },
|
|
26
27
|
sourcemap: { type: 'string' },
|
|
27
28
|
serve: { type: 'boolean' },
|
|
28
29
|
port: { type: 'string' },
|
|
@@ -63,7 +64,8 @@ if(flags.help) {
|
|
|
63
64
|
console.log(" "+theme.flags('--outdir <folder>')+" Compile imba files to the specified folder");
|
|
64
65
|
console.log(" "+theme.flags('--minify')+" Minify compiled .js files");
|
|
65
66
|
console.log(" "+theme.flags('--sourcemap <inline|external|none>')+" How should sourcemap files be included in the .js");
|
|
66
|
-
console.log(" "+theme.flags('--
|
|
67
|
+
console.log(" "+theme.flags('--target <browser|node>')+" Target platform for both Imba compiler and Bun bundler");
|
|
68
|
+
console.log(" "+theme.flags('--external <package>')+" Exclude package from bundle (repeatable, e.g. --external ws --external node-pty)");
|
|
67
69
|
console.log(" "+theme.flags('--watch')+" Watch for changes in the entrypoint folder");
|
|
68
70
|
console.log(" "+theme.flags('--clearcache')+" Clear cache on exit, works only when in watch mode");
|
|
69
71
|
console.log("");
|
|
@@ -137,17 +139,25 @@ async function bundle() {
|
|
|
137
139
|
console.log(theme.folder("──────────────────────────────────────────────────────────────────────"));
|
|
138
140
|
console.log(theme.start(`Start building the Imba entrypoint: ${theme.filedir(entrypoint)}`));
|
|
139
141
|
|
|
142
|
+
// set Imba compiler platform based on target
|
|
143
|
+
const buildTarget = flags.target || 'browser';
|
|
144
|
+
setTarget(buildTarget);
|
|
145
|
+
|
|
140
146
|
let result = undefined
|
|
141
147
|
try {
|
|
142
|
-
|
|
148
|
+
const buildOpts = {
|
|
143
149
|
entrypoints: [entrypoint],
|
|
144
150
|
outdir: flags.outdir,
|
|
145
|
-
target:
|
|
151
|
+
target: buildTarget,
|
|
146
152
|
sourcemap: flags.sourcemap || 'none',
|
|
147
153
|
minify: true,
|
|
148
154
|
splitting: flags.splitting || false,
|
|
149
155
|
plugins: [imbaPlugin]
|
|
150
|
-
}
|
|
156
|
+
};
|
|
157
|
+
if (flags.external?.length) {
|
|
158
|
+
buildOpts.external = flags.external;
|
|
159
|
+
}
|
|
160
|
+
result = await Bun.build(buildOpts);
|
|
151
161
|
|
|
152
162
|
if(stats.failed)
|
|
153
163
|
console.log(theme.start(theme.failure(" Failure ") + theme.filename(` Imba compiler failed to proceed ${stats.failed} file${stats.failed > 1 ? 's' : ''}`)));
|
package/package.json
CHANGED
package/plugin.js
CHANGED
|
@@ -18,6 +18,11 @@ export let stats = {
|
|
|
18
18
|
errors: 0,
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
// Target platform for the Imba compiler: 'browser' or 'node'
|
|
22
|
+
// Set via setTarget() from the CLI before building
|
|
23
|
+
export let target = 'browser';
|
|
24
|
+
export function setTarget(t) { target = t; }
|
|
25
|
+
|
|
21
26
|
export const imbaPlugin = {
|
|
22
27
|
name: "imba",
|
|
23
28
|
async setup(build) {
|
|
@@ -28,13 +33,11 @@ export const imbaPlugin = {
|
|
|
28
33
|
const f = dir.parse(path)
|
|
29
34
|
let contents = '';
|
|
30
35
|
|
|
31
|
-
// return the cached version if exists
|
|
32
|
-
const cached = dir.join(cache, Bun.hash(path) + '_' + fs.statSync(path).mtimeMs + '.js');
|
|
36
|
+
// return the cached version if exists (include target in hash to avoid cross-platform cache hits)
|
|
37
|
+
const cached = dir.join(cache, Bun.hash(path + ':' + target) + '_' + fs.statSync(path).mtimeMs + '.js');
|
|
33
38
|
if (fs.existsSync(cached)) {
|
|
34
39
|
stats.bundled++;
|
|
35
40
|
stats.cached++;
|
|
36
|
-
//console.log(theme.action("cached: ") + theme.folder(f.dir + '/') + theme.filename(f.base) + " - " + theme.success("ok"));
|
|
37
|
-
//console.log(theme.action("compiling: ") + theme.folder(dir.join(f.dir,'/')) + theme.filename(f.base) + " - " + theme.success("from cache"));
|
|
38
41
|
return {
|
|
39
42
|
contents: await Bun.file(cached).text(),
|
|
40
43
|
loader: "js",
|
|
@@ -42,14 +45,15 @@ export const imbaPlugin = {
|
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
// clear previous cached version
|
|
45
|
-
const glob = new Glob(Bun.hash(path) + '_' + "*.js");
|
|
48
|
+
const glob = new Glob(Bun.hash(path + ':' + target) + '_' + "*.js");
|
|
46
49
|
for await (const file of glob.scan(cache)) if (fs.existsSync(dir.join(cache, file))) unlink(dir.join(cache, file));
|
|
47
50
|
|
|
48
51
|
// if no cached version read and compile it with the imba compiler
|
|
49
52
|
const file = await Bun.file(path).text();
|
|
53
|
+
const platform = target === 'node' || target === 'bun' ? 'node' : 'browser';
|
|
50
54
|
const out = compiler.compile(file, {
|
|
51
55
|
sourcePath: path,
|
|
52
|
-
platform:
|
|
56
|
+
platform: platform,
|
|
53
57
|
comments: false
|
|
54
58
|
})
|
|
55
59
|
|
package/serve.js
CHANGED
|
@@ -42,7 +42,9 @@ const hmrClient = `
|
|
|
42
42
|
if (target) {
|
|
43
43
|
// Save old _ns_ before _patchClass overwrites prototype descriptors
|
|
44
44
|
if (target.prototype._ns_) _oldNs.set(name, target.prototype._ns_);
|
|
45
|
-
|
|
45
|
+
// When CSS-only (stable slots), skip patching render/methods —
|
|
46
|
+
// new render() has new Symbol closures that would cause duplicate DOM.
|
|
47
|
+
if (!_stableSlots) _patchClass(target, cls);
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
};
|
|
@@ -51,13 +53,12 @@ const hmrClient = `
|
|
|
51
53
|
|
|
52
54
|
// Copy all own property descriptors from source to target, skipping keys
|
|
53
55
|
// that match the shouldSkip predicate. Handles both string and symbol keys.
|
|
54
|
-
function _copyDescriptors(target, source, shouldSkip
|
|
56
|
+
function _copyDescriptors(target, source, shouldSkip) {
|
|
55
57
|
for (const key of Object.getOwnPropertyNames(source)) {
|
|
56
58
|
if (shouldSkip(key)) continue;
|
|
57
59
|
const d = Object.getOwnPropertyDescriptor(source, key);
|
|
58
60
|
if (d) try { Object.defineProperty(target, key, d); } catch(_) {}
|
|
59
61
|
}
|
|
60
|
-
if (skipSymbols) return; // CSS-only: keep existing Symbol-keyed render caches
|
|
61
62
|
for (const key of Object.getOwnPropertySymbols(source)) {
|
|
62
63
|
const d = Object.getOwnPropertyDescriptor(source, key);
|
|
63
64
|
if (d) try { Object.defineProperty(target, key, d); } catch(_) {}
|
|
@@ -65,8 +66,8 @@ const hmrClient = `
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
function _patchClass(target, source) {
|
|
68
|
-
_copyDescriptors(target.prototype, source.prototype, k => k === 'constructor'
|
|
69
|
-
_copyDescriptors(target, source, k => _skipStatics.has(k)
|
|
69
|
+
_copyDescriptors(target.prototype, source.prototype, k => k === 'constructor');
|
|
70
|
+
_copyDescriptors(target, source, k => _skipStatics.has(k));
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
// ── HMR update handler ─────────────────────────────────────────────────────
|