bunchee 6.6.2 → 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/README.md +26 -0
- package/dist/bin/cli.js +129 -45
- package/dist/index.d.ts +2 -0
- package/dist/index.js +309 -15
- package/package.json +33 -25
package/README.md
CHANGED
|
@@ -317,6 +317,23 @@ bunchee --no-external
|
|
|
317
317
|
|
|
318
318
|
This will include all dependencies within your output bundle.
|
|
319
319
|
|
|
320
|
+
#### TypeScript-Go Compiler
|
|
321
|
+
|
|
322
|
+
TypeScript-Go (`@typescript/native-preview`) is a high-performance, Go-based implementation of the TypeScript compiler that can significantly speed up type declaration file generation.
|
|
323
|
+
|
|
324
|
+
To use TypeScript-Go for type generation, use the `--tsgo` flag:
|
|
325
|
+
|
|
326
|
+
```sh
|
|
327
|
+
bunchee --tsgo
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**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
|
+
|
|
332
|
+
```sh
|
|
333
|
+
pnpm add -D bunchee @typescript/native-preview
|
|
334
|
+
bunchee --tsgo
|
|
335
|
+
```
|
|
336
|
+
|
|
320
337
|
#### Build Successful Command
|
|
321
338
|
|
|
322
339
|
A command to be executed after a build is successful can be specified using the `--success` option, which is useful for development watching mode:
|
|
@@ -365,6 +382,14 @@ Then use use the [exports field in package.json](https://nodejs.org/api/packages
|
|
|
365
382
|
|
|
366
383
|
If you're building a TypeScript library, separate the types from the main entry file and specify the types path in package.json. Types exports need to stay on the top of each export with `types` condition, and you can use `default` condition for the JS bundle file.
|
|
367
384
|
|
|
385
|
+
**bunchee** supports using the TypeScript-Go compiler (`@typescript/native-preview`) for faster type generation. To enable it, use the `--tsgo` flag:
|
|
386
|
+
|
|
387
|
+
```sh
|
|
388
|
+
bunchee --tsgo
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
Note: This requires `@typescript/native-preview` to be installed as a dev dependency. If it's not installed, bunchee will fall back to the regular TypeScript compiler with a warning.
|
|
392
|
+
|
|
368
393
|
```json5
|
|
369
394
|
{
|
|
370
395
|
"files": ["dist"],
|
|
@@ -545,6 +570,7 @@ await bundle(path.resolve('./src/index.ts'), {
|
|
|
545
570
|
cwd: process.cwd(), // string
|
|
546
571
|
clean: true, // boolean
|
|
547
572
|
tsconfig: 'tsconfig.json', // string
|
|
573
|
+
tsgo: false, // Boolean - use TypeScript-Go compiler for type generation
|
|
548
574
|
})
|
|
549
575
|
```
|
|
550
576
|
|
package/dist/bin/cli.js
CHANGED
|
@@ -198,7 +198,7 @@ function validateEntryFiles(entryFiles) {
|
|
|
198
198
|
|
|
199
199
|
function exit(err) {
|
|
200
200
|
logger.error(err);
|
|
201
|
-
|
|
201
|
+
throw typeof err === 'string' ? new Error(err) : err;
|
|
202
202
|
}
|
|
203
203
|
function hasPackageJson(cwd) {
|
|
204
204
|
return fileExists(path__default.default.resolve(cwd, 'package.json'));
|
|
@@ -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,11 +647,12 @@ function lint$1(pkg) {
|
|
|
647
647
|
}
|
|
648
648
|
}
|
|
649
649
|
|
|
650
|
-
var version = "6.
|
|
650
|
+
var version = "6.8.0";
|
|
651
651
|
|
|
652
|
-
async function writeDefaultTsconfig(tsConfigPath) {
|
|
652
|
+
async function writeDefaultTsconfig(tsConfigPath, useTsGo) {
|
|
653
653
|
await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
|
|
654
|
-
|
|
654
|
+
const compilerName = 'TypeScript';
|
|
655
|
+
logger.log(`Detected using ${compilerName} but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
|
|
655
656
|
}
|
|
656
657
|
|
|
657
658
|
// ./index -> default
|
|
@@ -826,7 +827,7 @@ const normalizeBaseNameToExportName = (name)=>{
|
|
|
826
827
|
const baseName = stripeBinaryTag(name);
|
|
827
828
|
return /^\.\/index(\.|$)/.test(baseName) ? '.' : posixRelativify(baseName);
|
|
828
829
|
};
|
|
829
|
-
function createExportCondition(exportName, sourceFile, moduleType) {
|
|
830
|
+
function createExportCondition(exportName, sourceFile, moduleType, esmOnly = false) {
|
|
830
831
|
const isTsSourceFile = isTypescriptFile(sourceFile);
|
|
831
832
|
let cjsExtension = 'js';
|
|
832
833
|
let esmExtension = 'mjs';
|
|
@@ -838,23 +839,31 @@ function createExportCondition(exportName, sourceFile, moduleType) {
|
|
|
838
839
|
exportName = 'index';
|
|
839
840
|
}
|
|
840
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
|
+
}
|
|
841
849
|
return {
|
|
842
|
-
import:
|
|
843
|
-
types: getDistPath('es', `${exportName}.${dtsExtensionsMap[esmExtension]}`),
|
|
844
|
-
default: getDistPath('es', `${exportName}.${esmExtension}`)
|
|
845
|
-
},
|
|
850
|
+
import: importCondition,
|
|
846
851
|
require: {
|
|
847
852
|
types: getDistPath('cjs', `${exportName}.${dtsExtensionsMap[cjsExtension]}`),
|
|
848
853
|
default: getDistPath('cjs', `${exportName}.${cjsExtension}`)
|
|
849
854
|
}
|
|
850
855
|
};
|
|
851
856
|
}
|
|
857
|
+
const importPath = getDistPath(`${exportName}.${esmExtension}`);
|
|
858
|
+
if (esmOnly) {
|
|
859
|
+
return importPath;
|
|
860
|
+
}
|
|
852
861
|
return {
|
|
853
|
-
import:
|
|
862
|
+
import: importPath,
|
|
854
863
|
require: getDistPath(`${exportName}.${cjsExtension}`)
|
|
855
864
|
};
|
|
856
865
|
}
|
|
857
|
-
function createExportConditionPair(exportName, sourceFile, moduleType) {
|
|
866
|
+
function createExportConditionPair(exportName, sourceFile, moduleType, esmOnly = false) {
|
|
858
867
|
// <exportName>.<specialCondition>
|
|
859
868
|
let specialCondition;
|
|
860
869
|
const specialConditionName = getSpecialExportTypeFromComposedExportPath(exportName);
|
|
@@ -872,13 +881,39 @@ function createExportConditionPair(exportName, sourceFile, moduleType) {
|
|
|
872
881
|
specialCondition
|
|
873
882
|
];
|
|
874
883
|
}
|
|
875
|
-
const exportCond = createExportCondition(exportName, sourceFile, moduleType);
|
|
884
|
+
const exportCond = createExportCondition(exportName, sourceFile, moduleType, esmOnly);
|
|
876
885
|
return [
|
|
877
886
|
normalizedExportPath,
|
|
878
887
|
exportCond
|
|
879
888
|
];
|
|
880
889
|
}
|
|
881
|
-
|
|
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) {
|
|
882
917
|
const sourceFolder = path__default.default.resolve(cwd, SRC);
|
|
883
918
|
if (!fs__default.default.existsSync(sourceFolder)) {
|
|
884
919
|
logger.error(`Source folder ${sourceFolder} does not exist. Cannot proceed to configure \`exports\` field.`);
|
|
@@ -920,7 +955,8 @@ async function prepare(cwd) {
|
|
|
920
955
|
}
|
|
921
956
|
}
|
|
922
957
|
// Configure as ESM package by default if there's no package.json
|
|
923
|
-
if
|
|
958
|
+
// OR if --esm flag is explicitly set
|
|
959
|
+
if (!hasPackageJson || (options == null ? void 0 : options.esm)) {
|
|
924
960
|
pkgJson.type = 'module';
|
|
925
961
|
}
|
|
926
962
|
if (bins.size > 0) {
|
|
@@ -950,24 +986,40 @@ async function prepare(cwd) {
|
|
|
950
986
|
}
|
|
951
987
|
}
|
|
952
988
|
const pkgExports = {};
|
|
989
|
+
const esmOnly = (options == null ? void 0 : options.esm) === true;
|
|
953
990
|
for (const [exportName, sourceFilesMap] of exportsEntries.entries()){
|
|
954
991
|
for (const sourceFile of Object.values(sourceFilesMap)){
|
|
955
|
-
const [normalizedExportPath, conditions] = createExportConditionPair(exportName, sourceFile, pkgJson.type);
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
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
|
+
}
|
|
960
1003
|
}
|
|
961
1004
|
}
|
|
962
1005
|
// Configure node10 module resolution
|
|
963
1006
|
if (exportsEntries.has('./index')) {
|
|
964
1007
|
const isESM = pkgJson.type === 'module';
|
|
965
1008
|
const mainExport = pkgExports['.'];
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
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
|
+
}
|
|
971
1023
|
}
|
|
972
1024
|
}
|
|
973
1025
|
// Assign the properties by order: files, main, module, types, exports
|
|
@@ -987,6 +1039,10 @@ async function prepare(cwd) {
|
|
|
987
1039
|
}
|
|
988
1040
|
}
|
|
989
1041
|
}
|
|
1042
|
+
// Additional setup when --esm flag is set
|
|
1043
|
+
if (options == null ? void 0 : options.esm) {
|
|
1044
|
+
addBuildScripts(pkgJson, cwd);
|
|
1045
|
+
}
|
|
990
1046
|
await fsp__default.default.writeFile(pkgJsonPath, JSON.stringify(pkgJson, null, 2) + '\n');
|
|
991
1047
|
logger.info('Configured `exports` in package.json');
|
|
992
1048
|
}
|
|
@@ -1082,7 +1138,7 @@ Options:
|
|
|
1082
1138
|
-o, --output <file> specify output filename
|
|
1083
1139
|
-f, --format <format> type of output (esm, amd, cjs, iife, umd, system), default: esm
|
|
1084
1140
|
-h, --help output usage information
|
|
1085
|
-
|
|
1141
|
+
|
|
1086
1142
|
--external <mod> specify an external dependency, separate by comma
|
|
1087
1143
|
--no-external do not bundle external dependencies
|
|
1088
1144
|
--no-clean do not clean dist folder before building, default: false
|
|
@@ -1095,6 +1151,7 @@ Options:
|
|
|
1095
1151
|
--tsconfig path to tsconfig file, default: tsconfig.json
|
|
1096
1152
|
--dts-bundle bundle type declaration files, default: false
|
|
1097
1153
|
--success <cmd> run command after build success
|
|
1154
|
+
--tsgo use TypeScript-Go compiler for type generation
|
|
1098
1155
|
`;
|
|
1099
1156
|
function help() {
|
|
1100
1157
|
logger.log(helpMessage);
|
|
@@ -1172,8 +1229,18 @@ async function parseCliArgs(argv) {
|
|
|
1172
1229
|
}).option('success', {
|
|
1173
1230
|
type: 'string',
|
|
1174
1231
|
description: 'run command after build success'
|
|
1175
|
-
}).
|
|
1176
|
-
|
|
1232
|
+
}).option('tsgo', {
|
|
1233
|
+
type: 'boolean',
|
|
1234
|
+
description: 'use TypeScript-Go compiler for type generation'
|
|
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
|
+
});
|
|
1177
1244
|
}).command('lint', 'lint package.json', ()=>{}, (argv)=>{
|
|
1178
1245
|
return lint(argv.cwd || process.cwd());
|
|
1179
1246
|
}).version(version).help('help', 'output usage information').showHelpOnFail(true).parse();
|
|
@@ -1207,7 +1274,8 @@ async function parseCliArgs(argv) {
|
|
|
1207
1274
|
clean: args['clean'] !== false,
|
|
1208
1275
|
env: args['env'],
|
|
1209
1276
|
tsconfig: args['tsconfig'],
|
|
1210
|
-
onSuccess: args['success']
|
|
1277
|
+
onSuccess: args['success'],
|
|
1278
|
+
tsgo: args['tsgo']
|
|
1211
1279
|
};
|
|
1212
1280
|
// When minify is enabled, sourcemap should be enabled by default, unless explicitly opted out
|
|
1213
1281
|
if (parsedArgs.minify && typeof args['sourcemap'] === 'undefined') {
|
|
@@ -1236,9 +1304,22 @@ async function run(args) {
|
|
|
1236
1304
|
env: (env == null ? void 0 : env.split(',')) || [],
|
|
1237
1305
|
clean,
|
|
1238
1306
|
tsconfig,
|
|
1239
|
-
onSuccess
|
|
1307
|
+
onSuccess,
|
|
1308
|
+
tsgo: args.tsgo
|
|
1240
1309
|
};
|
|
1241
1310
|
const cliEntry = source ? path__default.default.resolve(cwd, source) : '';
|
|
1311
|
+
// Check if ts-go is available when requested (before any build operations)
|
|
1312
|
+
if (args.tsgo) {
|
|
1313
|
+
try {
|
|
1314
|
+
require.resolve('@typescript/native-preview', {
|
|
1315
|
+
paths: [
|
|
1316
|
+
cwd
|
|
1317
|
+
]
|
|
1318
|
+
});
|
|
1319
|
+
} catch {
|
|
1320
|
+
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');
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1242
1323
|
// lint package by default
|
|
1243
1324
|
await lint(cwd);
|
|
1244
1325
|
const spinnerInstance = process.stdout.isTTY ? nanospinner.createSpinner('Building...\n\n', {
|
|
@@ -1389,4 +1470,7 @@ function logError(err) {
|
|
|
1389
1470
|
const error = normalizeError(err);
|
|
1390
1471
|
logger.error(error);
|
|
1391
1472
|
}
|
|
1392
|
-
main().catch(
|
|
1473
|
+
main().catch((error)=>{
|
|
1474
|
+
logError(error);
|
|
1475
|
+
process.exit(1);
|
|
1476
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ type BundleConfig = {
|
|
|
22
22
|
clean?: boolean;
|
|
23
23
|
tsconfig?: string;
|
|
24
24
|
onSuccess?: string | (() => void | Promise<void>);
|
|
25
|
+
tsgo?: boolean;
|
|
25
26
|
_callbacks?: {
|
|
26
27
|
onBuildStart?: (state: any) => void;
|
|
27
28
|
onBuildEnd?: (assetJobs: any) => void;
|
|
@@ -36,6 +37,7 @@ type PackageMetadata = {
|
|
|
36
37
|
files?: string[];
|
|
37
38
|
type?: 'commonjs' | 'module';
|
|
38
39
|
dependencies?: Record<string, string>;
|
|
40
|
+
optionalDependencies?: Record<string, string>;
|
|
39
41
|
peerDependencies?: Record<string, string>;
|
|
40
42
|
peerDependenciesMeta?: Record<string, Record<string, string>>;
|
|
41
43
|
exports?: string | Record<string, ExportCondition>;
|
package/dist/index.js
CHANGED
|
@@ -299,7 +299,7 @@ function validateEntryFiles(entryFiles) {
|
|
|
299
299
|
|
|
300
300
|
function exit(err) {
|
|
301
301
|
logger.error(err);
|
|
302
|
-
|
|
302
|
+
throw typeof err === 'string' ? new Error(err) : err;
|
|
303
303
|
}
|
|
304
304
|
async function getPackageMeta(cwd) {
|
|
305
305
|
const pkgFilePath = path__default.default.resolve(cwd, 'package.json');
|
|
@@ -1034,7 +1034,42 @@ const memoizeByKey = (fn)=>{
|
|
|
1034
1034
|
const memoize = (fn)=>createMemoize(fn);
|
|
1035
1035
|
|
|
1036
1036
|
let hasLoggedTsWarning = false;
|
|
1037
|
-
|
|
1037
|
+
let hasLoggedTsGoWarning = false;
|
|
1038
|
+
function resolveTsGo(cwd) {
|
|
1039
|
+
let tsgo;
|
|
1040
|
+
const m = new module$1.Module('', undefined);
|
|
1041
|
+
m.paths = module$1.Module._nodeModulePaths(cwd);
|
|
1042
|
+
try {
|
|
1043
|
+
// Bun does not yet support the `Module` class properly.
|
|
1044
|
+
if (typeof (m == null ? void 0 : m.require) === 'undefined') {
|
|
1045
|
+
const tsgoPath = require.resolve('@typescript/native-preview', {
|
|
1046
|
+
paths: [
|
|
1047
|
+
cwd
|
|
1048
|
+
]
|
|
1049
|
+
});
|
|
1050
|
+
tsgo = require(tsgoPath);
|
|
1051
|
+
} else {
|
|
1052
|
+
tsgo = m.require('@typescript/native-preview');
|
|
1053
|
+
}
|
|
1054
|
+
// ts-go exports the TypeScript API as default or named export
|
|
1055
|
+
return tsgo.default || tsgo;
|
|
1056
|
+
} catch (e) {
|
|
1057
|
+
if (!hasLoggedTsGoWarning) {
|
|
1058
|
+
hasLoggedTsGoWarning = true;
|
|
1059
|
+
logger.warn('Could not load TypeScript-Go compiler. Make sure `@typescript/native-preview` is installed as a dev dependency.');
|
|
1060
|
+
}
|
|
1061
|
+
return null;
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
function resolveTypescript(cwd, useTsGo) {
|
|
1065
|
+
if (useTsGo) {
|
|
1066
|
+
const tsgo = resolveTsGo(cwd);
|
|
1067
|
+
if (tsgo) {
|
|
1068
|
+
return tsgo;
|
|
1069
|
+
}
|
|
1070
|
+
// Error if ts-go is requested but not available
|
|
1071
|
+
exit('TypeScript-Go compiler not found. Please install @typescript/native-preview as a dev dependency: pnpm add -D @typescript/native-preview');
|
|
1072
|
+
}
|
|
1038
1073
|
let ts;
|
|
1039
1074
|
const m = new module$1.Module('', undefined);
|
|
1040
1075
|
m.paths = module$1.Module._nodeModulePaths(cwd);
|
|
@@ -1064,11 +1099,11 @@ const resolveTsConfigPath = memoize((cwd, tsconfigFileName = 'tsconfig.json')=>{
|
|
|
1064
1099
|
tsConfigPath = path.resolve(cwd, tsconfigFileName);
|
|
1065
1100
|
return fileExists(tsConfigPath) ? tsConfigPath : undefined;
|
|
1066
1101
|
});
|
|
1067
|
-
function resolveTsConfigHandler(cwd, tsConfigPath) {
|
|
1102
|
+
function resolveTsConfigHandler(cwd, tsConfigPath, useTsGo) {
|
|
1068
1103
|
let tsCompilerOptions = {};
|
|
1069
1104
|
if (tsConfigPath) {
|
|
1070
1105
|
// Use the original ts handler to avoid memory leak
|
|
1071
|
-
const ts = resolveTypescript(cwd);
|
|
1106
|
+
const ts = resolveTypescript(cwd, useTsGo);
|
|
1072
1107
|
const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd;
|
|
1073
1108
|
const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config;
|
|
1074
1109
|
tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options;
|
|
@@ -1080,15 +1115,28 @@ function resolveTsConfigHandler(cwd, tsConfigPath) {
|
|
|
1080
1115
|
tsConfigPath
|
|
1081
1116
|
};
|
|
1082
1117
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1118
|
+
// Note: We can't memoize resolveTsConfigHandler directly with useTsGo parameter
|
|
1119
|
+
// because memoize doesn't handle optional parameters well. Instead, we'll create
|
|
1120
|
+
// a wrapper that handles the memoization per useTsGo value.
|
|
1121
|
+
const resolveTsConfigCache = new Map();
|
|
1122
|
+
function resolveTsConfig(cwd, tsConfigPath, useTsGo) {
|
|
1123
|
+
const cacheKey = `${cwd}:${tsConfigPath || ''}:${useTsGo ? 'tsgo' : 'ts'}`;
|
|
1124
|
+
if (resolveTsConfigCache.has(cacheKey)) {
|
|
1125
|
+
return resolveTsConfigCache.get(cacheKey);
|
|
1126
|
+
}
|
|
1127
|
+
const result = resolveTsConfigHandler(cwd, tsConfigPath, useTsGo);
|
|
1128
|
+
resolveTsConfigCache.set(cacheKey, result);
|
|
1129
|
+
return result;
|
|
1130
|
+
}
|
|
1131
|
+
async function convertCompilerOptions(cwd, json, useTsGo) {
|
|
1085
1132
|
// Use the original ts handler to avoid memory leak
|
|
1086
|
-
const ts = resolveTypescript(cwd);
|
|
1133
|
+
const ts = resolveTypescript(cwd, useTsGo);
|
|
1087
1134
|
return ts.convertCompilerOptionsFromJson(json, './');
|
|
1088
1135
|
}
|
|
1089
|
-
async function writeDefaultTsconfig(tsConfigPath) {
|
|
1136
|
+
async function writeDefaultTsconfig(tsConfigPath, useTsGo) {
|
|
1090
1137
|
await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
|
|
1091
|
-
|
|
1138
|
+
const compilerName = useTsGo ? 'TypeScript-Go' : 'TypeScript';
|
|
1139
|
+
logger.log(`Detected using ${compilerName} but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
|
|
1092
1140
|
}
|
|
1093
1141
|
|
|
1094
1142
|
/**
|
|
@@ -1327,6 +1375,89 @@ function rawContent({ exclude }) {
|
|
|
1327
1375
|
};
|
|
1328
1376
|
}
|
|
1329
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
|
+
|
|
1330
1461
|
function hasNoSpecialCondition(conditionNames) {
|
|
1331
1462
|
return [
|
|
1332
1463
|
...conditionNames
|
|
@@ -1457,6 +1588,51 @@ const prependShebang = (entry)=>({
|
|
|
1457
1588
|
}
|
|
1458
1589
|
});
|
|
1459
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
|
+
|
|
1460
1636
|
const swcMinifyOptions = {
|
|
1461
1637
|
compress: {
|
|
1462
1638
|
directives: false
|
|
@@ -1468,7 +1644,7 @@ const swcMinifyOptions = {
|
|
|
1468
1644
|
toplevel: true
|
|
1469
1645
|
}
|
|
1470
1646
|
};
|
|
1471
|
-
async function createDtsPlugin(tsCompilerOptions, tsConfigPath, respectExternal, cwd) {
|
|
1647
|
+
async function createDtsPlugin(tsCompilerOptions, tsConfigPath, respectExternal, cwd, useTsGo) {
|
|
1472
1648
|
const enableIncrementalWithoutBuildInfo = (tsCompilerOptions == null ? void 0 : tsCompilerOptions.incremental) && !(tsCompilerOptions == null ? void 0 : tsCompilerOptions.tsBuildInfoFile);
|
|
1473
1649
|
const incrementalOptions = enableIncrementalWithoutBuildInfo ? {
|
|
1474
1650
|
incremental: false
|
|
@@ -1495,7 +1671,33 @@ async function createDtsPlugin(tsCompilerOptions, tsConfigPath, respectExternal,
|
|
|
1495
1671
|
...incrementalOptions,
|
|
1496
1672
|
// error TS6379: Composite projects may not disable incremental compilation.
|
|
1497
1673
|
...compositeOptions
|
|
1498
|
-
});
|
|
1674
|
+
}, useTsGo);
|
|
1675
|
+
// If useTsGo is enabled, we need to make ts-go available to rollup-plugin-dts
|
|
1676
|
+
// rollup-plugin-dts uses require('typescript') internally, so we need to
|
|
1677
|
+
// temporarily override the module cache to use ts-go
|
|
1678
|
+
if (useTsGo) {
|
|
1679
|
+
const tsgo = resolveTsGo(cwd);
|
|
1680
|
+
if (tsgo) {
|
|
1681
|
+
try {
|
|
1682
|
+
// First, try to resolve typescript to get its path
|
|
1683
|
+
const tsPath = require.resolve('typescript', {
|
|
1684
|
+
paths: [
|
|
1685
|
+
cwd
|
|
1686
|
+
]
|
|
1687
|
+
});
|
|
1688
|
+
// Make ts-go available as 'typescript' for rollup-plugin-dts
|
|
1689
|
+
// This overrides the module cache so rollup-plugin-dts will use ts-go
|
|
1690
|
+
require.cache[tsPath] = {
|
|
1691
|
+
id: tsPath,
|
|
1692
|
+
exports: tsgo,
|
|
1693
|
+
loaded: true
|
|
1694
|
+
};
|
|
1695
|
+
} catch (e) {
|
|
1696
|
+
// If typescript cannot be resolved, we can't override it
|
|
1697
|
+
// rollup-plugin-dts will try to require it and may fail
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1499
1701
|
const dtsPlugin = require('rollup-plugin-dts').default({
|
|
1500
1702
|
tsconfig: tsConfigPath,
|
|
1501
1703
|
compilerOptions: overrideResolvedTsOptions,
|
|
@@ -1589,8 +1791,8 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
1589
1791
|
// Each process should be unique
|
|
1590
1792
|
// Each package build should be unique
|
|
1591
1793
|
// Composing above factors into a unique cache key to retrieve the memoized dts plugin with tsconfigs
|
|
1592
|
-
const uniqueProcessId = 'dts-plugin:' + process.pid + tsConfigPath;
|
|
1593
|
-
const dtsPlugin = await memoizeDtsPluginByKey(uniqueProcessId)(tsCompilerOptions, tsConfigPath, bundleConfig.dts && bundleConfig.dts.respectExternal, cwd);
|
|
1794
|
+
const uniqueProcessId = 'dts-plugin:' + process.pid + tsConfigPath + (buildContext.useTsGo ? ':tsgo' : '');
|
|
1795
|
+
const dtsPlugin = await memoizeDtsPluginByKey(uniqueProcessId)(tsCompilerOptions, tsConfigPath, bundleConfig.dts && bundleConfig.dts.respectExternal, cwd, buildContext.useTsGo);
|
|
1594
1796
|
typesPlugins.push(dtsPlugin);
|
|
1595
1797
|
}
|
|
1596
1798
|
const plugins = (dts ? typesPlugins : [
|
|
@@ -1603,6 +1805,7 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
1603
1805
|
rawContent({
|
|
1604
1806
|
exclude: /node_modules/
|
|
1605
1807
|
}),
|
|
1808
|
+
nativeAddon(),
|
|
1606
1809
|
isBinEntry && prependShebang(entry),
|
|
1607
1810
|
replace__default.default({
|
|
1608
1811
|
values: inlineDefinedValues,
|
|
@@ -1627,6 +1830,11 @@ async function buildInputConfig(entry, bundleConfig, exportCondition, buildConte
|
|
|
1627
1830
|
// For relative paths, the module will be bundled;
|
|
1628
1831
|
// For external libraries, the module will not be bundled.
|
|
1629
1832
|
transformMixedEsModules: true
|
|
1833
|
+
}),
|
|
1834
|
+
// If SWC emits @swc/helpers imports, warn when it's not installed.
|
|
1835
|
+
swcHelpersWarningPlugin({
|
|
1836
|
+
cwd,
|
|
1837
|
+
pkg
|
|
1630
1838
|
})
|
|
1631
1839
|
]).filter(isNotNull);
|
|
1632
1840
|
return {
|
|
@@ -1668,6 +1876,62 @@ function getModuleLayer(moduleMeta) {
|
|
|
1668
1876
|
const moduleLayer = directives[0];
|
|
1669
1877
|
return moduleLayer ? hashTo3Char(moduleLayer) : undefined;
|
|
1670
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
|
+
}
|
|
1671
1935
|
// dependencyGraphMap: Map<subModuleId, Set<entryParentId>>
|
|
1672
1936
|
function createSplitChunks(dependencyGraphMap, entryFiles) {
|
|
1673
1937
|
// If there's existing chunk being splitted, and contains a layer { <id>: <chunkGroup> }
|
|
@@ -1704,6 +1968,24 @@ function createSplitChunks(dependencyGraphMap, entryFiles) {
|
|
|
1704
1968
|
}
|
|
1705
1969
|
}
|
|
1706
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
|
+
}
|
|
1707
1989
|
// If current module has a layer, and it's not an entry
|
|
1708
1990
|
if (moduleLayer && !isEntry) {
|
|
1709
1991
|
// If the module is imported by the entry:
|
|
@@ -1987,8 +2269,17 @@ async function bundle(cliEntryPath, { cwd: _cwd, onSuccess, ...options } = {}) {
|
|
|
1987
2269
|
// Original input file path, client path might change later
|
|
1988
2270
|
const inputFile = cliEntryPath;
|
|
1989
2271
|
const isFromCli = Boolean(cliEntryPath);
|
|
2272
|
+
const useTsGo = options.tsgo === true;
|
|
2273
|
+
// Check if ts-go is available when requested (before resolving tsconfig)
|
|
2274
|
+
let tsgoInstance = null;
|
|
2275
|
+
if (useTsGo) {
|
|
2276
|
+
tsgoInstance = resolveTsGo(cwd);
|
|
2277
|
+
if (!tsgoInstance) {
|
|
2278
|
+
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');
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
1990
2281
|
const tsConfigPath = resolveTsConfigPath(cwd, options.tsconfig);
|
|
1991
|
-
let tsConfig = resolveTsConfig(cwd, tsConfigPath);
|
|
2282
|
+
let tsConfig = resolveTsConfig(cwd, tsConfigPath, useTsGo);
|
|
1992
2283
|
let hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
|
|
1993
2284
|
const defaultTsOptions = {
|
|
1994
2285
|
tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath,
|
|
@@ -2058,7 +2349,7 @@ async function bundle(cliEntryPath, { cwd: _cwd, onSuccess, ...options } = {}) {
|
|
|
2058
2349
|
// Otherwise, use the existing one.
|
|
2059
2350
|
const defaultTsConfigPath = path.resolve(cwd, 'tsconfig.json');
|
|
2060
2351
|
if (!fileExists(defaultTsConfigPath)) {
|
|
2061
|
-
await writeDefaultTsconfig(defaultTsConfigPath);
|
|
2352
|
+
await writeDefaultTsconfig(defaultTsConfigPath, useTsGo);
|
|
2062
2353
|
}
|
|
2063
2354
|
defaultTsOptions.tsConfigPath = defaultTsConfigPath;
|
|
2064
2355
|
hasTsConfig = true;
|
|
@@ -2070,12 +2361,15 @@ async function bundle(cliEntryPath, { cwd: _cwd, onSuccess, ...options } = {}) {
|
|
|
2070
2361
|
const outputState = createOutputState({
|
|
2071
2362
|
entries
|
|
2072
2363
|
});
|
|
2364
|
+
// Use ts-go if it was successfully resolved earlier
|
|
2365
|
+
const useTsGoInContext = Boolean(useTsGo && hasTsConfig && tsgoInstance);
|
|
2073
2366
|
const buildContext = {
|
|
2074
2367
|
entries,
|
|
2075
2368
|
pkg,
|
|
2076
2369
|
cwd,
|
|
2077
2370
|
tsOptions: defaultTsOptions,
|
|
2078
2371
|
useTypeScript: hasTsConfig,
|
|
2372
|
+
useTsGo: useTsGoInContext,
|
|
2079
2373
|
browserslistConfig,
|
|
2080
2374
|
pluginContext: {
|
|
2081
2375
|
outputState,
|
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",
|
|
@@ -37,7 +56,7 @@
|
|
|
37
56
|
},
|
|
38
57
|
"license": "MIT",
|
|
39
58
|
"dependencies": {
|
|
40
|
-
"@rollup/plugin-commonjs": "^
|
|
59
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
41
60
|
"@rollup/plugin-json": "^6.1.0",
|
|
42
61
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
43
62
|
"@rollup/plugin-replace": "^6.0.2",
|
|
@@ -51,7 +70,7 @@
|
|
|
51
70
|
"picomatch": "^4.0.2",
|
|
52
71
|
"pretty-bytes": "^5.6.0",
|
|
53
72
|
"rollup": "^4.52.4",
|
|
54
|
-
"rollup-plugin-dts": "^6.
|
|
73
|
+
"rollup-plugin-dts": "^6.3.0",
|
|
55
74
|
"rollup-plugin-swc3": "^0.11.1",
|
|
56
75
|
"rollup-preserve-directives": "^1.1.3",
|
|
57
76
|
"tinyglobby": "^0.2.14",
|
|
@@ -59,7 +78,8 @@
|
|
|
59
78
|
"yargs": "^17.7.2"
|
|
60
79
|
},
|
|
61
80
|
"peerDependencies": {
|
|
62
|
-
"typescript": "^4.1 || ^5.0"
|
|
81
|
+
"typescript": "^4.1 || ^5.0",
|
|
82
|
+
"@typescript/native-preview": "*"
|
|
63
83
|
},
|
|
64
84
|
"peerDependenciesMeta": {
|
|
65
85
|
"typescript": {
|
|
@@ -67,6 +87,9 @@
|
|
|
67
87
|
},
|
|
68
88
|
"@swc/helpers": {
|
|
69
89
|
"optional": true
|
|
90
|
+
},
|
|
91
|
+
"@typescript/native-preview": {
|
|
92
|
+
"optional": true
|
|
70
93
|
}
|
|
71
94
|
},
|
|
72
95
|
"devDependencies": {
|
|
@@ -79,16 +102,17 @@
|
|
|
79
102
|
"@types/picomatch": "^3.0.1",
|
|
80
103
|
"@types/react": "^19.0.9",
|
|
81
104
|
"@types/yargs": "^17.0.33",
|
|
105
|
+
"@typescript/native-preview": "*",
|
|
82
106
|
"bunchee": "link:./",
|
|
83
107
|
"cross-env": "^7.0.3",
|
|
84
108
|
"husky": "^9.0.11",
|
|
85
109
|
"lint-staged": "^15.2.2",
|
|
86
|
-
"next": "16.0.
|
|
110
|
+
"next": "16.0.10",
|
|
87
111
|
"picocolors": "^1.0.0",
|
|
88
112
|
"postcss": "^8.5.4",
|
|
89
113
|
"prettier": "3.4.2",
|
|
90
|
-
"react": "^19.
|
|
91
|
-
"react-dom": "^19.
|
|
114
|
+
"react": "^19.2.1",
|
|
115
|
+
"react-dom": "^19.2.1",
|
|
92
116
|
"tailwindcss": "^4.1.8",
|
|
93
117
|
"typescript": "^5.9.2",
|
|
94
118
|
"vitest": "^3.0.4"
|
|
@@ -96,21 +120,5 @@
|
|
|
96
120
|
"lint-staged": {
|
|
97
121
|
"*.{js,jsx,ts,tsx,md,json,yml,yaml}": "prettier --write"
|
|
98
122
|
},
|
|
99
|
-
"
|
|
100
|
-
|
|
101
|
-
"test:update": "TEST_UPDATE_SNAPSHOT=1 pnpm test",
|
|
102
|
-
"test:post": "cross-env POST_BUILD=1 pnpm test test/compile.test.ts test/integration.test.ts",
|
|
103
|
-
"docs:dev": "next dev docs",
|
|
104
|
-
"docs:build": "next build docs",
|
|
105
|
-
"clean": "rm -rf ./dist",
|
|
106
|
-
"new-test": "node ./scripts/new-test.js",
|
|
107
|
-
"typecheck": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
|
|
108
|
-
"prepare-release": "pnpm clean && pnpm build",
|
|
109
|
-
"publish-local": "pnpm prepare-release && pnpm test && pnpm publish",
|
|
110
|
-
"run-ts": "cross-env SWC_NODE_IGNORE_DYNAMIC=1 node -r @swc-node/register",
|
|
111
|
-
"ts-bunchee": "pnpm run-ts ./src/bin/index.ts",
|
|
112
|
-
"build-dir": "pnpm ts-bunchee --cwd",
|
|
113
|
-
"build": "pnpm run-ts ./src/bin/index.ts --runtime node",
|
|
114
|
-
"format": "prettier --write ."
|
|
115
|
-
}
|
|
116
|
-
}
|
|
123
|
+
"packageManager": "pnpm@9.4.0"
|
|
124
|
+
}
|