@hyperfrontend/builder 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/_dependencies/@hyperfrontend/project-scope/core/fs/index.cjs.js +10 -3
- package/_dependencies/@hyperfrontend/project-scope/core/fs/index.esm.js +10 -3
- package/_dependencies/@hyperfrontend/project-scope/core/index.cjs.js +16 -6
- package/_dependencies/@hyperfrontend/project-scope/core/index.esm.js +16 -6
- package/_dependencies/@hyperfrontend/project-scope/core/path/index.cjs.js +4 -5
- package/_dependencies/@hyperfrontend/project-scope/core/path/index.esm.js +5 -4
- package/_dependencies/@hyperfrontend/project-scope/project/root/index.cjs.js +5 -1
- package/_dependencies/@hyperfrontend/project-scope/project/root/index.esm.js +5 -1
- package/bin/hf-build.js +110 -82
- package/bin/hf-build.linux-x64 +0 -0
- package/bin/index.cjs.js +82 -36
- package/bin/index.esm.js +82 -36
- package/bin/script/index.cjs.js +91 -45
- package/bin/script/index.esm.js +81 -35
- package/bundle/declarations/dts-per-entry.d.ts.map +1 -1
- package/bundle/declarations/dts-pre-pass.d.ts.map +1 -1
- package/bundle/declarations/index.cjs.js +118 -72
- package/bundle/declarations/index.esm.js +83 -37
- package/bundle/dependencies/index.cjs.js +95 -49
- package/bundle/dependencies/index.d.ts +13 -24
- package/bundle/dependencies/index.esm.js +79 -33
- package/bundle/dependencies/pre-pass.d.ts +13 -24
- package/bundle/dependencies/pre-pass.d.ts.map +1 -1
- package/bundle/index.cjs.js +203 -175
- package/bundle/index.esm.js +107 -79
- package/bundle/rollup/dispatch.d.ts +12 -14
- package/bundle/rollup/dispatch.d.ts.map +1 -1
- package/bundle/rollup/index.cjs.js +75 -29
- package/bundle/rollup/index.d.ts +14 -16
- package/bundle/rollup/index.esm.js +76 -30
- package/bundle/worker-locator.d.ts +47 -0
- package/bundle/worker-locator.d.ts.map +1 -0
- package/index.cjs.js +112 -84
- package/index.esm.js +113 -85
- package/package.json +31 -3
|
@@ -4,7 +4,7 @@ import { join as join$2, exists, relativePath, removeDirectory, readFileContent,
|
|
|
4
4
|
import { from } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js';
|
|
5
5
|
import { createSet } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
|
|
6
6
|
import { createRequire } from 'node:module';
|
|
7
|
-
import { join as join$1, isAbsolute, resolve
|
|
7
|
+
import { join as join$1, dirname, isAbsolute, resolve } from 'node:path';
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
9
|
import { existsSync, rmSync, mkdtempSync, readFileSync, cpSync, statSync, unlinkSync } from 'node:fs';
|
|
10
10
|
import { tmpdir } from 'node:os';
|
|
@@ -23,6 +23,70 @@ import { collectChunkSpecifiers, hasDynamicSpecifier } from '../../_shared/bundl
|
|
|
23
23
|
import { entryDirOf } from '../../_shared/bundle/fs/entry-dir/index.esm.js';
|
|
24
24
|
import { isUnderDir } from '../../_shared/bundle/fs/under-dir/index.esm.js';
|
|
25
25
|
|
|
26
|
+
const SWC_NODE_REGISTER = '@swc-node/register';
|
|
27
|
+
const probeDir = (dir, offset) => {
|
|
28
|
+
const compiled = join$1(dir, ...offset, 'index.cjs.js');
|
|
29
|
+
if (existsSync(compiled))
|
|
30
|
+
return { path: compiled, execArgv: [] };
|
|
31
|
+
const source = join$1(dir, ...offset, 'index.ts');
|
|
32
|
+
if (existsSync(source))
|
|
33
|
+
return { path: source, execArgv: ['--require', SWC_NODE_REGISTER] };
|
|
34
|
+
return undefined;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Directory of the currently-executing builder module, read from `__dirname`.
|
|
38
|
+
* It is present in the shipped CommonJS build, in the `@swc-node/register` source
|
|
39
|
+
* bootstrap, and under the test runner, so callers get their own on-disk location
|
|
40
|
+
* and can find the worker beside them however the builder was packaged.
|
|
41
|
+
*
|
|
42
|
+
* @returns Absolute directory path of the running module.
|
|
43
|
+
*
|
|
44
|
+
* @example Anchoring a lookup beside the running builder
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const invocation = ascendForWorker(['bundle', 'rollup', 'worker'], currentModuleDir())
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
const currentModuleDir = () => {
|
|
50
|
+
/* istanbul ignore if -- @preserve the ESM build has no __dirname; the shipped CommonJS build and the test runner always define it, so this guard is unreachable under test */
|
|
51
|
+
if (typeof __dirname === 'undefined') {
|
|
52
|
+
throw createError('@hyperfrontend/builder self-location requires the CommonJS build; drive build() from the CommonJS entry point');
|
|
53
|
+
}
|
|
54
|
+
return __dirname;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Locate a builder worker entry by ascending from a start directory toward the
|
|
58
|
+
* filesystem root, returning the first ancestor at which the worker exists at the
|
|
59
|
+
* given in-package offset. The compiled `index.cjs.js` is preferred; an `index.ts`
|
|
60
|
+
* sibling (source-mode bootstrap) resolves with the swc loader attached.
|
|
61
|
+
*
|
|
62
|
+
* The worker ships inside the builder's own package, so resolving relative to the
|
|
63
|
+
* running module finds it wherever the package lives — built dist, an installed
|
|
64
|
+
* `node_modules` copy, or melded into a host bundle under `_dependencies/`.
|
|
65
|
+
*
|
|
66
|
+
* @param offset - In-package path segments to the worker directory (e.g. `['bundle', 'rollup', 'worker']`).
|
|
67
|
+
* @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
|
|
68
|
+
* @returns The resolved worker invocation, or `undefined` if no worker exists at the offset under any ancestor.
|
|
69
|
+
*
|
|
70
|
+
* @example Resolving the rollup worker from the running module
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const invocation = ascendForWorker(['bundle', 'rollup', 'worker'])
|
|
73
|
+
* if (!invocation) throw new Error('builder rollup worker not found beside the builder module')
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
const ascendForWorker = (offset, startDir = currentModuleDir()) => {
|
|
77
|
+
let dir = startDir;
|
|
78
|
+
let parent = dirname(dir);
|
|
79
|
+
// how: probe each level then step up; the final probe covers the filesystem root, where parent === dir
|
|
80
|
+
while (parent !== dir) {
|
|
81
|
+
const found = probeDir(dir, offset);
|
|
82
|
+
if (found)
|
|
83
|
+
return found;
|
|
84
|
+
dir = parent;
|
|
85
|
+
parent = dirname(dir);
|
|
86
|
+
}
|
|
87
|
+
return probeDir(dir, offset);
|
|
88
|
+
};
|
|
89
|
+
|
|
26
90
|
const log$4 = logger.channel('builder:bundle:dependencies:pre-pass');
|
|
27
91
|
const REPORT_DIR_PREFIX = 'hf-builder-prepass-';
|
|
28
92
|
const createReportDir = () => mkdtempSync(join$2(tmpdir(), REPORT_DIR_PREFIX));
|
|
@@ -59,43 +123,25 @@ const readReport = (reportPath, job) => {
|
|
|
59
123
|
const data = parse(readFileSync(reportPath, 'utf8'));
|
|
60
124
|
return { job, outputSize: data.outputSize, endHeapMB: data.endHeapMB, endRssMB: data.endRssMB, durationMs: data.durationMs };
|
|
61
125
|
};
|
|
62
|
-
const SWC_NODE_REGISTER = '@swc-node/register';
|
|
63
|
-
const swcNodeAvailable = (workspaceRoot) => existsSync(join$2(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
|
|
64
126
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* the
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* @
|
|
77
|
-
*
|
|
78
|
-
* @example Locating the worker for an in-workspace consumer
|
|
127
|
+
* Resolves the dependency pre-pass worker by self-locating it beside the running
|
|
128
|
+
* builder module: ascends from the module's own directory to the builder package
|
|
129
|
+
* root and returns the worker at `bundle/dependencies/worker`. This works whether
|
|
130
|
+
* the builder runs from its built dist, an installed `node_modules` copy, or
|
|
131
|
+
* melded into a host bundle under `_dependencies/`. The compiled `index.cjs.js`
|
|
132
|
+
* is preferred; an `index.ts` sibling resolves with the `@swc-node/register`
|
|
133
|
+
* loader for source-mode bootstrap.
|
|
134
|
+
*
|
|
135
|
+
* @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
|
|
136
|
+
* @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
|
|
137
|
+
*
|
|
138
|
+
* @example Locating the worker beside the builder
|
|
79
139
|
* ```typescript
|
|
80
|
-
* const invocation = resolveDefaultWorkerPath(
|
|
140
|
+
* const invocation = resolveDefaultWorkerPath()
|
|
81
141
|
* if (!invocation) throw new Error('builder worker artifact not found')
|
|
82
142
|
* ```
|
|
83
143
|
*/
|
|
84
|
-
const resolveDefaultWorkerPath = (
|
|
85
|
-
const distCandidates = [
|
|
86
|
-
join$2(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
|
|
87
|
-
join$2(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
|
|
88
|
-
];
|
|
89
|
-
for (const path of distCandidates) {
|
|
90
|
-
if (existsSync(path))
|
|
91
|
-
return { path, execArgv: [] };
|
|
92
|
-
}
|
|
93
|
-
const sourcePath = join$2(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'dependencies', 'worker', 'index.ts');
|
|
94
|
-
if (existsSync(sourcePath) && swcNodeAvailable(workspaceRoot)) {
|
|
95
|
-
return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER] };
|
|
96
|
-
}
|
|
97
|
-
return undefined;
|
|
98
|
-
};
|
|
144
|
+
const resolveDefaultWorkerPath = (startDir) => ascendForWorker(['bundle', 'dependencies', 'worker'], startDir);
|
|
99
145
|
/**
|
|
100
146
|
* Sequentially runs the supplied pre-pass jobs by forking a fresh Node child
|
|
101
147
|
* per invocation. Strict sequential execution is mandatory — concurrent
|
|
@@ -401,9 +447,9 @@ const buildJobs$1 = (entries, context) => {
|
|
|
401
447
|
const runDtsPerEntry = async (context, monitor) => {
|
|
402
448
|
if (context.bundledDeps.length === 0 && context.workspaceBundledDeps.length === 0)
|
|
403
449
|
return;
|
|
404
|
-
const invocation = resolveDefaultWorkerPath(
|
|
450
|
+
const invocation = resolveDefaultWorkerPath();
|
|
405
451
|
if (!invocation) {
|
|
406
|
-
throw createError('bundleAllDeps is enabled but the pre-pass worker
|
|
452
|
+
throw createError('bundleAllDeps is enabled but the pre-pass worker could not be located beside the builder module for the per-entry d.ts pass.');
|
|
407
453
|
}
|
|
408
454
|
const jobs = buildJobs$1(context.entryPointDiscovery.entryPoints, context);
|
|
409
455
|
if (jobs.length === 0) {
|
|
@@ -585,9 +631,9 @@ const buildWorkspaceJobs = (context, npmDeps) => {
|
|
|
585
631
|
const runDtsPrePass = async (context, monitor) => {
|
|
586
632
|
if (context.bundledDeps.length === 0 && context.workspaceBundledDeps.length === 0)
|
|
587
633
|
return;
|
|
588
|
-
const invocation = resolveDefaultWorkerPath(
|
|
634
|
+
const invocation = resolveDefaultWorkerPath();
|
|
589
635
|
if (!invocation) {
|
|
590
|
-
throw createError('bundleAllDeps is enabled but the pre-pass worker
|
|
636
|
+
throw createError('bundleAllDeps is enabled but the pre-pass worker could not be located beside the builder module for the d.ts pre-pass.');
|
|
591
637
|
}
|
|
592
638
|
const npmJobs = buildJobs(context.bundledDeps, context);
|
|
593
639
|
const workspaceJobs = buildWorkspaceJobs(context, context.bundledDeps);
|
|
@@ -5,11 +5,11 @@ const node_path = require('node:path');
|
|
|
5
5
|
const node_child_process = require('node:child_process');
|
|
6
6
|
const node_fs = require('node:fs');
|
|
7
7
|
const node_os = require('node:os');
|
|
8
|
-
const index_cjs_js
|
|
9
|
-
const index_cjs_js$
|
|
10
|
-
const index_cjs_js$
|
|
11
|
-
const index_cjs_js = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
|
|
12
|
-
const index_cjs_js$
|
|
8
|
+
const index_cjs_js = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
|
|
9
|
+
const index_cjs_js$4 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.cjs.js');
|
|
10
|
+
const index_cjs_js$3 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.cjs.js');
|
|
11
|
+
const index_cjs_js$1 = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
|
|
12
|
+
const index_cjs_js$2 = require('../../_dependencies/@hyperfrontend/project-scope/core/index.cjs.js');
|
|
13
13
|
const index_cjs_js$7 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.cjs.js');
|
|
14
14
|
const index_cjs_js$6 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.cjs.js');
|
|
15
15
|
const index_cjs_js$5 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js');
|
|
@@ -31,13 +31,77 @@ const json__default = /*#__PURE__*/_interopDefaultCompat(json);
|
|
|
31
31
|
const nodeResolve__default = /*#__PURE__*/_interopDefaultCompat(nodeResolve);
|
|
32
32
|
const typescript__default = /*#__PURE__*/_interopDefaultCompat(typescript);
|
|
33
33
|
|
|
34
|
-
const
|
|
34
|
+
const SWC_NODE_REGISTER = '@swc-node/register';
|
|
35
|
+
const probeDir = (dir, offset) => {
|
|
36
|
+
const compiled = node_path.join(dir, ...offset, 'index.cjs.js');
|
|
37
|
+
if (node_fs.existsSync(compiled))
|
|
38
|
+
return { path: compiled, execArgv: [] };
|
|
39
|
+
const source = node_path.join(dir, ...offset, 'index.ts');
|
|
40
|
+
if (node_fs.existsSync(source))
|
|
41
|
+
return { path: source, execArgv: ['--require', SWC_NODE_REGISTER] };
|
|
42
|
+
return undefined;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Directory of the currently-executing builder module, read from `__dirname`.
|
|
46
|
+
* It is present in the shipped CommonJS build, in the `@swc-node/register` source
|
|
47
|
+
* bootstrap, and under the test runner, so callers get their own on-disk location
|
|
48
|
+
* and can find the worker beside them however the builder was packaged.
|
|
49
|
+
*
|
|
50
|
+
* @returns Absolute directory path of the running module.
|
|
51
|
+
*
|
|
52
|
+
* @example Anchoring a lookup beside the running builder
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const invocation = ascendForWorker(['bundle', 'rollup', 'worker'], currentModuleDir())
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
const currentModuleDir = () => {
|
|
58
|
+
/* istanbul ignore if -- @preserve the ESM build has no __dirname; the shipped CommonJS build and the test runner always define it, so this guard is unreachable under test */
|
|
59
|
+
if (typeof __dirname === 'undefined') {
|
|
60
|
+
throw index_cjs_js.createError('@hyperfrontend/builder self-location requires the CommonJS build; drive build() from the CommonJS entry point');
|
|
61
|
+
}
|
|
62
|
+
return __dirname;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Locate a builder worker entry by ascending from a start directory toward the
|
|
66
|
+
* filesystem root, returning the first ancestor at which the worker exists at the
|
|
67
|
+
* given in-package offset. The compiled `index.cjs.js` is preferred; an `index.ts`
|
|
68
|
+
* sibling (source-mode bootstrap) resolves with the swc loader attached.
|
|
69
|
+
*
|
|
70
|
+
* The worker ships inside the builder's own package, so resolving relative to the
|
|
71
|
+
* running module finds it wherever the package lives — built dist, an installed
|
|
72
|
+
* `node_modules` copy, or melded into a host bundle under `_dependencies/`.
|
|
73
|
+
*
|
|
74
|
+
* @param offset - In-package path segments to the worker directory (e.g. `['bundle', 'rollup', 'worker']`).
|
|
75
|
+
* @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
|
|
76
|
+
* @returns The resolved worker invocation, or `undefined` if no worker exists at the offset under any ancestor.
|
|
77
|
+
*
|
|
78
|
+
* @example Resolving the rollup worker from the running module
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const invocation = ascendForWorker(['bundle', 'rollup', 'worker'])
|
|
81
|
+
* if (!invocation) throw new Error('builder rollup worker not found beside the builder module')
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
const ascendForWorker = (offset, startDir = currentModuleDir()) => {
|
|
85
|
+
let dir = startDir;
|
|
86
|
+
let parent = node_path.dirname(dir);
|
|
87
|
+
// how: probe each level then step up; the final probe covers the filesystem root, where parent === dir
|
|
88
|
+
while (parent !== dir) {
|
|
89
|
+
const found = probeDir(dir, offset);
|
|
90
|
+
if (found)
|
|
91
|
+
return found;
|
|
92
|
+
dir = parent;
|
|
93
|
+
parent = node_path.dirname(dir);
|
|
94
|
+
}
|
|
95
|
+
return probeDir(dir, offset);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const log = index_cjs_js$1.logger.channel('builder:bundle:dependencies:pre-pass');
|
|
35
99
|
const REPORT_DIR_PREFIX = 'hf-builder-prepass-';
|
|
36
|
-
const createReportDir = () => node_fs.mkdtempSync(index_cjs_js$
|
|
37
|
-
const reportPathFor = (reportDir, job, index) => index_cjs_js$
|
|
38
|
-
const runOne = (job, reportPath, options) => index_cjs_js$
|
|
100
|
+
const createReportDir = () => node_fs.mkdtempSync(index_cjs_js$2.join(node_os.tmpdir(), REPORT_DIR_PREFIX));
|
|
101
|
+
const reportPathFor = (reportDir, job, index) => index_cjs_js$2.join(reportDir, `${index}-${job.dep.replace(/\//g, '__')}-${job.kind}-${job.format}.json`);
|
|
102
|
+
const runOne = (job, reportPath, options) => index_cjs_js$3.createPromise((resolve, reject) => {
|
|
39
103
|
const execPath = options.execPath ?? process.execPath;
|
|
40
|
-
const argv = [...(options.execArgv ?? []), options.workerPath, index_cjs_js$
|
|
104
|
+
const argv = [...(options.execArgv ?? []), options.workerPath, index_cjs_js$4.stringify({ ...job, reportPath })];
|
|
41
105
|
const child = node_child_process.spawn(execPath, argv, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
42
106
|
let capturedStderr = '';
|
|
43
107
|
child.stdout?.on('data', (chunk) => {
|
|
@@ -49,12 +113,12 @@ const runOne = (job, reportPath, options) => index_cjs_js$2.createPromise((resol
|
|
|
49
113
|
process.stderr.write(text);
|
|
50
114
|
});
|
|
51
115
|
child.on('error', (error) => {
|
|
52
|
-
reject(index_cjs_js
|
|
116
|
+
reject(index_cjs_js.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) failed to spawn: ${error.message}`));
|
|
53
117
|
});
|
|
54
118
|
child.on('exit', (code) => {
|
|
55
119
|
if (code !== 0) {
|
|
56
120
|
const tail = capturedStderr.trim().split('\n').slice(-10).join('\n');
|
|
57
|
-
reject(index_cjs_js
|
|
121
|
+
reject(index_cjs_js.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) exited with code ${code}\n${tail}`));
|
|
58
122
|
return;
|
|
59
123
|
}
|
|
60
124
|
resolve();
|
|
@@ -62,48 +126,30 @@ const runOne = (job, reportPath, options) => index_cjs_js$2.createPromise((resol
|
|
|
62
126
|
});
|
|
63
127
|
const readReport = (reportPath, job) => {
|
|
64
128
|
if (!node_fs.existsSync(reportPath)) {
|
|
65
|
-
throw index_cjs_js
|
|
129
|
+
throw index_cjs_js.createError(`pre-pass worker for ${job.dep} (${job.kind}/${job.format}) did not write a report at ${reportPath}`);
|
|
66
130
|
}
|
|
67
|
-
const data = index_cjs_js$
|
|
131
|
+
const data = index_cjs_js$4.parse(node_fs.readFileSync(reportPath, 'utf8'));
|
|
68
132
|
return { job, outputSize: data.outputSize, endHeapMB: data.endHeapMB, endRssMB: data.endRssMB, durationMs: data.durationMs };
|
|
69
133
|
};
|
|
70
|
-
const SWC_NODE_REGISTER = '@swc-node/register';
|
|
71
|
-
const swcNodeAvailable = (workspaceRoot) => node_fs.existsSync(index_cjs_js$1.join(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
|
|
72
134
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* the
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* @
|
|
85
|
-
*
|
|
86
|
-
* @example Locating the worker for an in-workspace consumer
|
|
135
|
+
* Resolves the dependency pre-pass worker by self-locating it beside the running
|
|
136
|
+
* builder module: ascends from the module's own directory to the builder package
|
|
137
|
+
* root and returns the worker at `bundle/dependencies/worker`. This works whether
|
|
138
|
+
* the builder runs from its built dist, an installed `node_modules` copy, or
|
|
139
|
+
* melded into a host bundle under `_dependencies/`. The compiled `index.cjs.js`
|
|
140
|
+
* is preferred; an `index.ts` sibling resolves with the `@swc-node/register`
|
|
141
|
+
* loader for source-mode bootstrap.
|
|
142
|
+
*
|
|
143
|
+
* @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
|
|
144
|
+
* @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
|
|
145
|
+
*
|
|
146
|
+
* @example Locating the worker beside the builder
|
|
87
147
|
* ```typescript
|
|
88
|
-
* const invocation = resolveDefaultWorkerPath(
|
|
148
|
+
* const invocation = resolveDefaultWorkerPath()
|
|
89
149
|
* if (!invocation) throw new Error('builder worker artifact not found')
|
|
90
150
|
* ```
|
|
91
151
|
*/
|
|
92
|
-
const resolveDefaultWorkerPath = (
|
|
93
|
-
const distCandidates = [
|
|
94
|
-
index_cjs_js$1.join(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
|
|
95
|
-
index_cjs_js$1.join(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
|
|
96
|
-
];
|
|
97
|
-
for (const path of distCandidates) {
|
|
98
|
-
if (node_fs.existsSync(path))
|
|
99
|
-
return { path, execArgv: [] };
|
|
100
|
-
}
|
|
101
|
-
const sourcePath = index_cjs_js$1.join(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'dependencies', 'worker', 'index.ts');
|
|
102
|
-
if (node_fs.existsSync(sourcePath) && swcNodeAvailable(workspaceRoot)) {
|
|
103
|
-
return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER] };
|
|
104
|
-
}
|
|
105
|
-
return undefined;
|
|
106
|
-
};
|
|
152
|
+
const resolveDefaultWorkerPath = (startDir) => ascendForWorker(['bundle', 'dependencies', 'worker'], startDir);
|
|
107
153
|
/**
|
|
108
154
|
* Sequentially runs the supplied pre-pass jobs by forking a fresh Node child
|
|
109
155
|
* per invocation. Strict sequential execution is mandatory — concurrent
|
|
@@ -425,13 +471,13 @@ const resolveWorkspaceBundledDeps = (packageJsonPath, workspaceRoot, options) =>
|
|
|
425
471
|
for (const packageName of filtered) {
|
|
426
472
|
const matches = collectMatchingSpecifiers(packageName, mappings);
|
|
427
473
|
if (matches.length === 0) {
|
|
428
|
-
throw index_cjs_js
|
|
474
|
+
throw index_cjs_js.createError(`bundleAllDeps: workspace dependency "${packageName}" has no resolvable tsconfig path mapping under ${workspaceRoot} (no matching paths entry, or its mapped source files are missing), so it cannot be bundled. Add a "${packageName}" (or "${packageName}/<sub-path>") entry to tsconfig.base.json paths pointing at an existing source file, or exclude it via bundleAllDeps.exclude.`);
|
|
429
475
|
}
|
|
430
476
|
const policy = policyFor(packageName);
|
|
431
477
|
const pushEntry = (specifier, inputPath) => {
|
|
432
478
|
const tsConfigPath = resolveTsConfigForPackage(inputPath);
|
|
433
479
|
if (!tsConfigPath) {
|
|
434
|
-
throw index_cjs_js
|
|
480
|
+
throw index_cjs_js.createError(`bundleAllDeps: workspace dependency "${specifier}" resolves to ${inputPath}, but no tsconfig (tsconfig.lib.json / tsconfig.json) was found in its project root, so it cannot be transformed during bundling.`);
|
|
435
481
|
}
|
|
436
482
|
const split = splitSpecifier(specifier);
|
|
437
483
|
results.push({ packageName, subPath: split.subPath, specifier, inputPath, tsConfigPath, policy });
|
|
@@ -439,7 +485,7 @@ const resolveWorkspaceBundledDeps = (packageJsonPath, workspaceRoot, options) =>
|
|
|
439
485
|
if (policy === 'whole-surface') {
|
|
440
486
|
const root = matches.find((m) => m.specifier === packageName);
|
|
441
487
|
if (!root) {
|
|
442
|
-
throw index_cjs_js
|
|
488
|
+
throw index_cjs_js.createError(`bundleAllDeps: workspace dependency "${packageName}" is explicitly set to the 'whole-surface' hoist policy but is subpath-only (no root export; tsconfig exposes only ${matches.map((m) => `"${m.specifier}"`).join(', ')}). Remove the 'whole-surface' override for it (sub-path is the default), or add a root export.`);
|
|
443
489
|
}
|
|
444
490
|
pushEntry(root.specifier, root.inputPath);
|
|
445
491
|
continue;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Plugin } from '../../_dependencies/rollup/index.js';
|
|
2
2
|
import { WorkspaceBundledDep, IsWorkspacePackagePredicate, WorkspaceDepHoistPolicy } from '../../models';
|
|
3
3
|
import { MemoryMonitor } from '../../memory';
|
|
4
|
+
import { WorkerInvocation } from '..';
|
|
4
5
|
export { PrePassWorkerJob, PrePassWorkerReport, runPrePassWorkerJob } from './worker';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -199,36 +200,24 @@ interface RunPrePassOptions {
|
|
|
199
200
|
execArgv?: string[];
|
|
200
201
|
}
|
|
201
202
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
execArgv: string[];
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Default worker-path resolution: prefers the built-and-published artifact, falls
|
|
213
|
-
* back to the workspace dist path, and finally to the in-source TypeScript file
|
|
214
|
-
* via `@swc-node/register` (bootstrap case where builder is building itself for
|
|
215
|
-
* the first time and the dist worker doesn't exist yet).
|
|
203
|
+
* Resolves the dependency pre-pass worker by self-locating it beside the running
|
|
204
|
+
* builder module: ascends from the module's own directory to the builder package
|
|
205
|
+
* root and returns the worker at `bundle/dependencies/worker`. This works whether
|
|
206
|
+
* the builder runs from its built dist, an installed `node_modules` copy, or
|
|
207
|
+
* melded into a host bundle under `_dependencies/`. The compiled `index.cjs.js`
|
|
208
|
+
* is preferred; an `index.ts` sibling resolves with the `@swc-node/register`
|
|
209
|
+
* loader for source-mode bootstrap.
|
|
216
210
|
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
* 2. `<workspaceRoot>/node_modules/@hyperfrontend/builder/bundle/dependencies/worker/index.cjs.js`
|
|
220
|
-
* 3. `<workspaceRoot>/libs/builder/src/bundle/dependencies/worker/index.ts` (with `--require \@swc-node/register`)
|
|
221
|
-
*
|
|
222
|
-
* @param workspaceRoot - Absolute workspace root.
|
|
223
|
-
* @returns Worker invocation descriptor, or `undefined` if no candidate exists.
|
|
211
|
+
* @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
|
|
212
|
+
* @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
|
|
224
213
|
*
|
|
225
|
-
* @example Locating the worker
|
|
214
|
+
* @example Locating the worker beside the builder
|
|
226
215
|
* ```typescript
|
|
227
|
-
* const invocation = resolveDefaultWorkerPath(
|
|
216
|
+
* const invocation = resolveDefaultWorkerPath()
|
|
228
217
|
* if (!invocation) throw new Error('builder worker artifact not found')
|
|
229
218
|
* ```
|
|
230
219
|
*/
|
|
231
|
-
declare const resolveDefaultWorkerPath: (
|
|
220
|
+
declare const resolveDefaultWorkerPath: (startDir?: string) => WorkerInvocation | undefined;
|
|
232
221
|
/**
|
|
233
222
|
* Sequentially runs the supplied pre-pass jobs by forking a fresh Node child
|
|
234
223
|
* per invocation. Strict sequential execution is mandatory — concurrent
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isBuiltin } from 'node:module';
|
|
2
|
-
import { join as join$1, relative, isAbsolute, resolve
|
|
2
|
+
import { join as join$1, relative, dirname, isAbsolute, resolve } from 'node:path';
|
|
3
3
|
import { spawn } from 'node:child_process';
|
|
4
4
|
import { existsSync, rmSync, mkdtempSync, readFileSync, statSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
5
5
|
import { tmpdir } from 'node:os';
|
|
@@ -22,6 +22,70 @@ import { rollup } from '../../_dependencies/rollup/index.esm.js';
|
|
|
22
22
|
import { normalizeToForwardSlashes, join } from '../../_shared/bundle/fs/posix-path/index.esm.js';
|
|
23
23
|
import { relativeImport, buildWorkspaceRoutes, createExternalizeBundledDepsPlugin } from '../../_shared/bundle/dependencies/externalize-plugin/index.esm.js';
|
|
24
24
|
|
|
25
|
+
const SWC_NODE_REGISTER = '@swc-node/register';
|
|
26
|
+
const probeDir = (dir, offset) => {
|
|
27
|
+
const compiled = join$1(dir, ...offset, 'index.cjs.js');
|
|
28
|
+
if (existsSync(compiled))
|
|
29
|
+
return { path: compiled, execArgv: [] };
|
|
30
|
+
const source = join$1(dir, ...offset, 'index.ts');
|
|
31
|
+
if (existsSync(source))
|
|
32
|
+
return { path: source, execArgv: ['--require', SWC_NODE_REGISTER] };
|
|
33
|
+
return undefined;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Directory of the currently-executing builder module, read from `__dirname`.
|
|
37
|
+
* It is present in the shipped CommonJS build, in the `@swc-node/register` source
|
|
38
|
+
* bootstrap, and under the test runner, so callers get their own on-disk location
|
|
39
|
+
* and can find the worker beside them however the builder was packaged.
|
|
40
|
+
*
|
|
41
|
+
* @returns Absolute directory path of the running module.
|
|
42
|
+
*
|
|
43
|
+
* @example Anchoring a lookup beside the running builder
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const invocation = ascendForWorker(['bundle', 'rollup', 'worker'], currentModuleDir())
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
const currentModuleDir = () => {
|
|
49
|
+
/* istanbul ignore if -- @preserve the ESM build has no __dirname; the shipped CommonJS build and the test runner always define it, so this guard is unreachable under test */
|
|
50
|
+
if (typeof __dirname === 'undefined') {
|
|
51
|
+
throw createError('@hyperfrontend/builder self-location requires the CommonJS build; drive build() from the CommonJS entry point');
|
|
52
|
+
}
|
|
53
|
+
return __dirname;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Locate a builder worker entry by ascending from a start directory toward the
|
|
57
|
+
* filesystem root, returning the first ancestor at which the worker exists at the
|
|
58
|
+
* given in-package offset. The compiled `index.cjs.js` is preferred; an `index.ts`
|
|
59
|
+
* sibling (source-mode bootstrap) resolves with the swc loader attached.
|
|
60
|
+
*
|
|
61
|
+
* The worker ships inside the builder's own package, so resolving relative to the
|
|
62
|
+
* running module finds it wherever the package lives — built dist, an installed
|
|
63
|
+
* `node_modules` copy, or melded into a host bundle under `_dependencies/`.
|
|
64
|
+
*
|
|
65
|
+
* @param offset - In-package path segments to the worker directory (e.g. `['bundle', 'rollup', 'worker']`).
|
|
66
|
+
* @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
|
|
67
|
+
* @returns The resolved worker invocation, or `undefined` if no worker exists at the offset under any ancestor.
|
|
68
|
+
*
|
|
69
|
+
* @example Resolving the rollup worker from the running module
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const invocation = ascendForWorker(['bundle', 'rollup', 'worker'])
|
|
72
|
+
* if (!invocation) throw new Error('builder rollup worker not found beside the builder module')
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
const ascendForWorker = (offset, startDir = currentModuleDir()) => {
|
|
76
|
+
let dir = startDir;
|
|
77
|
+
let parent = dirname(dir);
|
|
78
|
+
// how: probe each level then step up; the final probe covers the filesystem root, where parent === dir
|
|
79
|
+
while (parent !== dir) {
|
|
80
|
+
const found = probeDir(dir, offset);
|
|
81
|
+
if (found)
|
|
82
|
+
return found;
|
|
83
|
+
dir = parent;
|
|
84
|
+
parent = dirname(dir);
|
|
85
|
+
}
|
|
86
|
+
return probeDir(dir, offset);
|
|
87
|
+
};
|
|
88
|
+
|
|
25
89
|
const log = logger.channel('builder:bundle:dependencies:pre-pass');
|
|
26
90
|
const REPORT_DIR_PREFIX = 'hf-builder-prepass-';
|
|
27
91
|
const createReportDir = () => mkdtempSync(join$2(tmpdir(), REPORT_DIR_PREFIX));
|
|
@@ -58,43 +122,25 @@ const readReport = (reportPath, job) => {
|
|
|
58
122
|
const data = parse(readFileSync(reportPath, 'utf8'));
|
|
59
123
|
return { job, outputSize: data.outputSize, endHeapMB: data.endHeapMB, endRssMB: data.endRssMB, durationMs: data.durationMs };
|
|
60
124
|
};
|
|
61
|
-
const SWC_NODE_REGISTER = '@swc-node/register';
|
|
62
|
-
const swcNodeAvailable = (workspaceRoot) => existsSync(join$2(workspaceRoot, 'node_modules', '@swc-node', 'register', 'index.js'));
|
|
63
125
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* the
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* @
|
|
76
|
-
*
|
|
77
|
-
* @example Locating the worker for an in-workspace consumer
|
|
126
|
+
* Resolves the dependency pre-pass worker by self-locating it beside the running
|
|
127
|
+
* builder module: ascends from the module's own directory to the builder package
|
|
128
|
+
* root and returns the worker at `bundle/dependencies/worker`. This works whether
|
|
129
|
+
* the builder runs from its built dist, an installed `node_modules` copy, or
|
|
130
|
+
* melded into a host bundle under `_dependencies/`. The compiled `index.cjs.js`
|
|
131
|
+
* is preferred; an `index.ts` sibling resolves with the `@swc-node/register`
|
|
132
|
+
* loader for source-mode bootstrap.
|
|
133
|
+
*
|
|
134
|
+
* @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
|
|
135
|
+
* @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
|
|
136
|
+
*
|
|
137
|
+
* @example Locating the worker beside the builder
|
|
78
138
|
* ```typescript
|
|
79
|
-
* const invocation = resolveDefaultWorkerPath(
|
|
139
|
+
* const invocation = resolveDefaultWorkerPath()
|
|
80
140
|
* if (!invocation) throw new Error('builder worker artifact not found')
|
|
81
141
|
* ```
|
|
82
142
|
*/
|
|
83
|
-
const resolveDefaultWorkerPath = (
|
|
84
|
-
const distCandidates = [
|
|
85
|
-
join$2(workspaceRoot, 'dist', 'libs', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
|
|
86
|
-
join$2(workspaceRoot, 'node_modules', '@hyperfrontend', 'builder', 'bundle', 'dependencies', 'worker', 'index.cjs.js'),
|
|
87
|
-
];
|
|
88
|
-
for (const path of distCandidates) {
|
|
89
|
-
if (existsSync(path))
|
|
90
|
-
return { path, execArgv: [] };
|
|
91
|
-
}
|
|
92
|
-
const sourcePath = join$2(workspaceRoot, 'libs', 'builder', 'src', 'bundle', 'dependencies', 'worker', 'index.ts');
|
|
93
|
-
if (existsSync(sourcePath) && swcNodeAvailable(workspaceRoot)) {
|
|
94
|
-
return { path: sourcePath, execArgv: ['--require', SWC_NODE_REGISTER] };
|
|
95
|
-
}
|
|
96
|
-
return undefined;
|
|
97
|
-
};
|
|
143
|
+
const resolveDefaultWorkerPath = (startDir) => ascendForWorker(['bundle', 'dependencies', 'worker'], startDir);
|
|
98
144
|
/**
|
|
99
145
|
* Sequentially runs the supplied pre-pass jobs by forking a fresh Node child
|
|
100
146
|
* per invocation. Strict sequential execution is mandatory — concurrent
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { MemoryMonitor } from '../../memory/monitor';
|
|
2
|
+
import type { WorkerInvocation } from '../worker-locator';
|
|
2
3
|
import type { WorkspaceBundledDepRoute } from './externalize-plugin';
|
|
3
4
|
/**
|
|
4
5
|
* Pre-pass kind. Mirrors `PrePassWorkerJobKind` on the worker side.
|
|
@@ -98,36 +99,24 @@ export interface RunPrePassOptions {
|
|
|
98
99
|
execArgv?: string[];
|
|
99
100
|
}
|
|
100
101
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
execArgv: string[];
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Default worker-path resolution: prefers the built-and-published artifact, falls
|
|
112
|
-
* back to the workspace dist path, and finally to the in-source TypeScript file
|
|
113
|
-
* via `@swc-node/register` (bootstrap case where builder is building itself for
|
|
114
|
-
* the first time and the dist worker doesn't exist yet).
|
|
115
|
-
*
|
|
116
|
-
* Looks at, in order:
|
|
117
|
-
* 1. `<workspaceRoot>/dist/libs/builder/bundle/dependencies/worker/index.cjs.js`
|
|
118
|
-
* 2. `<workspaceRoot>/node_modules/@hyperfrontend/builder/bundle/dependencies/worker/index.cjs.js`
|
|
119
|
-
* 3. `<workspaceRoot>/libs/builder/src/bundle/dependencies/worker/index.ts` (with `--require \@swc-node/register`)
|
|
102
|
+
* Resolves the dependency pre-pass worker by self-locating it beside the running
|
|
103
|
+
* builder module: ascends from the module's own directory to the builder package
|
|
104
|
+
* root and returns the worker at `bundle/dependencies/worker`. This works whether
|
|
105
|
+
* the builder runs from its built dist, an installed `node_modules` copy, or
|
|
106
|
+
* melded into a host bundle under `_dependencies/`. The compiled `index.cjs.js`
|
|
107
|
+
* is preferred; an `index.ts` sibling resolves with the `@swc-node/register`
|
|
108
|
+
* loader for source-mode bootstrap.
|
|
120
109
|
*
|
|
121
|
-
* @param
|
|
122
|
-
* @returns Worker invocation descriptor, or `undefined` if no
|
|
110
|
+
* @param startDir - Directory to begin the ascent from. Defaults to the running module's directory; pass an explicit value to resolve from another anchor or under test.
|
|
111
|
+
* @returns Worker invocation descriptor, or `undefined` if no worker is found under any ancestor.
|
|
123
112
|
*
|
|
124
|
-
* @example Locating the worker
|
|
113
|
+
* @example Locating the worker beside the builder
|
|
125
114
|
* ```typescript
|
|
126
|
-
* const invocation = resolveDefaultWorkerPath(
|
|
115
|
+
* const invocation = resolveDefaultWorkerPath()
|
|
127
116
|
* if (!invocation) throw new Error('builder worker artifact not found')
|
|
128
117
|
* ```
|
|
129
118
|
*/
|
|
130
|
-
export declare const resolveDefaultWorkerPath: (
|
|
119
|
+
export declare const resolveDefaultWorkerPath: (startDir?: string) => WorkerInvocation | undefined;
|
|
131
120
|
/**
|
|
132
121
|
* Sequentially runs the supplied pre-pass jobs by forking a fresh Node child
|
|
133
122
|
* per invocation. Strict sequential execution is mandatory — concurrent
|