bunchee 3.3.4 → 3.4.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 +33 -2
- package/dist/cli.js +2 -2
- package/dist/index.js +106 -42
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,7 +61,10 @@ Using pure ESM package?
|
|
|
61
61
|
}
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
Then just run `npm run build`, or `pnpm build` / `yarn build` if you're using these package managers.
|
|
64
|
+
Then just run `npm run build`, or `pnpm build` / `yarn build` if you're using these package managers. The output format will based on the exports condition and also the file extension. Given an example:
|
|
65
|
+
|
|
66
|
+
* It's CommonJS for `require` and ESM for `import` based on the exports condition.
|
|
67
|
+
* It's CommonJS for `.js` and ESM for `.mjs` based on the extension regardless the exports condition. Then for export condition like "node" you could choose the format with your extension.
|
|
65
68
|
|
|
66
69
|
## Configuration
|
|
67
70
|
|
|
@@ -121,7 +124,6 @@ bunchee --env=ENV1,ENV2,ENV3
|
|
|
121
124
|
|
|
122
125
|
Replace `ENV1`, `ENV2`, and `ENV3` with the names of the environment variables you want to include in your bundled code. These environment variables will be inlined during the bundling process.
|
|
123
126
|
|
|
124
|
-
|
|
125
127
|
### Entry Files Convention
|
|
126
128
|
|
|
127
129
|
While `exports` field is becoming the standard of exporting in node.js, bunchee also supports to build multiple exports all in one command.
|
|
@@ -161,6 +163,35 @@ Then you need to add two entry files `index.ts` and `lite.ts` in project root di
|
|
|
161
163
|
|- package.json
|
|
162
164
|
```
|
|
163
165
|
|
|
166
|
+
It will also look up for `index.<ext>` file under the directory having the name of the export path. For example, if you have `"./lite": "./dist/lite.js"` in exports field, then it will look up for `./lite/index.js` as the entry file as well.
|
|
167
|
+
|
|
168
|
+
### Special Exports Conventions
|
|
169
|
+
|
|
170
|
+
For exports condition like `react-native`, `react-server` and `edge-light` as they're special platforms, they could have different exports or different code conditions. In this case bunchee provides an override input source file convention if you want to build them as different code bundle.
|
|
171
|
+
|
|
172
|
+
For instance:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"exports": {
|
|
177
|
+
"react-server": "./dist/react-server.mjs",
|
|
178
|
+
"edge-light": "./dist/edge-light.mjs",
|
|
179
|
+
"import": "./dist/index.mjs"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
You can use `index.<export-type>.<ext>` to override the input source file for specific export name. Or using `<export-path>/index.<export-type>.<ext>` also works. Such as:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
|- src/
|
|
188
|
+
|- index/.ts
|
|
189
|
+
|- index.react-server.ts
|
|
190
|
+
|- index.edge-light.ts
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
This will match the export name `"react-server"` and `"edge-light"` then use the corresponding input source file to build the bundle.
|
|
194
|
+
|
|
164
195
|
#### Package lint
|
|
165
196
|
|
|
166
197
|
`bunchee` has support for checking the package bundles are matched with package exports configuration.
|
package/dist/cli.js
CHANGED
|
@@ -76,7 +76,7 @@ const logger = {
|
|
|
76
76
|
console.log('\x1b[33m' + arg + '\x1b[0m');
|
|
77
77
|
},
|
|
78
78
|
error (arg) {
|
|
79
|
-
console.error('\x1b[31m' + arg + '\x1b[0m');
|
|
79
|
+
console.error('\x1b[31m' + (arg instanceof Error ? arg.stack : arg) + '\x1b[0m');
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
82
|
function fileExists(filePath) {
|
|
@@ -97,7 +97,7 @@ function _fileExists() {
|
|
|
97
97
|
return _fileExists.apply(this, arguments);
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
var version = "3.
|
|
100
|
+
var version = "3.4.1";
|
|
101
101
|
|
|
102
102
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
103
103
|
try {
|
package/dist/index.js
CHANGED
|
@@ -118,7 +118,7 @@ const logger = {
|
|
|
118
118
|
console.log('\x1b[33m' + arg + '\x1b[0m');
|
|
119
119
|
},
|
|
120
120
|
error (arg) {
|
|
121
|
-
console.error('\x1b[31m' + arg + '\x1b[0m');
|
|
121
|
+
console.error('\x1b[31m' + (arg instanceof Error ? arg.stack : arg) + '\x1b[0m');
|
|
122
122
|
}
|
|
123
123
|
};
|
|
124
124
|
function fileExists(filePath) {
|
|
@@ -151,30 +151,55 @@ const SRC = 'src' // resolve from src/ directory
|
|
|
151
151
|
function resolveSourceFile(cwd, filename) {
|
|
152
152
|
return path__default.default.resolve(cwd, SRC, filename);
|
|
153
153
|
}
|
|
154
|
+
function findSourceEntryFile(cwd, exportPath, exportTypeSuffix, ext) {
|
|
155
|
+
return _findSourceEntryFile.apply(this, arguments);
|
|
156
|
+
}
|
|
157
|
+
function _findSourceEntryFile() {
|
|
158
|
+
_findSourceEntryFile = _async_to_generator$3(function*(cwd, exportPath, exportTypeSuffix, ext) {
|
|
159
|
+
const filename = resolveSourceFile(cwd, `${exportPath}${exportTypeSuffix ? `.${exportTypeSuffix}` : ''}.${ext}`);
|
|
160
|
+
if (yield fileExists(filename)) {
|
|
161
|
+
return filename;
|
|
162
|
+
}
|
|
163
|
+
const subFolderIndexFilename = resolveSourceFile(cwd, `${exportPath}/index${exportTypeSuffix ? `.${exportTypeSuffix}` : ''}.${ext}`);
|
|
164
|
+
if (yield fileExists(subFolderIndexFilename)) {
|
|
165
|
+
return subFolderIndexFilename;
|
|
166
|
+
}
|
|
167
|
+
return undefined;
|
|
168
|
+
});
|
|
169
|
+
return _findSourceEntryFile.apply(this, arguments);
|
|
170
|
+
}
|
|
154
171
|
// Map '.' -> './index.[ext]'
|
|
155
172
|
// Map './lite' -> './lite.[ext]'
|
|
156
173
|
// Return undefined if no match or if it's package.json exports
|
|
157
|
-
|
|
174
|
+
const availableExtensions = [
|
|
175
|
+
'js',
|
|
176
|
+
'cjs',
|
|
177
|
+
'mjs',
|
|
178
|
+
'jsx',
|
|
179
|
+
'ts',
|
|
180
|
+
'tsx'
|
|
181
|
+
];
|
|
182
|
+
const availableExportConventions = [
|
|
183
|
+
'react-server',
|
|
184
|
+
'react-native',
|
|
185
|
+
'edge-light'
|
|
186
|
+
];
|
|
187
|
+
function getSourcePathFromExportPath(cwd, exportPath, exportType) {
|
|
158
188
|
return _getSourcePathFromExportPath.apply(this, arguments);
|
|
159
189
|
}
|
|
160
190
|
function _getSourcePathFromExportPath() {
|
|
161
|
-
_getSourcePathFromExportPath = _async_to_generator$3(function*(cwd, exportPath) {
|
|
162
|
-
const
|
|
163
|
-
'js',
|
|
164
|
-
'cjs',
|
|
165
|
-
'mjs',
|
|
166
|
-
'jsx',
|
|
167
|
-
'ts',
|
|
168
|
-
'tsx'
|
|
169
|
-
];
|
|
170
|
-
for (const ext of exts){
|
|
191
|
+
_getSourcePathFromExportPath = _async_to_generator$3(function*(cwd, exportPath, exportType) {
|
|
192
|
+
for (const ext of availableExtensions){
|
|
171
193
|
// ignore package.json
|
|
172
194
|
if (exportPath.endsWith('package.json')) return;
|
|
173
195
|
if (exportPath === '.') exportPath = './index';
|
|
174
|
-
|
|
175
|
-
if (
|
|
176
|
-
|
|
196
|
+
// Find convention-based source file for specific export types
|
|
197
|
+
if (availableExportConventions.includes(exportType)) {
|
|
198
|
+
const filename = yield findSourceEntryFile(cwd, exportPath, exportType, ext);
|
|
199
|
+
if (filename) return filename;
|
|
177
200
|
}
|
|
201
|
+
const filename = yield findSourceEntryFile(cwd, exportPath, null, ext);
|
|
202
|
+
if (filename) return filename;
|
|
178
203
|
}
|
|
179
204
|
return;
|
|
180
205
|
});
|
|
@@ -184,6 +209,7 @@ function _getSourcePathFromExportPath() {
|
|
|
184
209
|
function filenameWithoutExtension(file) {
|
|
185
210
|
return file ? file.replace(new RegExp(`${path__default.default.extname(file)}$`), '') : undefined;
|
|
186
211
|
}
|
|
212
|
+
const nonNullable = (n)=>Boolean(n);
|
|
187
213
|
|
|
188
214
|
function getTypings(pkg) {
|
|
189
215
|
return pkg.types || pkg.typings;
|
|
@@ -350,22 +376,19 @@ function constructDefaultExportCondition(value, packageType) {
|
|
|
350
376
|
} : value;
|
|
351
377
|
return constructFullExportCondition(objValue, packageType);
|
|
352
378
|
}
|
|
353
|
-
function isEsmExportName(name) {
|
|
379
|
+
function isEsmExportName(name, ext) {
|
|
354
380
|
return [
|
|
355
381
|
'import',
|
|
356
|
-
'module'
|
|
357
|
-
|
|
358
|
-
'react-server',
|
|
359
|
-
'edge-light'
|
|
360
|
-
].includes(name);
|
|
382
|
+
'module'
|
|
383
|
+
].includes(name) || ext === 'mjs';
|
|
361
384
|
}
|
|
362
|
-
function isCjsExportName(name) {
|
|
385
|
+
function isCjsExportName(name, ext) {
|
|
363
386
|
return [
|
|
364
387
|
'require',
|
|
365
388
|
'main',
|
|
366
389
|
'node',
|
|
367
390
|
'default'
|
|
368
|
-
].includes(name);
|
|
391
|
+
].includes(name) || ext === 'cjs';
|
|
369
392
|
}
|
|
370
393
|
function getExportConditionDist(pkg, parsedExportCondition, cwd) {
|
|
371
394
|
const dist = [];
|
|
@@ -375,12 +398,14 @@ function getExportConditionDist(pkg, parsedExportCondition, cwd) {
|
|
|
375
398
|
if (key === 'types') {
|
|
376
399
|
continue;
|
|
377
400
|
}
|
|
401
|
+
const filePath = parsedExportCondition.export[key];
|
|
402
|
+
const ext = path.extname(filePath).slice(1);
|
|
378
403
|
const relativePath = parsedExportCondition.export[key];
|
|
379
404
|
const distFile = getDistPath(relativePath, cwd);
|
|
380
405
|
let format = 'esm';
|
|
381
|
-
if (isEsmExportName(key)) {
|
|
406
|
+
if (isEsmExportName(key, ext)) {
|
|
382
407
|
format = 'esm';
|
|
383
|
-
} else if (isCjsExportName(key)) {
|
|
408
|
+
} else if (isCjsExportName(key, ext)) {
|
|
384
409
|
format = 'cjs';
|
|
385
410
|
}
|
|
386
411
|
// Deduplicate the same path jobs
|
|
@@ -592,8 +617,8 @@ function hasEsmExport(exportPaths, tsCompilerOptions) {
|
|
|
592
617
|
let hasEsm = false;
|
|
593
618
|
for(const key in exportPaths){
|
|
594
619
|
const exportInfo = exportPaths[key];
|
|
595
|
-
const
|
|
596
|
-
if (
|
|
620
|
+
const exportInfoEntries = Object.entries(exportInfo);
|
|
621
|
+
if (exportInfoEntries.some(([exportType, file])=>isEsmExportName(exportType, file))) {
|
|
597
622
|
hasEsm = true;
|
|
598
623
|
break;
|
|
599
624
|
}
|
|
@@ -636,22 +661,61 @@ function buildEntryConfig(pkg, entryPath, exportPaths, bundleConfig, cwd, tsOpti
|
|
|
636
661
|
}
|
|
637
662
|
function _buildEntryConfig() {
|
|
638
663
|
_buildEntryConfig = _async_to_generator$2(function*(pkg, entryPath, exportPaths, bundleConfig, cwd, tsOptions, dts) {
|
|
639
|
-
const configs =
|
|
664
|
+
const configs = [];
|
|
665
|
+
Object.keys(exportPaths).forEach(/*#__PURE__*/ _async_to_generator$2(function*(entryExport) {
|
|
640
666
|
// TODO: improve the source detection
|
|
641
|
-
const
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
667
|
+
const exportCond = exportPaths[entryExport];
|
|
668
|
+
const buildConfigs = [
|
|
669
|
+
createBuildConfig('', exportCond) // default config
|
|
670
|
+
];
|
|
671
|
+
// For dts job, only build the default config.
|
|
672
|
+
// For assets job, build all configs.
|
|
673
|
+
if (!dts) {
|
|
674
|
+
if (exportCond['edge-light']) {
|
|
675
|
+
buildConfigs.push(createBuildConfig('edge-light', exportCond));
|
|
676
|
+
}
|
|
677
|
+
if (exportCond['react-server']) {
|
|
678
|
+
buildConfigs.push(createBuildConfig('react-server', exportCond));
|
|
679
|
+
}
|
|
680
|
+
if (exportCond['react-native']) {
|
|
681
|
+
buildConfigs.push(createBuildConfig('react-native', exportCond));
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
function createBuildConfig(exportType, exportCondRef) {
|
|
685
|
+
return _createBuildConfig.apply(this, arguments);
|
|
686
|
+
}
|
|
687
|
+
function _createBuildConfig() {
|
|
688
|
+
_createBuildConfig = _async_to_generator$2(function*(exportType, exportCondRef) {
|
|
689
|
+
let exportCondForType = _extends$1({}, exportCondRef);
|
|
690
|
+
// Special cases of export type, only pass down the exportPaths for the type
|
|
691
|
+
if (availableExportConventions.includes(exportType)) {
|
|
692
|
+
exportCondForType = {
|
|
693
|
+
[entryExport]: exportCondRef[exportType]
|
|
694
|
+
};
|
|
695
|
+
// Basic export type, pass down the exportPaths with erasing the special ones
|
|
696
|
+
} else {
|
|
697
|
+
for (const exportType of availableExportConventions){
|
|
698
|
+
delete exportCondForType[exportType];
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
const source = entryPath || (yield getSourcePathFromExportPath(cwd, entryExport, exportType));
|
|
702
|
+
if (!source) return undefined;
|
|
703
|
+
// For dts, only build types filed
|
|
704
|
+
if (dts && !exportCondRef['types']) return undefined;
|
|
705
|
+
const exportCondition = {
|
|
706
|
+
source,
|
|
707
|
+
name: entryExport,
|
|
708
|
+
export: exportCondForType
|
|
709
|
+
};
|
|
710
|
+
const entry = resolveSourceFile(cwd, source);
|
|
711
|
+
const rollupConfig = buildConfig(entry, pkg, exportPaths, bundleConfig, exportCondition, cwd, tsOptions, dts);
|
|
712
|
+
return rollupConfig;
|
|
713
|
+
});
|
|
714
|
+
return _createBuildConfig.apply(this, arguments);
|
|
715
|
+
}
|
|
716
|
+
configs.push(...buildConfigs);
|
|
653
717
|
}));
|
|
654
|
-
return (yield Promise.all(configs)).filter(
|
|
718
|
+
return (yield Promise.all(configs)).filter(nonNullable);
|
|
655
719
|
});
|
|
656
720
|
return _buildEntryConfig.apply(this, arguments);
|
|
657
721
|
}
|
|
@@ -876,7 +940,7 @@ function _bundle() {
|
|
|
876
940
|
if (!isMultiEntries) {
|
|
877
941
|
// Use specified string file path if possible, then fallback to the default behavior entry picking logic
|
|
878
942
|
// e.g. "exports": "./dist/index.js" -> use "./index.<ext>" as entry
|
|
879
|
-
entryPath = entryPath || (yield getSourcePathFromExportPath(cwd, '.')) || '';
|
|
943
|
+
entryPath = entryPath || (yield getSourcePathFromExportPath(cwd, '.', 'default')) || '';
|
|
880
944
|
}
|
|
881
945
|
if (entryPath) {
|
|
882
946
|
let mainEntryPath;
|