bunchee 6.7.0 → 6.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +100 -38
- package/dist/index.d.ts +1 -0
- package/dist/index.js +208 -0
- package/package.json +22 -19
package/dist/bin/cli.js
CHANGED
|
@@ -437,13 +437,13 @@ function validateFilesField(packageJson) {
|
|
|
437
437
|
'*'
|
|
438
438
|
];
|
|
439
439
|
const exportsField = packageJson.exports || {};
|
|
440
|
-
const resolveExportsPaths = (exports)=>{
|
|
440
|
+
const resolveExportsPaths = (exports$1)=>{
|
|
441
441
|
const paths = [];
|
|
442
|
-
if (typeof exports === 'string') {
|
|
443
|
-
paths.push(exports);
|
|
444
|
-
} else if (typeof exports === 'object') {
|
|
445
|
-
for(const key in exports){
|
|
446
|
-
paths.push(...resolveExportsPaths(exports[key]));
|
|
442
|
+
if (typeof exports$1 === 'string') {
|
|
443
|
+
paths.push(exports$1);
|
|
444
|
+
} else if (typeof exports$1 === 'object') {
|
|
445
|
+
for(const key in exports$1){
|
|
446
|
+
paths.push(...resolveExportsPaths(exports$1[key]));
|
|
447
447
|
}
|
|
448
448
|
}
|
|
449
449
|
return paths;
|
|
@@ -470,7 +470,7 @@ function validateFilesField(packageJson) {
|
|
|
470
470
|
return state;
|
|
471
471
|
}
|
|
472
472
|
function lint$1(pkg) {
|
|
473
|
-
const { name, main, exports } = pkg;
|
|
473
|
+
const { name, main, exports: exports$1 } = pkg;
|
|
474
474
|
const isESM = isESModulePackage(pkg.type);
|
|
475
475
|
const parsedExports = parseExports(pkg);
|
|
476
476
|
if (!name) {
|
|
@@ -500,12 +500,12 @@ function lint$1(pkg) {
|
|
|
500
500
|
};
|
|
501
501
|
// Validate ESM package
|
|
502
502
|
if (isESM) {
|
|
503
|
-
if (exports) {
|
|
504
|
-
if (typeof exports === 'string') {
|
|
505
|
-
if (hasCjsExtension(exports)) {
|
|
503
|
+
if (exports$1) {
|
|
504
|
+
if (typeof exports$1 === 'string') {
|
|
505
|
+
if (hasCjsExtension(exports$1)) {
|
|
506
506
|
exportsState.badMainExport = true;
|
|
507
507
|
}
|
|
508
|
-
} else if (typeof exports !== 'object') {
|
|
508
|
+
} else if (typeof exports$1 !== 'object') {
|
|
509
509
|
exportsState.invalidExportsFieldType = true;
|
|
510
510
|
} else {
|
|
511
511
|
parsedExports.forEach((outputPairs)=>{
|
|
@@ -548,12 +548,12 @@ function lint$1(pkg) {
|
|
|
548
548
|
if (main && path__default.default.extname(main) === '.mjs') {
|
|
549
549
|
exportsState.badMainExtension = true;
|
|
550
550
|
}
|
|
551
|
-
if (exports) {
|
|
552
|
-
if (typeof exports === 'string') {
|
|
553
|
-
if (path__default.default.extname(exports) === '.mjs') {
|
|
551
|
+
if (exports$1) {
|
|
552
|
+
if (typeof exports$1 === 'string') {
|
|
553
|
+
if (path__default.default.extname(exports$1) === '.mjs') {
|
|
554
554
|
exportsState.badMainExport = true;
|
|
555
555
|
}
|
|
556
|
-
} else if (typeof exports !== 'object') {
|
|
556
|
+
} else if (typeof exports$1 !== 'object') {
|
|
557
557
|
exportsState.invalidExportsFieldType = true;
|
|
558
558
|
} else {
|
|
559
559
|
parsedExports.forEach((outputPairs)=>{
|
|
@@ -647,7 +647,7 @@ function lint$1(pkg) {
|
|
|
647
647
|
}
|
|
648
648
|
}
|
|
649
649
|
|
|
650
|
-
var version = "6.
|
|
650
|
+
var version = "6.8.0";
|
|
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();
|
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
|
@@ -1375,6 +1375,89 @@ function rawContent({ exclude }) {
|
|
|
1375
1375
|
};
|
|
1376
1376
|
}
|
|
1377
1377
|
|
|
1378
|
+
const NATIVE_ADDON_SUFFIX = '\0native-addon:';
|
|
1379
|
+
/**
|
|
1380
|
+
* Plugin to handle native Node.js addon (.node) files.
|
|
1381
|
+
* Copies the binary to the output directory and rewrites import paths.
|
|
1382
|
+
*/ function nativeAddon() {
|
|
1383
|
+
// Map from virtual module id to original absolute path
|
|
1384
|
+
const nativeAddonMap = new Map();
|
|
1385
|
+
return {
|
|
1386
|
+
name: 'native-addon',
|
|
1387
|
+
resolveId (source, importer) {
|
|
1388
|
+
// Check if this is a .node file import
|
|
1389
|
+
if (!source.endsWith('.node')) {
|
|
1390
|
+
return null;
|
|
1391
|
+
}
|
|
1392
|
+
// Resolve the absolute path of the .node file
|
|
1393
|
+
let absolutePath;
|
|
1394
|
+
if (path__default.default.isAbsolute(source)) {
|
|
1395
|
+
absolutePath = source;
|
|
1396
|
+
} else if (importer) {
|
|
1397
|
+
absolutePath = path__default.default.resolve(path__default.default.dirname(importer), source);
|
|
1398
|
+
} else {
|
|
1399
|
+
return null;
|
|
1400
|
+
}
|
|
1401
|
+
// Create a virtual module id for this native addon
|
|
1402
|
+
const virtualId = NATIVE_ADDON_SUFFIX + absolutePath;
|
|
1403
|
+
// Track the mapping
|
|
1404
|
+
nativeAddonMap.set(virtualId, absolutePath);
|
|
1405
|
+
return virtualId;
|
|
1406
|
+
},
|
|
1407
|
+
async load (id) {
|
|
1408
|
+
if (!id.startsWith(NATIVE_ADDON_SUFFIX)) {
|
|
1409
|
+
return null;
|
|
1410
|
+
}
|
|
1411
|
+
const absolutePath = nativeAddonMap.get(id);
|
|
1412
|
+
if (!absolutePath) {
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
// Get the filename for the output
|
|
1416
|
+
const fileName = path__default.default.basename(absolutePath);
|
|
1417
|
+
// Return code that will require the binary from the same directory
|
|
1418
|
+
// Using __dirname to get the directory of the output file at runtime
|
|
1419
|
+
return {
|
|
1420
|
+
code: `
|
|
1421
|
+
import { createRequire } from 'module';
|
|
1422
|
+
import { fileURLToPath } from 'url';
|
|
1423
|
+
import { dirname, join } from 'path';
|
|
1424
|
+
|
|
1425
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
1426
|
+
const __dirname = dirname(__filename);
|
|
1427
|
+
const require = createRequire(import.meta.url);
|
|
1428
|
+
|
|
1429
|
+
const nativeAddon = require(join(__dirname, ${JSON.stringify(fileName)}));
|
|
1430
|
+
export default nativeAddon;
|
|
1431
|
+
`,
|
|
1432
|
+
map: null,
|
|
1433
|
+
meta: {
|
|
1434
|
+
nativeAddon: {
|
|
1435
|
+
absolutePath,
|
|
1436
|
+
fileName
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
};
|
|
1440
|
+
},
|
|
1441
|
+
async generateBundle () {
|
|
1442
|
+
// Copy all tracked native addon files to the output directory
|
|
1443
|
+
for (const [_, absolutePath] of nativeAddonMap){
|
|
1444
|
+
const fileName = path__default.default.basename(absolutePath);
|
|
1445
|
+
try {
|
|
1446
|
+
const fileContent = await fsp.readFile(absolutePath);
|
|
1447
|
+
// Emit the binary file as an asset
|
|
1448
|
+
this.emitFile({
|
|
1449
|
+
type: 'asset',
|
|
1450
|
+
fileName,
|
|
1451
|
+
source: fileContent
|
|
1452
|
+
});
|
|
1453
|
+
} catch (error) {
|
|
1454
|
+
this.error(`[bunchee] Failed to read native addon file: ${absolutePath}`);
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1378
1461
|
function hasNoSpecialCondition(conditionNames) {
|
|
1379
1462
|
return [
|
|
1380
1463
|
...conditionNames
|
|
@@ -1505,6 +1588,51 @@ const prependShebang = (entry)=>({
|
|
|
1505
1588
|
}
|
|
1506
1589
|
});
|
|
1507
1590
|
|
|
1591
|
+
function hasSwcHelpersDeclared(pkg) {
|
|
1592
|
+
var _pkg_dependencies, _pkg_peerDependencies, _pkg_optionalDependencies;
|
|
1593
|
+
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']));
|
|
1594
|
+
}
|
|
1595
|
+
function isSwcHelpersInstalled(cwd) {
|
|
1596
|
+
try {
|
|
1597
|
+
// Use Node's resolver (supports pnpm/yarn PnP) and resolve from the user's project.
|
|
1598
|
+
const req = module$1.createRequire(path__default.default.join(cwd, 'package.json'));
|
|
1599
|
+
req.resolve('@swc/helpers/package.json');
|
|
1600
|
+
return true;
|
|
1601
|
+
} catch {
|
|
1602
|
+
return false;
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
function chunkUsesSwcHelpers(chunk) {
|
|
1606
|
+
const allImports = chunk.imports.concat(chunk.dynamicImports);
|
|
1607
|
+
return allImports.some((id)=>id === '@swc/helpers' || id.startsWith('@swc/helpers/'));
|
|
1608
|
+
}
|
|
1609
|
+
function swcHelpersWarningPlugin({ cwd, pkg }) {
|
|
1610
|
+
let hasWarned = false;
|
|
1611
|
+
const swcHelpersImportFiles = new Set();
|
|
1612
|
+
return {
|
|
1613
|
+
name: 'bunchee:swc-helpers-warning',
|
|
1614
|
+
writeBundle (options, bundle) {
|
|
1615
|
+
if (hasWarned) return;
|
|
1616
|
+
const outputDir = options.dir || path__default.default.dirname(options.file);
|
|
1617
|
+
for (const [fileName, item] of Object.entries(bundle)){
|
|
1618
|
+
if (item.type !== 'chunk') continue;
|
|
1619
|
+
if (!chunkUsesSwcHelpers(item)) continue;
|
|
1620
|
+
swcHelpersImportFiles.add(path__default.default.relative(cwd, path__default.default.join(outputDir, fileName)));
|
|
1621
|
+
}
|
|
1622
|
+
if (swcHelpersImportFiles.size === 0) return;
|
|
1623
|
+
if (isSwcHelpersInstalled(cwd)) return;
|
|
1624
|
+
hasWarned = true;
|
|
1625
|
+
const exampleFiles = Array.from(swcHelpersImportFiles).slice(0, 3).join(', ');
|
|
1626
|
+
const declaredHint = hasSwcHelpersDeclared(pkg) ? '' : ' (and add it to your dependencies)';
|
|
1627
|
+
logger.warn([
|
|
1628
|
+
`Your build output imports "@swc/helpers" due to transform, but it isn't installed in this project.`,
|
|
1629
|
+
`Install it as a runtime dependency${declaredHint} (e.g. "pnpm add @swc/helpers").`,
|
|
1630
|
+
exampleFiles ? `Detected in: ${exampleFiles}` : ''
|
|
1631
|
+
].filter(Boolean).join('\n'));
|
|
1632
|
+
}
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1508
1636
|
const swcMinifyOptions = {
|
|
1509
1637
|
compress: {
|
|
1510
1638
|
directives: false
|
|
@@ -1677,6 +1805,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
1677
1805
|
rawContent({
|
|
1678
1806
|
exclude: /node_modules/
|
|
1679
1807
|
}),
|
|
1808
|
+
nativeAddon(),
|
|
1680
1809
|
isBinEntry && prependShebang(entry),
|
|
1681
1810
|
replace__default.default({
|
|
1682
1811
|
values: inlineDefinedValues,
|
|
@@ -1701,6 +1830,11 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
1701
1830
|
// For relative paths, the module will be bundled;
|
|
1702
1831
|
// For external libraries, the module will not be bundled.
|
|
1703
1832
|
transformMixedEsModules: true
|
|
1833
|
+
}),
|
|
1834
|
+
// If SWC emits @swc/helpers imports, warn when it's not installed.
|
|
1835
|
+
swcHelpersWarningPlugin({
|
|
1836
|
+
cwd,
|
|
1837
|
+
pkg
|
|
1704
1838
|
})
|
|
1705
1839
|
]).filter(isNotNull);
|
|
1706
1840
|
return {
|
|
@@ -1742,6 +1876,62 @@ function getModuleLayer(moduleMeta) {
|
|
|
1742
1876
|
const moduleLayer = directives[0];
|
|
1743
1877
|
return moduleLayer ? hashTo3Char(moduleLayer) : undefined;
|
|
1744
1878
|
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Get the effective layer of a module by walking up the importer chain.
|
|
1881
|
+
* A module inherits the layer of its importer if it doesn't have its own layer.
|
|
1882
|
+
*/ function getEffectiveModuleLayer(id, getModuleInfo, visited = new Set()) {
|
|
1883
|
+
if (visited.has(id)) {
|
|
1884
|
+
return undefined;
|
|
1885
|
+
}
|
|
1886
|
+
visited.add(id);
|
|
1887
|
+
const moduleInfo = getModuleInfo(id);
|
|
1888
|
+
if (!moduleInfo) {
|
|
1889
|
+
return undefined;
|
|
1890
|
+
}
|
|
1891
|
+
// If this module has its own layer, return it
|
|
1892
|
+
const ownLayer = getModuleLayer(moduleInfo.meta);
|
|
1893
|
+
if (ownLayer) {
|
|
1894
|
+
return ownLayer;
|
|
1895
|
+
}
|
|
1896
|
+
// Otherwise, inherit layer from importers
|
|
1897
|
+
for (const importerId of moduleInfo.importers){
|
|
1898
|
+
const importerLayer = getEffectiveModuleLayer(importerId, getModuleInfo, visited);
|
|
1899
|
+
if (importerLayer) {
|
|
1900
|
+
return importerLayer;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
return undefined;
|
|
1904
|
+
}
|
|
1905
|
+
/**
|
|
1906
|
+
* Check if a module is imported by modules with different boundary layers.
|
|
1907
|
+
* Returns the set of unique layers if there are multiple, otherwise undefined.
|
|
1908
|
+
*/ function getImporterLayers(id, getModuleInfo) {
|
|
1909
|
+
const moduleInfo = getModuleInfo(id);
|
|
1910
|
+
if (!moduleInfo) {
|
|
1911
|
+
return new Set();
|
|
1912
|
+
}
|
|
1913
|
+
const layers = new Set();
|
|
1914
|
+
for (const importerId of moduleInfo.importers){
|
|
1915
|
+
const importerInfo = getModuleInfo(importerId);
|
|
1916
|
+
if (!importerInfo) {
|
|
1917
|
+
continue;
|
|
1918
|
+
}
|
|
1919
|
+
// Get the importer's own layer first
|
|
1920
|
+
const importerOwnLayer = getModuleLayer(importerInfo.meta);
|
|
1921
|
+
if (importerOwnLayer) {
|
|
1922
|
+
layers.add(importerOwnLayer);
|
|
1923
|
+
} else {
|
|
1924
|
+
// If the importer doesn't have a layer, get its effective layer
|
|
1925
|
+
const effectiveLayer = getEffectiveModuleLayer(importerId, getModuleInfo, new Set([
|
|
1926
|
+
id
|
|
1927
|
+
]));
|
|
1928
|
+
if (effectiveLayer) {
|
|
1929
|
+
layers.add(effectiveLayer);
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
return layers;
|
|
1934
|
+
}
|
|
1745
1935
|
// dependencyGraphMap: Map<subModuleId, Set<entryParentId>>
|
|
1746
1936
|
function createSplitChunks(dependencyGraphMap, entryFiles) {
|
|
1747
1937
|
// If there's existing chunk being splitted, and contains a layer { <id>: <chunkGroup> }
|
|
@@ -1778,6 +1968,24 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
|
|
|
1778
1968
|
}
|
|
1779
1969
|
}
|
|
1780
1970
|
}
|
|
1971
|
+
// Check if this module (without its own directive) is imported by multiple boundaries.
|
|
1972
|
+
// If so, split it into a separate shared chunk to prevent boundary crossing issues.
|
|
1973
|
+
if (!moduleLayer && !isEntry) {
|
|
1974
|
+
const importerLayers = getImporterLayers(id, ctx.getModuleInfo);
|
|
1975
|
+
// If this module is imported by modules with different layers (e.g., both client and server),
|
|
1976
|
+
// split it into a separate chunk that can be safely imported by both boundaries.
|
|
1977
|
+
if (importerLayers.size > 1) {
|
|
1978
|
+
if (splitChunksGroupMap.has(id)) {
|
|
1979
|
+
return splitChunksGroupMap.get(id);
|
|
1980
|
+
}
|
|
1981
|
+
const chunkName = path__default.default.basename(id, path__default.default.extname(id));
|
|
1982
|
+
// Create a unique suffix based on all the layers that import this module
|
|
1983
|
+
const layersSuffix = Array.from(importerLayers).sort().join('-');
|
|
1984
|
+
const chunkGroup = `${chunkName}-${hashTo3Char(layersSuffix)}`;
|
|
1985
|
+
splitChunksGroupMap.set(id, chunkGroup);
|
|
1986
|
+
return chunkGroup;
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1781
1989
|
// If current module has a layer, and it's not an entry
|
|
1782
1990
|
if (moduleLayer && !isEntry) {
|
|
1783
1991
|
// 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.0",
|
|
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
|
+
}
|