bunchee 6.7.0 → 6.8.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/README.md +0 -4
- package/dist/bin/cli.js +87 -27
- package/dist/index.d.ts +1 -0
- package/dist/index.js +211 -9
- package/package.json +22 -19
package/README.md
CHANGED
|
@@ -323,10 +323,6 @@ TypeScript-Go (`@typescript/native-preview`) is a high-performance, Go-based imp
|
|
|
323
323
|
|
|
324
324
|
To use TypeScript-Go for type generation, use the `--tsgo` flag:
|
|
325
325
|
|
|
326
|
-
```sh
|
|
327
|
-
bunchee --tsgo
|
|
328
|
-
```
|
|
329
|
-
|
|
330
326
|
**Note**: This requires `@typescript/native-preview` to be installed as a dev dependency. If it's not installed, bunchee will exit with an error.
|
|
331
327
|
|
|
332
328
|
```sh
|
package/dist/bin/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var path = require('path');
|
|
3
|
+
var module$1 = require('module');
|
|
3
4
|
var yargs = require('yargs');
|
|
4
5
|
var helpers = require('yargs/helpers');
|
|
5
6
|
var perf_hooks = require('perf_hooks');
|
|
@@ -8,7 +9,6 @@ var fsp = require('fs/promises');
|
|
|
8
9
|
var require$$0 = require('tty');
|
|
9
10
|
var picomatch = require('picomatch');
|
|
10
11
|
var index_js = require('../index.js');
|
|
11
|
-
require('module');
|
|
12
12
|
var tinyglobby = require('tinyglobby');
|
|
13
13
|
var prettyBytes = require('pretty-bytes');
|
|
14
14
|
var nanospinner = require('nanospinner');
|
|
@@ -647,7 +647,7 @@ function lint$1(pkg) {
|
|
|
647
647
|
}
|
|
648
648
|
}
|
|
649
649
|
|
|
650
|
-
var version = "6.
|
|
650
|
+
var version = "6.8.1";
|
|
651
651
|
|
|
652
652
|
async function writeDefaultTsconfig(tsConfigPath, useTsGo) {
|
|
653
653
|
await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
|
|
@@ -827,7 +827,7 @@ const normalizeBaseNameToExportName = (name)=>{
|
|
|
827
827
|
const baseName = stripeBinaryTag(name);
|
|
828
828
|
return /^\.\/index(\.|$)/.test(baseName) ? '.' : posixRelativify(baseName);
|
|
829
829
|
};
|
|
830
|
-
function createExportCondition(exportName, sourceFile, moduleType) {
|
|
830
|
+
function createExportCondition(exportName, sourceFile, moduleType, esmOnly = false) {
|
|
831
831
|
const isTsSourceFile = isTypescriptFile(sourceFile);
|
|
832
832
|
let cjsExtension = 'js';
|
|
833
833
|
let esmExtension = 'mjs';
|
|
@@ -839,23 +839,31 @@ function createExportCondition(exportName, sourceFile, moduleType) {
|
|
|
839
839
|
exportName = 'index';
|
|
840
840
|
}
|
|
841
841
|
if (isTsSourceFile) {
|
|
842
|
+
const importCondition = {
|
|
843
|
+
types: getDistPath('es', `${exportName}.${dtsExtensionsMap[esmExtension]}`),
|
|
844
|
+
default: getDistPath('es', `${exportName}.${esmExtension}`)
|
|
845
|
+
};
|
|
846
|
+
if (esmOnly) {
|
|
847
|
+
return importCondition;
|
|
848
|
+
}
|
|
842
849
|
return {
|
|
843
|
-
import:
|
|
844
|
-
types: getDistPath('es', `${exportName}.${dtsExtensionsMap[esmExtension]}`),
|
|
845
|
-
default: getDistPath('es', `${exportName}.${esmExtension}`)
|
|
846
|
-
},
|
|
850
|
+
import: importCondition,
|
|
847
851
|
require: {
|
|
848
852
|
types: getDistPath('cjs', `${exportName}.${dtsExtensionsMap[cjsExtension]}`),
|
|
849
853
|
default: getDistPath('cjs', `${exportName}.${cjsExtension}`)
|
|
850
854
|
}
|
|
851
855
|
};
|
|
852
856
|
}
|
|
857
|
+
const importPath = getDistPath(`${exportName}.${esmExtension}`);
|
|
858
|
+
if (esmOnly) {
|
|
859
|
+
return importPath;
|
|
860
|
+
}
|
|
853
861
|
return {
|
|
854
|
-
import:
|
|
862
|
+
import: importPath,
|
|
855
863
|
require: getDistPath(`${exportName}.${cjsExtension}`)
|
|
856
864
|
};
|
|
857
865
|
}
|
|
858
|
-
function createExportConditionPair(exportName, sourceFile, moduleType) {
|
|
866
|
+
function createExportConditionPair(exportName, sourceFile, moduleType, esmOnly = false) {
|
|
859
867
|
// <exportName>.<specialCondition>
|
|
860
868
|
let specialCondition;
|
|
861
869
|
const specialConditionName = getSpecialExportTypeFromComposedExportPath(exportName);
|
|
@@ -873,13 +881,39 @@ function createExportConditionPair(exportName, sourceFile, moduleType) {
|
|
|
873
881
|
specialCondition
|
|
874
882
|
];
|
|
875
883
|
}
|
|
876
|
-
const exportCond = createExportCondition(exportName, sourceFile, moduleType);
|
|
884
|
+
const exportCond = createExportCondition(exportName, sourceFile, moduleType, esmOnly);
|
|
877
885
|
return [
|
|
878
886
|
normalizedExportPath,
|
|
879
887
|
exportCond
|
|
880
888
|
];
|
|
881
889
|
}
|
|
882
|
-
|
|
890
|
+
function detectPackageManager(cwd) {
|
|
891
|
+
if (fs__default.default.existsSync(path__default.default.join(cwd, 'pnpm-lock.yaml'))) {
|
|
892
|
+
return 'pnpm';
|
|
893
|
+
}
|
|
894
|
+
if (fs__default.default.existsSync(path__default.default.join(cwd, 'yarn.lock'))) {
|
|
895
|
+
return 'yarn';
|
|
896
|
+
}
|
|
897
|
+
if (fs__default.default.existsSync(path__default.default.join(cwd, 'package-lock.json'))) {
|
|
898
|
+
return 'npm';
|
|
899
|
+
}
|
|
900
|
+
// Default to npm if no lock file found
|
|
901
|
+
return 'npm';
|
|
902
|
+
}
|
|
903
|
+
function addBuildScripts(pkgJson, cwd) {
|
|
904
|
+
if (!pkgJson.scripts) {
|
|
905
|
+
pkgJson.scripts = {};
|
|
906
|
+
}
|
|
907
|
+
const packageManager = detectPackageManager(cwd);
|
|
908
|
+
const buildCmd = packageManager === 'pnpm' ? 'pnpm build' : `${packageManager} run build`;
|
|
909
|
+
if (!pkgJson.scripts.build) {
|
|
910
|
+
pkgJson.scripts.build = 'bunchee';
|
|
911
|
+
}
|
|
912
|
+
if (!pkgJson.scripts.prepublishOnly) {
|
|
913
|
+
pkgJson.scripts.prepublishOnly = buildCmd;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
async function prepare(cwd, options) {
|
|
883
917
|
const sourceFolder = path__default.default.resolve(cwd, SRC);
|
|
884
918
|
if (!fs__default.default.existsSync(sourceFolder)) {
|
|
885
919
|
logger.error(`Source folder ${sourceFolder} does not exist. Cannot proceed to configure \`exports\` field.`);
|
|
@@ -921,7 +955,8 @@ async function prepare(cwd) {
|
|
|
921
955
|
}
|
|
922
956
|
}
|
|
923
957
|
// Configure as ESM package by default if there's no package.json
|
|
924
|
-
if
|
|
958
|
+
// OR if --esm flag is explicitly set
|
|
959
|
+
if (!hasPackageJson || (options == null ? void 0 : options.esm)) {
|
|
925
960
|
pkgJson.type = 'module';
|
|
926
961
|
}
|
|
927
962
|
if (bins.size > 0) {
|
|
@@ -951,24 +986,40 @@ async function prepare(cwd) {
|
|
|
951
986
|
}
|
|
952
987
|
}
|
|
953
988
|
const pkgExports = {};
|
|
989
|
+
const esmOnly = (options == null ? void 0 : options.esm) === true;
|
|
954
990
|
for (const [exportName, sourceFilesMap] of exportsEntries.entries()){
|
|
955
991
|
for (const sourceFile of Object.values(sourceFilesMap)){
|
|
956
|
-
const [normalizedExportPath, conditions] = createExportConditionPair(exportName, sourceFile, pkgJson.type);
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
992
|
+
const [normalizedExportPath, conditions] = createExportConditionPair(exportName, sourceFile, pkgJson.type, esmOnly);
|
|
993
|
+
// When esmOnly is true, conditions is either a string or an object with types/default (no import/require)
|
|
994
|
+
// When esmOnly is false, conditions is an object with import/require
|
|
995
|
+
if (esmOnly || typeof conditions === 'string' || typeof conditions === 'object' && conditions !== null && !('import' in conditions || 'require' in conditions)) {
|
|
996
|
+
pkgExports[normalizedExportPath] = conditions;
|
|
997
|
+
} else {
|
|
998
|
+
pkgExports[normalizedExportPath] = {
|
|
999
|
+
...conditions,
|
|
1000
|
+
...pkgExports[normalizedExportPath]
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
961
1003
|
}
|
|
962
1004
|
}
|
|
963
1005
|
// Configure node10 module resolution
|
|
964
1006
|
if (exportsEntries.has('./index')) {
|
|
965
1007
|
const isESM = pkgJson.type === 'module';
|
|
966
1008
|
const mainExport = pkgExports['.'];
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1009
|
+
if (esmOnly) {
|
|
1010
|
+
// When esmOnly is true, mainExport is either a string or an object with types/default
|
|
1011
|
+
pkgJson.main = isUsingTs ? typeof mainExport === 'object' ? mainExport.default : mainExport : typeof mainExport === 'string' ? mainExport : mainExport.default;
|
|
1012
|
+
pkgJson.module = isUsingTs ? typeof mainExport === 'object' ? mainExport.default : mainExport : typeof mainExport === 'string' ? mainExport : mainExport.default;
|
|
1013
|
+
if (isUsingTs && typeof mainExport === 'object') {
|
|
1014
|
+
pkgJson.types = mainExport.types;
|
|
1015
|
+
}
|
|
1016
|
+
} else {
|
|
1017
|
+
const mainCondition = isESM ? 'import' : 'require';
|
|
1018
|
+
pkgJson.main = isUsingTs ? mainExport[mainCondition].default : mainExport[mainCondition];
|
|
1019
|
+
pkgJson.module = isUsingTs ? mainExport.import.default : mainExport.import;
|
|
1020
|
+
if (isUsingTs) {
|
|
1021
|
+
pkgJson.types = mainExport[mainCondition].types;
|
|
1022
|
+
}
|
|
972
1023
|
}
|
|
973
1024
|
}
|
|
974
1025
|
// Assign the properties by order: files, main, module, types, exports
|
|
@@ -988,6 +1039,10 @@ async function prepare(cwd) {
|
|
|
988
1039
|
}
|
|
989
1040
|
}
|
|
990
1041
|
}
|
|
1042
|
+
// Additional setup when --esm flag is set
|
|
1043
|
+
if (options == null ? void 0 : options.esm) {
|
|
1044
|
+
addBuildScripts(pkgJson, cwd);
|
|
1045
|
+
}
|
|
991
1046
|
await fsp__default.default.writeFile(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + '\n');
|
|
992
1047
|
logger.info('Configured `exports` in package.json');
|
|
993
1048
|
}
|
|
@@ -1177,8 +1232,15 @@ async function parseCliArgs(argv) {
|
|
|
1177
1232
|
}).option('tsgo', {
|
|
1178
1233
|
type: 'boolean',
|
|
1179
1234
|
description: 'use TypeScript-Go compiler for type generation'
|
|
1180
|
-
}).command('prepare', 'auto configure package.json exports for building', ()=>{
|
|
1181
|
-
return
|
|
1235
|
+
}).command('prepare', 'auto configure package.json exports for building', (yargs)=>{
|
|
1236
|
+
return yargs.option('esm', {
|
|
1237
|
+
type: 'boolean',
|
|
1238
|
+
description: 'configure package as ESM (sets type: "module")'
|
|
1239
|
+
});
|
|
1240
|
+
}, (argv)=>{
|
|
1241
|
+
return prepare(argv.cwd || process.cwd(), {
|
|
1242
|
+
esm: argv.esm
|
|
1243
|
+
});
|
|
1182
1244
|
}).command('lint', 'lint package.json', ()=>{}, (argv)=>{
|
|
1183
1245
|
return lint(argv.cwd || process.cwd());
|
|
1184
1246
|
}).version(version).help('help', 'output usage information').showHelpOnFail(true).parse();
|
|
@@ -1250,9 +1312,7 @@ async function run(args) {
|
|
|
1250
1312
|
if (args.tsgo) {
|
|
1251
1313
|
try {
|
|
1252
1314
|
require.resolve('@typescript/native-preview', {
|
|
1253
|
-
paths:
|
|
1254
|
-
cwd
|
|
1255
|
-
]
|
|
1315
|
+
paths: module$1.Module._nodeModulePaths(cwd)
|
|
1256
1316
|
});
|
|
1257
1317
|
} catch {
|
|
1258
1318
|
exit('--tsgo flag was specified but @typescript/native-preview is not installed. Please install it as a dev dependency: pnpm add -D @typescript/native-preview');
|
package/dist/index.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ type PackageMetadata = {
|
|
|
37
37
|
files?: string[];
|
|
38
38
|
type?: 'commonjs' | 'module';
|
|
39
39
|
dependencies?: Record<string, string>;
|
|
40
|
+
optionalDependencies?: Record<string, string>;
|
|
40
41
|
peerDependencies?: Record<string, string>;
|
|
41
42
|
peerDependenciesMeta?: Record<string, Record<string, string>>;
|
|
42
43
|
exports?: string | Record<string, ExportCondition>;
|
package/dist/index.js
CHANGED
|
@@ -1043,9 +1043,7 @@ function resolveTsGo(cwd) {
|
|
|
1043
1043
|
// Bun does not yet support the `Module` class properly.
|
|
1044
1044
|
if (typeof (m == null ? void 0 : m.require) === 'undefined') {
|
|
1045
1045
|
const tsgoPath = require.resolve('@typescript/native-preview', {
|
|
1046
|
-
paths:
|
|
1047
|
-
cwd
|
|
1048
|
-
]
|
|
1046
|
+
paths: module$1.Module._nodeModulePaths(cwd)
|
|
1049
1047
|
});
|
|
1050
1048
|
tsgo = require(tsgoPath);
|
|
1051
1049
|
} else {
|
|
@@ -1077,9 +1075,7 @@ function resolveTypescript(cwd, useTsGo) {
|
|
|
1077
1075
|
// Bun does not yet support the `Module` class properly.
|
|
1078
1076
|
if (typeof (m == null ? void 0 : m.require) === 'undefined') {
|
|
1079
1077
|
const tsPath = require.resolve('typescript', {
|
|
1080
|
-
paths:
|
|
1081
|
-
cwd
|
|
1082
|
-
]
|
|
1078
|
+
paths: module$1.Module._nodeModulePaths(cwd)
|
|
1083
1079
|
});
|
|
1084
1080
|
ts = require(tsPath);
|
|
1085
1081
|
} else {
|
|
@@ -1375,6 +1371,89 @@ function rawContent({ exclude }) {
|
|
|
1375
1371
|
};
|
|
1376
1372
|
}
|
|
1377
1373
|
|
|
1374
|
+
const NATIVE_ADDON_SUFFIX = '\0native-addon:';
|
|
1375
|
+
/**
|
|
1376
|
+
* Plugin to handle native Node.js addon (.node) files.
|
|
1377
|
+
* Copies the binary to the output directory and rewrites import paths.
|
|
1378
|
+
*/ function nativeAddon() {
|
|
1379
|
+
// Map from virtual module id to original absolute path
|
|
1380
|
+
const nativeAddonMap = new Map();
|
|
1381
|
+
return {
|
|
1382
|
+
name: 'native-addon',
|
|
1383
|
+
resolveId (source, importer) {
|
|
1384
|
+
// Check if this is a .node file import
|
|
1385
|
+
if (!source.endsWith('.node')) {
|
|
1386
|
+
return null;
|
|
1387
|
+
}
|
|
1388
|
+
// Resolve the absolute path of the .node file
|
|
1389
|
+
let absolutePath;
|
|
1390
|
+
if (path__default.default.isAbsolute(source)) {
|
|
1391
|
+
absolutePath = source;
|
|
1392
|
+
} else if (importer) {
|
|
1393
|
+
absolutePath = path__default.default.resolve(path__default.default.dirname(importer), source);
|
|
1394
|
+
} else {
|
|
1395
|
+
return null;
|
|
1396
|
+
}
|
|
1397
|
+
// Create a virtual module id for this native addon
|
|
1398
|
+
const virtualId = NATIVE_ADDON_SUFFIX + absolutePath;
|
|
1399
|
+
// Track the mapping
|
|
1400
|
+
nativeAddonMap.set(virtualId, absolutePath);
|
|
1401
|
+
return virtualId;
|
|
1402
|
+
},
|
|
1403
|
+
async load (id) {
|
|
1404
|
+
if (!id.startsWith(NATIVE_ADDON_SUFFIX)) {
|
|
1405
|
+
return null;
|
|
1406
|
+
}
|
|
1407
|
+
const absolutePath = nativeAddonMap.get(id);
|
|
1408
|
+
if (!absolutePath) {
|
|
1409
|
+
return null;
|
|
1410
|
+
}
|
|
1411
|
+
// Get the filename for the output
|
|
1412
|
+
const fileName = path__default.default.basename(absolutePath);
|
|
1413
|
+
// Return code that will require the binary from the same directory
|
|
1414
|
+
// Using __dirname to get the directory of the output file at runtime
|
|
1415
|
+
return {
|
|
1416
|
+
code: `
|
|
1417
|
+
import { createRequire } from 'module';
|
|
1418
|
+
import { fileURLToPath } from 'url';
|
|
1419
|
+
import { dirname, join } from 'path';
|
|
1420
|
+
|
|
1421
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
1422
|
+
const __dirname = dirname(__filename);
|
|
1423
|
+
const require = createRequire(import.meta.url);
|
|
1424
|
+
|
|
1425
|
+
const nativeAddon = require(join(__dirname, ${JSON.stringify(fileName)}));
|
|
1426
|
+
export default nativeAddon;
|
|
1427
|
+
`,
|
|
1428
|
+
map: null,
|
|
1429
|
+
meta: {
|
|
1430
|
+
nativeAddon: {
|
|
1431
|
+
absolutePath,
|
|
1432
|
+
fileName
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
},
|
|
1437
|
+
async generateBundle () {
|
|
1438
|
+
// Copy all tracked native addon files to the output directory
|
|
1439
|
+
for (const [_, absolutePath] of nativeAddonMap){
|
|
1440
|
+
const fileName = path__default.default.basename(absolutePath);
|
|
1441
|
+
try {
|
|
1442
|
+
const fileContent = await fsp.readFile(absolutePath);
|
|
1443
|
+
// Emit the binary file as an asset
|
|
1444
|
+
this.emitFile({
|
|
1445
|
+
type: 'asset',
|
|
1446
|
+
fileName,
|
|
1447
|
+
source: fileContent
|
|
1448
|
+
});
|
|
1449
|
+
} catch (error) {
|
|
1450
|
+
this.error(`[bunchee] Failed to read native addon file: ${absolutePath}`);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1378
1457
|
function hasNoSpecialCondition(conditionNames) {
|
|
1379
1458
|
return [
|
|
1380
1459
|
...conditionNames
|
|
@@ -1505,6 +1584,51 @@ const prependShebang = (entry)=>({
|
|
|
1505
1584
|
}
|
|
1506
1585
|
});
|
|
1507
1586
|
|
|
1587
|
+
function hasSwcHelpersDeclared(pkg) {
|
|
1588
|
+
var _pkg_dependencies, _pkg_peerDependencies, _pkg_optionalDependencies;
|
|
1589
|
+
return Boolean(((_pkg_dependencies = pkg.dependencies) == null ? void 0 : _pkg_dependencies['@swc/helpers']) || ((_pkg_peerDependencies = pkg.peerDependencies) == null ? void 0 : _pkg_peerDependencies['@swc/helpers']) || ((_pkg_optionalDependencies = pkg.optionalDependencies) == null ? void 0 : _pkg_optionalDependencies['@swc/helpers']));
|
|
1590
|
+
}
|
|
1591
|
+
function isSwcHelpersInstalled(cwd) {
|
|
1592
|
+
try {
|
|
1593
|
+
// Use Node's resolver (supports pnpm/yarn PnP) and resolve from the user's project.
|
|
1594
|
+
const req = module$1.createRequire(path__default.default.join(cwd, 'package.json'));
|
|
1595
|
+
req.resolve('@swc/helpers/package.json');
|
|
1596
|
+
return true;
|
|
1597
|
+
} catch {
|
|
1598
|
+
return false;
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
function chunkUsesSwcHelpers(chunk) {
|
|
1602
|
+
const allImports = chunk.imports.concat(chunk.dynamicImports);
|
|
1603
|
+
return allImports.some((id)=>id === '@swc/helpers' || id.startsWith('@swc/helpers/'));
|
|
1604
|
+
}
|
|
1605
|
+
function swcHelpersWarningPlugin({ cwd, pkg }) {
|
|
1606
|
+
let hasWarned = false;
|
|
1607
|
+
const swcHelpersImportFiles = new Set();
|
|
1608
|
+
return {
|
|
1609
|
+
name: 'bunchee:swc-helpers-warning',
|
|
1610
|
+
writeBundle (options, bundle) {
|
|
1611
|
+
if (hasWarned) return;
|
|
1612
|
+
const outputDir = options.dir || path__default.default.dirname(options.file);
|
|
1613
|
+
for (const [fileName, item] of Object.entries(bundle)){
|
|
1614
|
+
if (item.type !== 'chunk') continue;
|
|
1615
|
+
if (!chunkUsesSwcHelpers(item)) continue;
|
|
1616
|
+
swcHelpersImportFiles.add(path__default.default.relative(cwd, path__default.default.join(outputDir, fileName)));
|
|
1617
|
+
}
|
|
1618
|
+
if (swcHelpersImportFiles.size === 0) return;
|
|
1619
|
+
if (isSwcHelpersInstalled(cwd)) return;
|
|
1620
|
+
hasWarned = true;
|
|
1621
|
+
const exampleFiles = Array.from(swcHelpersImportFiles).slice(0, 3).join(', ');
|
|
1622
|
+
const declaredHint = hasSwcHelpersDeclared(pkg) ? '' : ' (and add it to your dependencies)';
|
|
1623
|
+
logger.warn([
|
|
1624
|
+
`Your build output imports "@swc/helpers" due to transform, but it isn't installed in this project.`,
|
|
1625
|
+
`Install it as a runtime dependency${declaredHint} (e.g. "pnpm add @swc/helpers").`,
|
|
1626
|
+
exampleFiles ? `Detected in: ${exampleFiles}` : ''
|
|
1627
|
+
].filter(Boolean).join('\n'));
|
|
1628
|
+
}
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1508
1632
|
const swcMinifyOptions = {
|
|
1509
1633
|
compress: {
|
|
1510
1634
|
directives: false
|
|
@@ -1553,9 +1677,7 @@ async function createDtsPlugin(tsCompilerOptions, tsConfigPath, respectExternal,
|
|
|
1553
1677
|
try {
|
|
1554
1678
|
// First, try to resolve typescript to get its path
|
|
1555
1679
|
const tsPath = require.resolve('typescript', {
|
|
1556
|
-
paths:
|
|
1557
|
-
cwd
|
|
1558
|
-
]
|
|
1680
|
+
paths: module$1.Module._nodeModulePaths(cwd)
|
|
1559
1681
|
});
|
|
1560
1682
|
// Make ts-go available as 'typescript' for rollup-plugin-dts
|
|
1561
1683
|
// This overrides the module cache so rollup-plugin-dts will use ts-go
|
|
@@ -1677,6 +1799,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
1677
1799
|
rawContent({
|
|
1678
1800
|
exclude: /node_modules/
|
|
1679
1801
|
}),
|
|
1802
|
+
nativeAddon(),
|
|
1680
1803
|
isBinEntry && prependShebang(entry),
|
|
1681
1804
|
replace__default.default({
|
|
1682
1805
|
values: inlineDefinedValues,
|
|
@@ -1701,6 +1824,11 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
1701
1824
|
// For relative paths, the module will be bundled;
|
|
1702
1825
|
// For external libraries, the module will not be bundled.
|
|
1703
1826
|
transformMixedEsModules: true
|
|
1827
|
+
}),
|
|
1828
|
+
// If SWC emits @swc/helpers imports, warn when it's not installed.
|
|
1829
|
+
swcHelpersWarningPlugin({
|
|
1830
|
+
cwd,
|
|
1831
|
+
pkg
|
|
1704
1832
|
})
|
|
1705
1833
|
]).filter(isNotNull);
|
|
1706
1834
|
return {
|
|
@@ -1742,6 +1870,62 @@ function getModuleLayer(moduleMeta) {
|
|
|
1742
1870
|
const moduleLayer = directives[0];
|
|
1743
1871
|
return moduleLayer ? hashTo3Char(moduleLayer) : undefined;
|
|
1744
1872
|
}
|
|
1873
|
+
/**
|
|
1874
|
+
* Get the effective layer of a module by walking up the importer chain.
|
|
1875
|
+
* A module inherits the layer of its importer if it doesn't have its own layer.
|
|
1876
|
+
*/ function getEffectiveModuleLayer(id, getModuleInfo, visited = new Set()) {
|
|
1877
|
+
if (visited.has(id)) {
|
|
1878
|
+
return undefined;
|
|
1879
|
+
}
|
|
1880
|
+
visited.add(id);
|
|
1881
|
+
const moduleInfo = getModuleInfo(id);
|
|
1882
|
+
if (!moduleInfo) {
|
|
1883
|
+
return undefined;
|
|
1884
|
+
}
|
|
1885
|
+
// If this module has its own layer, return it
|
|
1886
|
+
const ownLayer = getModuleLayer(moduleInfo.meta);
|
|
1887
|
+
if (ownLayer) {
|
|
1888
|
+
return ownLayer;
|
|
1889
|
+
}
|
|
1890
|
+
// Otherwise, inherit layer from importers
|
|
1891
|
+
for (const importerId of moduleInfo.importers){
|
|
1892
|
+
const importerLayer = getEffectiveModuleLayer(importerId, getModuleInfo, visited);
|
|
1893
|
+
if (importerLayer) {
|
|
1894
|
+
return importerLayer;
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
return undefined;
|
|
1898
|
+
}
|
|
1899
|
+
/**
|
|
1900
|
+
* Check if a module is imported by modules with different boundary layers.
|
|
1901
|
+
* Returns the set of unique layers if there are multiple, otherwise undefined.
|
|
1902
|
+
*/ function getImporterLayers(id, getModuleInfo) {
|
|
1903
|
+
const moduleInfo = getModuleInfo(id);
|
|
1904
|
+
if (!moduleInfo) {
|
|
1905
|
+
return new Set();
|
|
1906
|
+
}
|
|
1907
|
+
const layers = new Set();
|
|
1908
|
+
for (const importerId of moduleInfo.importers){
|
|
1909
|
+
const importerInfo = getModuleInfo(importerId);
|
|
1910
|
+
if (!importerInfo) {
|
|
1911
|
+
continue;
|
|
1912
|
+
}
|
|
1913
|
+
// Get the importer's own layer first
|
|
1914
|
+
const importerOwnLayer = getModuleLayer(importerInfo.meta);
|
|
1915
|
+
if (importerOwnLayer) {
|
|
1916
|
+
layers.add(importerOwnLayer);
|
|
1917
|
+
} else {
|
|
1918
|
+
// If the importer doesn't have a layer, get its effective layer
|
|
1919
|
+
const effectiveLayer = getEffectiveModuleLayer(importerId, getModuleInfo, new Set([
|
|
1920
|
+
id
|
|
1921
|
+
]));
|
|
1922
|
+
if (effectiveLayer) {
|
|
1923
|
+
layers.add(effectiveLayer);
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
return layers;
|
|
1928
|
+
}
|
|
1745
1929
|
// dependencyGraphMap: Map<subModuleId, Set<entryParentId>>
|
|
1746
1930
|
function createSplitChunks(dependencyGraphMap, entryFiles) {
|
|
1747
1931
|
// If there's existing chunk being splitted, and contains a layer { <id>: <chunkGroup> }
|
|
@@ -1778,6 +1962,24 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
|
|
|
1778
1962
|
}
|
|
1779
1963
|
}
|
|
1780
1964
|
}
|
|
1965
|
+
// Check if this module (without its own directive) is imported by multiple boundaries.
|
|
1966
|
+
// If so, split it into a separate shared chunk to prevent boundary crossing issues.
|
|
1967
|
+
if (!moduleLayer && !isEntry) {
|
|
1968
|
+
const importerLayers = getImporterLayers(id, ctx.getModuleInfo);
|
|
1969
|
+
// If this module is imported by modules with different layers (e.g., both client and server),
|
|
1970
|
+
// split it into a separate chunk that can be safely imported by both boundaries.
|
|
1971
|
+
if (importerLayers.size > 1) {
|
|
1972
|
+
if (splitChunksGroupMap.has(id)) {
|
|
1973
|
+
return splitChunksGroupMap.get(id);
|
|
1974
|
+
}
|
|
1975
|
+
const chunkName = path__default.default.basename(id, path__default.default.extname(id));
|
|
1976
|
+
// Create a unique suffix based on all the layers that import this module
|
|
1977
|
+
const layersSuffix = Array.from(importerLayers).sort().join('-');
|
|
1978
|
+
const chunkGroup = `${chunkName}-${hashTo3Char(layersSuffix)}`;
|
|
1979
|
+
splitChunksGroupMap.set(id, chunkGroup);
|
|
1980
|
+
return chunkGroup;
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1781
1983
|
// If current module has a layer, and it's not an entry
|
|
1782
1984
|
if (moduleLayer && !isEntry) {
|
|
1783
1985
|
// If the module is imported by the entry:
|
package/package.json
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bunchee",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.8.1",
|
|
4
4
|
"description": "zero config bundler for js/ts/jsx libraries",
|
|
5
5
|
"bin": "./dist/bin/cli.js",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"test": "vitest run",
|
|
10
|
+
"test:update": "TEST_UPDATE_SNAPSHOT=1 pnpm test",
|
|
11
|
+
"test:post": "cross-env POST_BUILD=1 pnpm test test/compile.test.ts test/integration.test.ts",
|
|
12
|
+
"site": "next dev docs",
|
|
13
|
+
"docs:build": "next build docs",
|
|
14
|
+
"clean": "rm -rf ./dist",
|
|
15
|
+
"new-test": "node ./scripts/new-test.js",
|
|
16
|
+
"typecheck": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
|
|
17
|
+
"prepare-release": "pnpm clean && pnpm build",
|
|
18
|
+
"publish-local": "pnpm prepare-release && pnpm test && pnpm publish",
|
|
19
|
+
"prepublishOnly": "pnpm prepare-release && chmod +x ./dist/bin/cli.js",
|
|
20
|
+
"run-ts": "cross-env SWC_NODE_IGNORE_DYNAMIC=1 node -r @swc-node/register",
|
|
21
|
+
"ts-bunchee": "pnpm run-ts ./src/bin/index.ts",
|
|
22
|
+
"build-dir": "pnpm ts-bunchee --cwd",
|
|
23
|
+
"build": "pnpm run-ts ./src/bin/index.ts --runtime node",
|
|
24
|
+
"format": "prettier --write .",
|
|
25
|
+
"prepare": "husky"
|
|
26
|
+
},
|
|
8
27
|
"type": "commonjs",
|
|
9
28
|
"keywords": [
|
|
10
29
|
"bundler",
|
|
@@ -101,21 +120,5 @@
|
|
|
101
120
|
"lint-staged": {
|
|
102
121
|
"*.{js,jsx,ts,tsx,md,json,yml,yaml}": "prettier --write"
|
|
103
122
|
},
|
|
104
|
-
"
|
|
105
|
-
|
|
106
|
-
"test:update": "TEST_UPDATE_SNAPSHOT=1 pnpm test",
|
|
107
|
-
"test:post": "cross-env POST_BUILD=1 pnpm test test/compile.test.ts test/integration.test.ts",
|
|
108
|
-
"site": "next dev docs",
|
|
109
|
-
"docs:build": "next build docs",
|
|
110
|
-
"clean": "rm -rf ./dist",
|
|
111
|
-
"new-test": "node ./scripts/new-test.js",
|
|
112
|
-
"typecheck": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
|
|
113
|
-
"prepare-release": "pnpm clean && pnpm build",
|
|
114
|
-
"publish-local": "pnpm prepare-release && pnpm test && pnpm publish",
|
|
115
|
-
"run-ts": "cross-env SWC_NODE_IGNORE_DYNAMIC=1 node -r @swc-node/register",
|
|
116
|
-
"ts-bunchee": "pnpm run-ts ./src/bin/index.ts",
|
|
117
|
-
"build-dir": "pnpm ts-bunchee --cwd",
|
|
118
|
-
"build": "pnpm run-ts ./src/bin/index.ts --runtime node",
|
|
119
|
-
"format": "prettier --write ."
|
|
120
|
-
}
|
|
121
|
-
}
|
|
123
|
+
"packageManager": "pnpm@9.4.0"
|
|
124
|
+
}
|