@d1g1tal/tsbuild 1.8.3 → 1.8.5
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 +44 -0
- package/dist/{UM2SFHAT.js → WCBM4DJB.js} +137 -96
- package/dist/tsbuild.js +2 -2
- package/dist/type-script-project.js +1 -1
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,47 @@
|
|
|
1
|
+
## [1.8.5](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.8.4...v1.8.5) (2026-04-14)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* **iife:** resolve paths absolutely and output to nested directory (7514592a039f02e070b71f4c30c6cd88a99bd17d)
|
|
6
|
+
- Changes IIFE output to resolve paths absolutely instead of relatively
|
|
7
|
+
- Creates a dedicated `iife` output directory under the main `outdir`
|
|
8
|
+
- Fixes virtual loader plugin to handle the new directory structure properly
|
|
9
|
+
- Adds an integration test for IIFE builds
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Build System
|
|
13
|
+
|
|
14
|
+
* **deps-dev:** bump typescript-eslint dependencies (e4abe9fe4083b89953f94f4cd17622387844b844)
|
|
15
|
+
- Updates `@typescript-eslint/eslint-plugin`, `@typescript-eslint/parser`, and `typescript-eslint` from 8.58.1 to 8.58.2
|
|
16
|
+
- Updates `pnpm-lock.yaml` with the new versions and their sub-dependencies
|
|
17
|
+
|
|
18
|
+
## [1.8.4](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.8.3...v1.8.4) (2026-04-12)
|
|
19
|
+
|
|
20
|
+
### Performance Improvements
|
|
21
|
+
|
|
22
|
+
* **build:** delegate file writing to esbuild (84a64e212a9dc7f309bb2dcbe74ffa990c06065b)
|
|
23
|
+
- Enables esbuild write option for direct-to-disk transpilation output
|
|
24
|
+
- Moves relative module specifier rewriting logic to FileManager
|
|
25
|
+
- Simplifies output plugin to only manage shebang executable permissions via chmod
|
|
26
|
+
- Adapts IIFE plugin to process metafile outputs instead of in-memory files
|
|
27
|
+
- Updates tests and mock helpers to align with file writing capabilities
|
|
28
|
+
|
|
29
|
+
* **dts:** optimize declaration bundler module resolution and graph traversal (59606c0ccfe54ac74068fe6ab8f6d26d7edd97b6)
|
|
30
|
+
- Optimizes module pattern matching by using Sets and RegEx arrays instead of iteration
|
|
31
|
+
- Refactors bundled specifiers state to use ReadonlySet for O(1) lookups
|
|
32
|
+
- Simplifies deduplication of non-mergeable imports using Sets
|
|
33
|
+
- Yields the event loop before cpu-intensive declaration bundling to prevent I/O blocking
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Miscellaneous Chores
|
|
37
|
+
|
|
38
|
+
* **perf:** add performance baseline documentation and benchmark script (3e897aaa7a35022b8d9ec1d4222448973eb57a2b)
|
|
39
|
+
- Adds documentation detailing performance baselines and architectures
|
|
40
|
+
- Introduces performance measurements log
|
|
41
|
+
- Adds quick reference for performance monitoring
|
|
42
|
+
- Introduces new benchmark script for running automated metrics collection
|
|
43
|
+
- Registers bench script in package.json
|
|
44
|
+
|
|
1
45
|
## [1.8.3](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.8.2...v1.8.3) (2026-04-11)
|
|
2
46
|
|
|
3
47
|
### Performance Improvements
|
|
@@ -148,13 +148,13 @@ var isColorSupported = !("NO_COLOR" in env) && ("FORCE_COLOR" in env || platform
|
|
|
148
148
|
var replaceClose = (index, string, close, replace, head = string.substring(0, index) + replace, tail = string.substring(index + close.length), next = tail.indexOf(close)) => {
|
|
149
149
|
return head + (next < 0 ? tail : replaceClose(next, tail, close, replace));
|
|
150
150
|
};
|
|
151
|
-
var clearBleed = (index, string,
|
|
152
|
-
return index < 0 ? `${
|
|
151
|
+
var clearBleed = (index, string, open2, close, replace) => {
|
|
152
|
+
return index < 0 ? `${open2}${string}${close}` : `${open2}${replaceClose(index, string, close, replace)}${close}`;
|
|
153
153
|
};
|
|
154
|
-
var filterEmpty = (
|
|
155
|
-
return (text) => text.length ? clearBleed(text.indexOf(close, at), text,
|
|
154
|
+
var filterEmpty = (open2, close, replace = open2, at = open2.length + 1) => {
|
|
155
|
+
return (text) => text.length ? clearBleed(text.indexOf(close, at), text, open2, close, replace) : "";
|
|
156
156
|
};
|
|
157
|
-
var generateTextFormatter = (
|
|
157
|
+
var generateTextFormatter = (open2, close, replace) => filterEmpty(`\x1B[${open2}m`, `\x1B[${close}m`, replace);
|
|
158
158
|
var TextFormat = class {
|
|
159
159
|
static enabled = isColorSupported;
|
|
160
160
|
static reset = generateTextFormatter(0, 0);
|
|
@@ -817,36 +817,40 @@ import {
|
|
|
817
817
|
forEachChild as forEachChild2
|
|
818
818
|
} from "typescript";
|
|
819
819
|
var nodeModules = "/node_modules/";
|
|
820
|
+
var emptySet = /* @__PURE__ */ new Set();
|
|
820
821
|
var importPattern = /^import\s*(?:type\s*)?\{\s*([^}]+)\s*\}\s*from\s*['"]([^'"]+)['"]\s*;?\s*$/;
|
|
821
822
|
var typePrefixPattern = /^type:/;
|
|
822
823
|
function mergeImports(imports) {
|
|
823
824
|
const moduleImports = /* @__PURE__ */ new Map();
|
|
824
|
-
const nonMergeableImports =
|
|
825
|
+
const nonMergeableImports = /* @__PURE__ */ new Set();
|
|
825
826
|
for (const importStatement of imports) {
|
|
826
827
|
const match = importPattern.exec(importStatement);
|
|
827
828
|
if (match) {
|
|
828
829
|
const [, namesString, moduleSpecifier] = match;
|
|
829
830
|
const isType = importStatement.includes("import type");
|
|
830
831
|
const key = `${isType ? "type:" : ""}${moduleSpecifier}`;
|
|
831
|
-
|
|
832
|
-
|
|
832
|
+
let entry = moduleImports.get(key);
|
|
833
|
+
if (entry === void 0) {
|
|
834
|
+
entry = { names: /* @__PURE__ */ new Set(), isType };
|
|
835
|
+
moduleImports.set(key, entry);
|
|
833
836
|
}
|
|
834
|
-
const entry = moduleImports.get(key);
|
|
835
837
|
for (const name of namesString.split(",")) {
|
|
836
838
|
entry.names.add(name.trim());
|
|
837
839
|
}
|
|
838
840
|
} else {
|
|
839
|
-
nonMergeableImports.
|
|
841
|
+
nonMergeableImports.add(importStatement);
|
|
840
842
|
}
|
|
841
843
|
}
|
|
842
844
|
const result = [];
|
|
843
845
|
for (const [key, { names, isType }] of moduleImports) {
|
|
844
846
|
result.push(`${isType ? "import type" : "import"} { ${[...names].sort().join(", ")} } from "${key.replace(typePrefixPattern, "")}";`);
|
|
845
847
|
}
|
|
846
|
-
|
|
848
|
+
for (const imp of nonMergeableImports) {
|
|
849
|
+
result.push(imp);
|
|
850
|
+
}
|
|
847
851
|
return result;
|
|
848
852
|
}
|
|
849
|
-
var DeclarationBundler = class {
|
|
853
|
+
var DeclarationBundler = class _DeclarationBundler {
|
|
850
854
|
/** Project declaration files from in-memory FileManager */
|
|
851
855
|
declarationFiles = /* @__PURE__ */ new Map();
|
|
852
856
|
/** External declaration files resolved from disk (node_modules) when resolve is enabled */
|
|
@@ -859,6 +863,10 @@ var DeclarationBundler = class {
|
|
|
859
863
|
moduleResolutionCache = /* @__PURE__ */ new Map();
|
|
860
864
|
/** Pre-computed set of directory prefixes from declaration file paths for O(1) directoryExists lookups */
|
|
861
865
|
declarationDirs = /* @__PURE__ */ new Set();
|
|
866
|
+
/** Pre-built matcher for external patterns — O(1) string lookups + cached regex tests */
|
|
867
|
+
matchExternal;
|
|
868
|
+
/** Pre-built matcher for noExternal patterns — O(1) string lookups + cached regex tests */
|
|
869
|
+
matchNoExternal;
|
|
862
870
|
// Create a proper module resolution host that supports both in-memory files and disk files
|
|
863
871
|
moduleResolutionHost = {
|
|
864
872
|
fileExists: (fileName) => {
|
|
@@ -908,6 +916,8 @@ var DeclarationBundler = class {
|
|
|
908
916
|
}
|
|
909
917
|
}
|
|
910
918
|
this.options = dtsBundleOptions;
|
|
919
|
+
this.matchExternal = _DeclarationBundler.buildMatcher(dtsBundleOptions.external);
|
|
920
|
+
this.matchNoExternal = _DeclarationBundler.buildMatcher(dtsBundleOptions.noExternal);
|
|
911
921
|
}
|
|
912
922
|
/**
|
|
913
923
|
* Clears external declaration files and module resolution cache to free memory.
|
|
@@ -960,23 +970,42 @@ var DeclarationBundler = class {
|
|
|
960
970
|
return imports;
|
|
961
971
|
}
|
|
962
972
|
/**
|
|
963
|
-
*
|
|
964
|
-
*
|
|
965
|
-
* @param patterns -
|
|
966
|
-
* @returns
|
|
967
|
-
*/
|
|
968
|
-
matchesPattern(moduleSpecifier, patterns) {
|
|
969
|
-
return patterns.some((pattern) => {
|
|
970
|
-
return typeof pattern === "string" ? moduleSpecifier === pattern || moduleSpecifier.startsWith(`${pattern}/`) : pattern.test(moduleSpecifier);
|
|
971
|
-
});
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* Check if a module specifier matches explicit external patterns
|
|
975
|
-
* @param moduleSpecifier - The module specifier to check
|
|
976
|
-
* @returns True if the module should be treated as external
|
|
973
|
+
* Builds an O(1) matcher from a mixed Pattern array by splitting into a Set<string> for
|
|
974
|
+
* exact/sub-path checks and a RegExp[] for regex tests. Called once per bundler instance.
|
|
975
|
+
* @param patterns - The array of string and RegExp patterns to match against module specifiers
|
|
976
|
+
* @returns A function that takes a module specifier and returns true if it matches any of the patterns
|
|
977
977
|
*/
|
|
978
|
-
|
|
979
|
-
|
|
978
|
+
static buildMatcher(patterns) {
|
|
979
|
+
const exact = /* @__PURE__ */ new Set();
|
|
980
|
+
const prefixes = [];
|
|
981
|
+
const regexps = [];
|
|
982
|
+
for (const p of patterns) {
|
|
983
|
+
if (typeof p === "string") {
|
|
984
|
+
exact.add(p);
|
|
985
|
+
prefixes.push(p + "/");
|
|
986
|
+
} else {
|
|
987
|
+
regexps.push(p);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
if (exact.size === 0 && regexps.length === 0) {
|
|
991
|
+
return () => false;
|
|
992
|
+
}
|
|
993
|
+
return (id) => {
|
|
994
|
+
if (exact.has(id)) {
|
|
995
|
+
return true;
|
|
996
|
+
}
|
|
997
|
+
for (let i = 0; i < prefixes.length; i++) {
|
|
998
|
+
if (id.startsWith(prefixes[i])) {
|
|
999
|
+
return true;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
for (let i = 0; i < regexps.length; i++) {
|
|
1003
|
+
if (regexps[i].test(id)) {
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
return false;
|
|
1008
|
+
};
|
|
980
1009
|
}
|
|
981
1010
|
/**
|
|
982
1011
|
* Resolve a module import using TypeScript's resolution algorithm with path mapping support
|
|
@@ -1024,18 +1053,18 @@ var DeclarationBundler = class {
|
|
|
1024
1053
|
const sourceFile = createSourceFile(path, code, ScriptTarget.Latest, true);
|
|
1025
1054
|
const identifiers = this.collectIdentifiers(sourceFile.statements, sourceFile);
|
|
1026
1055
|
const module = { path, code, imports: /* @__PURE__ */ new Set(), typeReferences: new Set(typeReferences), fileReferences: new Set(fileReferences), sourceFile, identifiers };
|
|
1027
|
-
const bundledSpecs =
|
|
1056
|
+
const bundledSpecs = /* @__PURE__ */ new Set();
|
|
1028
1057
|
for (const specifier of this.extractImports(sourceFile)) {
|
|
1029
|
-
if (this.
|
|
1058
|
+
if (this.matchExternal(specifier)) {
|
|
1030
1059
|
continue;
|
|
1031
1060
|
}
|
|
1032
1061
|
const resolvedPath = this.resolveModule(specifier, path);
|
|
1033
|
-
if (resolvedPath?.includes(nodeModules) && !this.
|
|
1062
|
+
if (resolvedPath?.includes(nodeModules) && !this.matchNoExternal(specifier)) {
|
|
1034
1063
|
continue;
|
|
1035
1064
|
}
|
|
1036
1065
|
if (resolvedPath && (this.declarationFiles.has(resolvedPath) || this.externalDeclarationFiles.has(resolvedPath))) {
|
|
1037
1066
|
module.imports.add(resolvedPath);
|
|
1038
|
-
bundledSpecs.
|
|
1067
|
+
bundledSpecs.add(specifier);
|
|
1039
1068
|
visit(resolvedPath);
|
|
1040
1069
|
}
|
|
1041
1070
|
}
|
|
@@ -1146,7 +1175,7 @@ var DeclarationBundler = class {
|
|
|
1146
1175
|
* @param code - Declaration file content
|
|
1147
1176
|
* @param sourceFile - Parsed source file AST (required to avoid re-parsing)
|
|
1148
1177
|
* @param identifiers - Pre-computed type and value identifiers (to avoid re-computation)
|
|
1149
|
-
* @param bundledImportPaths -
|
|
1178
|
+
* @param bundledImportPaths - Set of resolved file paths that were bundled (to exclude from external imports)
|
|
1150
1179
|
* @param renameMap - Map of renamed identifiers (name:path -> newName)
|
|
1151
1180
|
* @param modulePath - Path of current module for looking up renames
|
|
1152
1181
|
* @returns Object with processed code, collected external imports, and exported names (separated by type/value)
|
|
@@ -1169,7 +1198,7 @@ var DeclarationBundler = class {
|
|
|
1169
1198
|
for (const statement of sourceFile.statements) {
|
|
1170
1199
|
if (isImportDeclaration2(statement)) {
|
|
1171
1200
|
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
1172
|
-
if (this.
|
|
1201
|
+
if (this.matchExternal(moduleSpecifier) || !bundledImportPaths.has(moduleSpecifier)) {
|
|
1173
1202
|
externalImports.push(code.substring(statement.pos, statement.end).trim());
|
|
1174
1203
|
} else if (statement.importClause?.namedBindings && isNamespaceImport(statement.importClause.namedBindings)) {
|
|
1175
1204
|
bundledNamespaceAliases.add(statement.importClause.namedBindings.name.text);
|
|
@@ -1262,7 +1291,9 @@ var DeclarationBundler = class {
|
|
|
1262
1291
|
for (const [name, sourcesSet] of declarationSources) {
|
|
1263
1292
|
if (sourcesSet.size > 1) {
|
|
1264
1293
|
let suffix = 1;
|
|
1265
|
-
|
|
1294
|
+
const modulePaths = sourcesSet.values();
|
|
1295
|
+
modulePaths.next();
|
|
1296
|
+
for (const modulePath of modulePaths) {
|
|
1266
1297
|
let candidate = `${name}$${suffix}`;
|
|
1267
1298
|
while (declarationSources.has(candidate)) {
|
|
1268
1299
|
candidate = `${name}$${++suffix}`;
|
|
@@ -1275,7 +1306,7 @@ var DeclarationBundler = class {
|
|
|
1275
1306
|
for (const { path, typeReferences, fileReferences, sourceFile, code, identifiers } of sortedModules) {
|
|
1276
1307
|
allTypeReferences.push(...typeReferences);
|
|
1277
1308
|
allFileReferences.push(...fileReferences);
|
|
1278
|
-
const bundledForThisModule = bundledSpecifiers.get(path)
|
|
1309
|
+
const bundledForThisModule = bundledSpecifiers.get(path) ?? emptySet;
|
|
1279
1310
|
const { code: strippedCode, externalImports, typeExports, valueExports } = this.stripImportsExports(code, sourceFile, identifiers, bundledForThisModule, renameMap, path);
|
|
1280
1311
|
allExternalImports.push(...externalImports);
|
|
1281
1312
|
if (!path.includes(nodeModules)) {
|
|
@@ -1372,11 +1403,12 @@ async function bundleDeclarations(options) {
|
|
|
1372
1403
|
await mkdir2(options.compilerOptions.outDir, defaultDirOptions);
|
|
1373
1404
|
}
|
|
1374
1405
|
const dtsBundler = new DeclarationBundler(options);
|
|
1406
|
+
await new Promise((resolve3) => void setImmediate(resolve3));
|
|
1375
1407
|
const bundleTasks = [];
|
|
1376
1408
|
for (const [entryName, entryPoint] of Object.entries(options.entryPoints)) {
|
|
1377
1409
|
const content = dtsBundler.bundle(entryPoint);
|
|
1378
1410
|
if (content.length > 0) {
|
|
1379
|
-
const outPath = Paths.join(options.compilerOptions.outDir, `${entryName}.
|
|
1411
|
+
const outPath = Paths.join(options.compilerOptions.outDir, `${entryName}${FileExtension.DTS}`);
|
|
1380
1412
|
bundleTasks.push(writeFile2(outPath, content, Encoding.utf8).then(() => ({ path: Paths.relative(options.currentDirectory, outPath), size: content.length })));
|
|
1381
1413
|
}
|
|
1382
1414
|
}
|
|
@@ -1386,38 +1418,42 @@ async function bundleDeclarations(options) {
|
|
|
1386
1418
|
}
|
|
1387
1419
|
|
|
1388
1420
|
// src/plugins/output.ts
|
|
1421
|
+
import { chmod, open } from "node:fs/promises";
|
|
1389
1422
|
import { extname } from "node:path";
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
}
|
|
1398
|
-
async function fileMapper({ path, contents }) {
|
|
1399
|
-
if (extname(path) !== FileExtension.JS) {
|
|
1400
|
-
return Files.write(path, contents, { mode: FileMode.READ_WRITE });
|
|
1401
|
-
}
|
|
1402
|
-
let rewritten = false;
|
|
1403
|
-
const result = textDecoder.decode(contents).replace(relativeSpecifierPattern, (_, before, specPath, after) => {
|
|
1404
|
-
if (localFileIdentifier.test(specPath)) {
|
|
1405
|
-
return before + specPath + after;
|
|
1423
|
+
async function setShebangPermissions(filePath) {
|
|
1424
|
+
const handle = await open(filePath, "r");
|
|
1425
|
+
try {
|
|
1426
|
+
const buf = Buffer.alloc(2);
|
|
1427
|
+
await handle.read(buf, 0, 2, 0);
|
|
1428
|
+
if (buf[0] === 35 && buf[1] === 33) {
|
|
1429
|
+
await chmod(filePath, 493);
|
|
1406
1430
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
}
|
|
1410
|
-
return Files.write(path, rewritten ? textEncoder.encode(result) : contents, { mode: contents[0] === 35 && contents[1] === 33 ? FileMode.READ_WRITE_EXECUTE : FileMode.READ_WRITE });
|
|
1431
|
+
} finally {
|
|
1432
|
+
await handle.close();
|
|
1433
|
+
}
|
|
1411
1434
|
}
|
|
1412
1435
|
var outputPlugin = () => {
|
|
1413
1436
|
return {
|
|
1414
1437
|
name: "esbuild:output-plugin",
|
|
1415
1438
|
/**
|
|
1416
|
-
*
|
|
1439
|
+
* Checks JS entry points for shebangs and sets executable permissions
|
|
1417
1440
|
* @param build The esbuild build instance
|
|
1418
1441
|
*/
|
|
1419
1442
|
setup(build) {
|
|
1420
|
-
build.onEnd(async ({
|
|
1443
|
+
build.onEnd(async ({ metafile }) => {
|
|
1444
|
+
if (!metafile) {
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
const tasks = [];
|
|
1448
|
+
for (const [outputPath, { entryPoint }] of Object.entries(metafile.outputs)) {
|
|
1449
|
+
if (entryPoint && extname(outputPath) === FileExtension.JS) {
|
|
1450
|
+
tasks.push(setShebangPermissions(outputPath));
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
if (tasks.length > 0) {
|
|
1454
|
+
await Promise.all(tasks);
|
|
1455
|
+
}
|
|
1456
|
+
});
|
|
1421
1457
|
}
|
|
1422
1458
|
};
|
|
1423
1459
|
};
|
|
@@ -1538,9 +1574,9 @@ async function resolvePlugins(plugins, projectDir) {
|
|
|
1538
1574
|
}
|
|
1539
1575
|
|
|
1540
1576
|
// src/plugins/iife.ts
|
|
1541
|
-
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
1577
|
+
import { mkdir as mkdir3, readFile as readFile2, writeFile as writeFile3 } from "node:fs/promises";
|
|
1542
1578
|
import { basename as basename2, dirname as dirname2, join, resolve as resolve2 } from "node:path";
|
|
1543
|
-
var
|
|
1579
|
+
var textDecoder = new TextDecoder();
|
|
1544
1580
|
var jsExtension = ".js";
|
|
1545
1581
|
function iifePlugin(options) {
|
|
1546
1582
|
const globalName = options?.globalName;
|
|
@@ -1560,11 +1596,11 @@ function iifePlugin(options) {
|
|
|
1560
1596
|
}
|
|
1561
1597
|
const sourcemap = build.initialOptions.sourcemap;
|
|
1562
1598
|
const entryPointNames = extractEntryNames(build.initialOptions.entryPoints);
|
|
1563
|
-
build.onEnd(async ({
|
|
1564
|
-
if (!
|
|
1599
|
+
build.onEnd(async ({ metafile }) => {
|
|
1600
|
+
if (!metafile || entryPointNames.length === 0) {
|
|
1565
1601
|
return;
|
|
1566
1602
|
}
|
|
1567
|
-
const written = await buildIife(
|
|
1603
|
+
const written = await buildIife(metafile.outputs, entryPointNames, outdir, globalName, sourcemap);
|
|
1568
1604
|
files.push(...written);
|
|
1569
1605
|
});
|
|
1570
1606
|
}
|
|
@@ -1590,6 +1626,7 @@ function extractEntryNames(entryPoints) {
|
|
|
1590
1626
|
}
|
|
1591
1627
|
var exportRegex = /export\s*\{([^}]*)\};?/g;
|
|
1592
1628
|
var exportAliasRegex = /^(\w+)\s+as\s+(\w+)$/;
|
|
1629
|
+
var namespace = "iife";
|
|
1593
1630
|
function wrapAsIife(text, globalName) {
|
|
1594
1631
|
const exportIndex = text.lastIndexOf("export");
|
|
1595
1632
|
if (exportIndex === -1) {
|
|
@@ -1620,31 +1657,30 @@ ${body}
|
|
|
1620
1657
|
${assignment}
|
|
1621
1658
|
})();${after}`;
|
|
1622
1659
|
}
|
|
1623
|
-
async function buildIife(
|
|
1660
|
+
async function buildIife(outputs, entryPointNames, outdir, globalName, sourcemap) {
|
|
1624
1661
|
const { build: esbuild } = await import("esbuild");
|
|
1625
1662
|
const fileContents = /* @__PURE__ */ new Map();
|
|
1626
|
-
for (const
|
|
1627
|
-
if (
|
|
1628
|
-
fileContents.set(
|
|
1663
|
+
for (const outputPath of Object.keys(outputs)) {
|
|
1664
|
+
if (outputPath.endsWith(jsExtension)) {
|
|
1665
|
+
fileContents.set(resolve2(outputPath), await readFile2(outputPath, "utf8"));
|
|
1629
1666
|
}
|
|
1630
1667
|
}
|
|
1631
1668
|
const validEntries = [];
|
|
1632
1669
|
for (const name of entryPointNames) {
|
|
1633
|
-
const
|
|
1634
|
-
if (fileContents.has(
|
|
1635
|
-
validEntries.push({ name,
|
|
1670
|
+
const path = Paths.absolute(outdir, name + jsExtension);
|
|
1671
|
+
if (fileContents.has(path)) {
|
|
1672
|
+
validEntries.push({ name, path });
|
|
1636
1673
|
}
|
|
1637
1674
|
}
|
|
1638
1675
|
if (validEntries.length === 0) {
|
|
1639
1676
|
return [];
|
|
1640
1677
|
}
|
|
1641
1678
|
const hasSourceMap = sourcemap !== void 0 && sourcemap !== false;
|
|
1642
|
-
const
|
|
1643
|
-
const
|
|
1644
|
-
await
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
entryPoints: { [name]: absPath },
|
|
1679
|
+
const plugins = [virtualLoaderPlugin(fileContents)];
|
|
1680
|
+
const iifeOutdir = await mkdir3(join(outdir, namespace), { recursive: true });
|
|
1681
|
+
const results = await Promise.all(validEntries.map(({ name, path }) => {
|
|
1682
|
+
return esbuild({
|
|
1683
|
+
entryPoints: { [name]: path },
|
|
1648
1684
|
bundle: true,
|
|
1649
1685
|
format: "esm",
|
|
1650
1686
|
splitting: false,
|
|
@@ -1652,16 +1688,16 @@ async function buildIife(outputFiles, entryPointNames, outdir, globalName, sourc
|
|
|
1652
1688
|
sourcemap: hasSourceMap ? "external" : false,
|
|
1653
1689
|
write: false,
|
|
1654
1690
|
logLevel: "warning",
|
|
1655
|
-
plugins
|
|
1656
|
-
})
|
|
1657
|
-
));
|
|
1691
|
+
plugins
|
|
1692
|
+
});
|
|
1693
|
+
}));
|
|
1658
1694
|
const written = [];
|
|
1659
1695
|
const writes = [];
|
|
1660
1696
|
const cwd = process.cwd();
|
|
1661
1697
|
for (const { outputFiles: iifeFiles } of results) {
|
|
1662
1698
|
for (const { path, contents } of iifeFiles) {
|
|
1663
1699
|
if (path.endsWith(jsExtension)) {
|
|
1664
|
-
const text = wrapAsIife(
|
|
1700
|
+
const text = wrapAsIife(textDecoder.decode(contents), globalName);
|
|
1665
1701
|
writes.push(writeFile3(path, text));
|
|
1666
1702
|
written.push({ path: Paths.relative(cwd, path), size: Buffer.byteLength(text) });
|
|
1667
1703
|
} else {
|
|
@@ -1683,23 +1719,20 @@ function virtualLoaderPlugin(fileContents) {
|
|
|
1683
1719
|
setup(build) {
|
|
1684
1720
|
build.onResolve({ filter: /.*/ }, (args) => {
|
|
1685
1721
|
if (args.kind === "entry-point") {
|
|
1686
|
-
return { path: args.path, namespace
|
|
1722
|
+
return { path: args.path, namespace };
|
|
1687
1723
|
}
|
|
1688
1724
|
if (!args.path.startsWith(".") && !args.path.startsWith("/")) {
|
|
1689
1725
|
return { external: true };
|
|
1690
1726
|
}
|
|
1691
1727
|
const resolved = resolve2(args.resolveDir, args.path);
|
|
1692
1728
|
if (fileContents.has(resolved)) {
|
|
1693
|
-
return { path: resolved, namespace
|
|
1729
|
+
return { path: resolved, namespace };
|
|
1694
1730
|
}
|
|
1695
1731
|
return { external: true };
|
|
1696
1732
|
});
|
|
1697
|
-
build.onLoad({ filter: /.*/, namespace
|
|
1733
|
+
build.onLoad({ filter: /.*/, namespace }, (args) => {
|
|
1698
1734
|
const contents = fileContents.get(args.path);
|
|
1699
|
-
|
|
1700
|
-
return { contents, loader: "js", resolveDir: dirname2(args.path) };
|
|
1701
|
-
}
|
|
1702
|
-
return null;
|
|
1735
|
+
return contents === void 0 ? null : { contents, loader: "js", resolveDir: dirname2(args.path) };
|
|
1703
1736
|
});
|
|
1704
1737
|
}
|
|
1705
1738
|
};
|
|
@@ -1941,6 +1974,11 @@ function debounce(wait) {
|
|
|
1941
1974
|
|
|
1942
1975
|
// src/file-manager.ts
|
|
1943
1976
|
import { createSourceFile as createSourceFile2, ScriptTarget as ScriptTarget2 } from "typescript";
|
|
1977
|
+
var localFileIdentifier = /\.[a-z]+$/i;
|
|
1978
|
+
var relativeSpecifierPattern = /(from\s*['"])(\.\.?\/[^'"]*?)(['"])/g;
|
|
1979
|
+
function rewriteRelativeSpecifiers(code) {
|
|
1980
|
+
return code.replace(relativeSpecifierPattern, (_, before, path, after) => localFileIdentifier.test(path) ? before + path + after : `${before}${path}.js${after}`);
|
|
1981
|
+
}
|
|
1944
1982
|
var FileManager = class {
|
|
1945
1983
|
hasEmittedFiles = false;
|
|
1946
1984
|
declarationFiles = /* @__PURE__ */ new Map();
|
|
@@ -1999,14 +2037,17 @@ var FileManager = class {
|
|
|
1999
2037
|
*/
|
|
2000
2038
|
finalize() {
|
|
2001
2039
|
this.processEmittedFiles();
|
|
2002
|
-
const
|
|
2040
|
+
const tasks = [];
|
|
2041
|
+
if (this.pendingBuildInfo) {
|
|
2042
|
+
tasks.push(Files.write(this.pendingBuildInfo.path, this.pendingBuildInfo.text));
|
|
2043
|
+
}
|
|
2003
2044
|
this.pendingBuildInfo = void 0;
|
|
2004
2045
|
if (this.cache && this.hasEmittedFiles) {
|
|
2005
|
-
|
|
2006
|
-
});
|
|
2007
|
-
} else if (buildInfoWrite) {
|
|
2008
|
-
this.pendingSave = buildInfoWrite;
|
|
2046
|
+
tasks.push(this.cache.save(this.declarationFiles));
|
|
2009
2047
|
}
|
|
2048
|
+
this.pendingSave = Promise.all(tasks).then(() => {
|
|
2049
|
+
}, () => {
|
|
2050
|
+
});
|
|
2010
2051
|
this.pendingSave?.catch(() => {
|
|
2011
2052
|
});
|
|
2012
2053
|
return this.cache === void 0 || this.hasEmittedFiles;
|
|
@@ -2038,7 +2079,7 @@ var FileManager = class {
|
|
|
2038
2079
|
writeTasks.push(this.writeFile(projectDirectory, filePath, code));
|
|
2039
2080
|
}
|
|
2040
2081
|
}
|
|
2041
|
-
return
|
|
2082
|
+
return Promise.all(writeTasks);
|
|
2042
2083
|
}
|
|
2043
2084
|
/**
|
|
2044
2085
|
* Resolves entry points for declaration bundling.
|
|
@@ -2383,7 +2424,7 @@ var _TypeScriptProject = class _TypeScriptProject {
|
|
|
2383
2424
|
return Files.empty(this.buildConfiguration.outDir);
|
|
2384
2425
|
}
|
|
2385
2426
|
async build() {
|
|
2386
|
-
Logger.header(`${tsLogo} tsbuild v${"1.8.
|
|
2427
|
+
Logger.header(`${tsLogo} tsbuild v${"1.8.5"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
|
|
2387
2428
|
try {
|
|
2388
2429
|
const processes = [];
|
|
2389
2430
|
const filesWereEmitted = await this.typeCheck();
|
|
@@ -2486,7 +2527,7 @@ var _TypeScriptProject = class _TypeScriptProject {
|
|
|
2486
2527
|
format,
|
|
2487
2528
|
plugins,
|
|
2488
2529
|
define,
|
|
2489
|
-
write:
|
|
2530
|
+
write: true,
|
|
2490
2531
|
metafile: true,
|
|
2491
2532
|
treeShaking: true,
|
|
2492
2533
|
logLevel: "warning",
|
package/dist/tsbuild.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BuildError,
|
|
4
4
|
TypeScriptProject
|
|
5
|
-
} from "./
|
|
5
|
+
} from "./WCBM4DJB.js";
|
|
6
6
|
import "./JKGYA2AW.js";
|
|
7
7
|
|
|
8
8
|
// src/tsbuild.ts
|
|
@@ -30,7 +30,7 @@ if (help) {
|
|
|
30
30
|
process.exit(0);
|
|
31
31
|
}
|
|
32
32
|
if (version) {
|
|
33
|
-
console.log("1.8.
|
|
33
|
+
console.log("1.8.5");
|
|
34
34
|
process.exit(0);
|
|
35
35
|
}
|
|
36
36
|
var typeScriptOptions = {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d1g1tal/tsbuild",
|
|
3
3
|
"author": "D1g1talEntr0py",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.5",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "A fast, ESM-only TypeScript build tool combining the TypeScript API for type checking and declaration generation, esbuild for bundling, and SWC for decorator metadata.",
|
|
7
7
|
"homepage": "https://github.com/D1g1talEntr0py/tsbuild#readme",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@eslint/js": "^10.0.1",
|
|
53
53
|
"@types/node": "^25.6.0",
|
|
54
|
-
"@typescript-eslint/eslint-plugin": "^8.58.
|
|
55
|
-
"@typescript-eslint/parser": "^8.58.
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^8.58.2",
|
|
55
|
+
"@typescript-eslint/parser": "^8.58.2",
|
|
56
56
|
"@vitest/coverage-v8": "^4.1.4",
|
|
57
57
|
"eslint": "^10.2.0",
|
|
58
58
|
"eslint-plugin-jsdoc": "^62.9.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"memfs": "^4.57.1",
|
|
61
61
|
"tsx": "^4.21.0",
|
|
62
62
|
"typescript": "^6.0.2",
|
|
63
|
-
"typescript-eslint": "^8.58.
|
|
63
|
+
"typescript-eslint": "^8.58.2",
|
|
64
64
|
"vitest": "^4.1.4"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
"scripts": {
|
|
82
82
|
"build": "tsx ./src/tsbuild.ts",
|
|
83
83
|
"build:watch": "tsx ./src/tsbuild.ts --watch",
|
|
84
|
+
"bench": "tsx ./scripts/benchmark.ts",
|
|
84
85
|
"type-check": "tsx ./src/tsbuild.ts --noEmit",
|
|
85
86
|
"lint": "eslint ./src",
|
|
86
87
|
"test": "vitest run",
|