bunchee 4.3.4 → 4.4.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 +23 -6
- package/dist/bin/cli.js +378 -24
- package/dist/index.d.ts +1 -0
- package/dist/index.js +182 -116
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ Then use use the [exports field in package.json](https://nodejs.org/api/packages
|
|
|
64
64
|
"files": ["dist"],
|
|
65
65
|
"exports": {
|
|
66
66
|
"import": "./dist/es/index.mjs",
|
|
67
|
-
"require": "./dist/cjs/index.
|
|
67
|
+
"require": "./dist/cjs/index.js"
|
|
68
68
|
},
|
|
69
69
|
"scripts": {
|
|
70
70
|
"build": "bunchee"
|
|
@@ -88,8 +88,8 @@ If you're build a TypeScript library, separate the types from the main entry fil
|
|
|
88
88
|
"default": "./dist/es/index.mjs"
|
|
89
89
|
},
|
|
90
90
|
"require": {
|
|
91
|
-
"types": "./dist/cjs/index.d.
|
|
92
|
-
"default": "./dist/cjs/index.
|
|
91
|
+
"types": "./dist/cjs/index.d.ts",
|
|
92
|
+
"default": "./dist/cjs/index.js"
|
|
93
93
|
}
|
|
94
94
|
},
|
|
95
95
|
"scripts": {
|
|
@@ -107,13 +107,13 @@ If you're using TypeScript with Node 10 and Node 16 module resolution, you can u
|
|
|
107
107
|
```json
|
|
108
108
|
{
|
|
109
109
|
"files": ["dist"],
|
|
110
|
-
"main": "./dist/cjs/index.
|
|
110
|
+
"main": "./dist/cjs/index.js",
|
|
111
111
|
"module": "./dist/es/index.mjs",
|
|
112
112
|
"types": "./dist/cjs/index.d.ts",
|
|
113
113
|
"exports": {
|
|
114
114
|
"import": {
|
|
115
|
-
"types": "./dist/es/index.d.
|
|
116
|
-
"default": "./dist/es/index.
|
|
115
|
+
"types": "./dist/es/index.d.ts",
|
|
116
|
+
"default": "./dist/es/index.js"
|
|
117
117
|
},
|
|
118
118
|
"require": {
|
|
119
119
|
"types": "./dist/cjs/index.d.cts",
|
|
@@ -268,6 +268,7 @@ If you're using `"use client"` or `"use server"` in a file that used as a depend
|
|
|
268
268
|
- Types (`--dts`): Generate TypeScript declaration files along with assets.
|
|
269
269
|
- Minify (`-m`): Compress output.
|
|
270
270
|
- Watch (`-w`): Watch for source file changes.
|
|
271
|
+
- No Clean(`--no-clean`): Do not clean the dist folder before building. (default: `false`)
|
|
271
272
|
|
|
272
273
|
```sh
|
|
273
274
|
cd <project-root-dir>
|
|
@@ -323,6 +324,21 @@ You can use `index.<export-type>.<ext>` to override the input source file for sp
|
|
|
323
324
|
|
|
324
325
|
This will match the export name `"react-server"` and `"edge-light"` then use the corresponding input source file to build the bundle.
|
|
325
326
|
|
|
327
|
+
#### Auto Development and Production Mode
|
|
328
|
+
|
|
329
|
+
`process.env.NODE_ENV` is injected by default if present that you don't need to manually inject yourself. If you need to separate the development build and production build, `bunchee` provides different export conditions for development and production mode with `development` and `production` export conditions.
|
|
330
|
+
|
|
331
|
+
```json
|
|
332
|
+
{
|
|
333
|
+
"exports": {
|
|
334
|
+
"development": "./dist/index.development.js",
|
|
335
|
+
"production": "./dist/index.production.js"
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Then you can use `bunchee` to build the development bundle and production bundle automatically.
|
|
341
|
+
|
|
326
342
|
### Wildcard Exports
|
|
327
343
|
|
|
328
344
|
Bunchee implements the Node.js feature of using the asterisk `*` as a wildcard to match the exportable entry files.
|
|
@@ -439,6 +455,7 @@ await bundle(path.resolve('./src/index.ts'), {
|
|
|
439
455
|
target: 'es2015', // ES syntax target
|
|
440
456
|
runtime: 'nodejs', // 'browser' | 'nodejs'
|
|
441
457
|
cwd: process.cwd(), // string
|
|
458
|
+
clean: true, // boolean
|
|
442
459
|
})
|
|
443
460
|
```
|
|
444
461
|
|
package/dist/bin/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ var path = require('path');
|
|
|
3
3
|
var arg = require('arg');
|
|
4
4
|
var fs = require('fs');
|
|
5
5
|
var fsp = require('fs/promises');
|
|
6
|
+
require('rimraf');
|
|
6
7
|
var require$$0 = require('tty');
|
|
7
8
|
var bunchee = require('bunchee');
|
|
8
9
|
|
|
@@ -25,6 +26,7 @@ const availableExtensions = new Set([
|
|
|
25
26
|
'mts'
|
|
26
27
|
]);
|
|
27
28
|
const SRC = 'src';
|
|
29
|
+
const DIST = 'dist';
|
|
28
30
|
const dtsExtensionsMap = {
|
|
29
31
|
js: 'd.ts',
|
|
30
32
|
cjs: 'd.cts',
|
|
@@ -36,6 +38,12 @@ const tsExtensions = new Set([
|
|
|
36
38
|
'cts',
|
|
37
39
|
'mts'
|
|
38
40
|
]);
|
|
41
|
+
const DEFAULT_TS_CONFIG = {
|
|
42
|
+
compilerOptions: {
|
|
43
|
+
module: 'ESNext',
|
|
44
|
+
moduleResolution: 'bundler'
|
|
45
|
+
}
|
|
46
|
+
};
|
|
39
47
|
|
|
40
48
|
function getDefaultExportFromCjs (x) {
|
|
41
49
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -140,22 +148,372 @@ function fileExists(filePath) {
|
|
|
140
148
|
return fs__default.default.existsSync(filePath);
|
|
141
149
|
}
|
|
142
150
|
const hasAvailableExtension = (filename)=>availableExtensions.has(path__default.default.extname(filename).slice(1));
|
|
151
|
+
const hasCjsExtension = (filename)=>path__default.default.extname(filename) === '.cjs';
|
|
143
152
|
// TODO: add unit test
|
|
144
153
|
const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
|
|
154
|
+
const isTestFile = (filename)=>/\.(test|spec)$/.test(baseNameWithoutExtension(filename));
|
|
155
|
+
|
|
156
|
+
function getTypings(pkg) {
|
|
157
|
+
return pkg.types || pkg.typings;
|
|
158
|
+
}
|
|
159
|
+
// Reached the end of the export path
|
|
160
|
+
function isExportLike(field) {
|
|
161
|
+
if (typeof field === 'string') return true;
|
|
162
|
+
return Object.entries(field).every(// Every value is string and key is not start with '.'
|
|
163
|
+
([key, value])=>typeof value === 'string' && !key.startsWith('.'));
|
|
164
|
+
}
|
|
165
|
+
function constructFullExportCondition(exportCondition, packageType) {
|
|
166
|
+
let fullExportCond;
|
|
167
|
+
if (typeof exportCondition === 'string') {
|
|
168
|
+
const exportType = getExportTypeFromFile(exportCondition, packageType);
|
|
169
|
+
fullExportCond = {
|
|
170
|
+
[exportType]: exportCondition
|
|
171
|
+
};
|
|
172
|
+
} else {
|
|
173
|
+
const exportTypes = Object.keys(exportCondition);
|
|
174
|
+
fullExportCond = {};
|
|
175
|
+
exportTypes.forEach((exportType)=>{
|
|
176
|
+
const condition = exportCondition[exportType];
|
|
177
|
+
// Filter out nullable value
|
|
178
|
+
if (condition) {
|
|
179
|
+
fullExportCond[exportType] = condition;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
return fullExportCond;
|
|
184
|
+
}
|
|
185
|
+
function joinRelativePath(...segments) {
|
|
186
|
+
let result = path.join(...segments);
|
|
187
|
+
// If the first segment starts with '.', ensure the result does too.
|
|
188
|
+
if (segments[0] === '.' && !result.startsWith('.')) {
|
|
189
|
+
result = './' + result;
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
const getFirstExportPath = (fullExportCondition)=>{
|
|
194
|
+
// Handle all export cond { <require|import|default>: ... }
|
|
195
|
+
if (typeof fullExportCondition === 'object') {
|
|
196
|
+
for (const key of Object.keys(fullExportCondition)){
|
|
197
|
+
if (key.startsWith('.') || key === 'types') {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
return fullExportCondition[key];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return fullExportCondition;
|
|
204
|
+
};
|
|
205
|
+
function findExport(exportPath, exportCondition, paths, packageType, currentPath) {
|
|
206
|
+
// Skip `types` field, it cannot be the entry point
|
|
207
|
+
if (exportPath === 'types') return;
|
|
208
|
+
if (isExportLike(exportCondition)) {
|
|
209
|
+
const fullExportCondition = constructFullExportCondition(exportCondition, packageType);
|
|
210
|
+
if (exportPath.startsWith('.')) {
|
|
211
|
+
paths[exportPath] = {
|
|
212
|
+
...paths[exportPath],
|
|
213
|
+
...fullExportCondition
|
|
214
|
+
};
|
|
215
|
+
} else {
|
|
216
|
+
const exportJsBundlePath = getFirstExportPath(fullExportCondition);
|
|
217
|
+
// exportPath is exportType, import, require, ...
|
|
218
|
+
// merge to currentPath
|
|
219
|
+
paths[currentPath] = {
|
|
220
|
+
...paths[currentPath],
|
|
221
|
+
[exportPath]: exportJsBundlePath
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
Object.keys(exportCondition).forEach((subpath)=>{
|
|
227
|
+
if (subpath.startsWith('.')) {
|
|
228
|
+
// subpath is actual export path, ./a, ./b, ...
|
|
229
|
+
const nestedExportPath = joinRelativePath(currentPath, subpath);
|
|
230
|
+
const nestedExportCondition = exportCondition[subpath];
|
|
231
|
+
findExport(nestedExportPath, nestedExportCondition, paths, packageType, nestedExportPath);
|
|
232
|
+
} else {
|
|
233
|
+
// subpath is exportType, import, require, ...
|
|
234
|
+
const exportType = subpath;
|
|
235
|
+
const defaultPath = typeof exportCondition[subpath] === 'object' ? exportCondition[subpath].default : exportCondition[subpath];
|
|
236
|
+
const nestedExportCondition = {
|
|
237
|
+
[exportType]: defaultPath
|
|
238
|
+
};
|
|
239
|
+
findExport(exportPath, nestedExportCondition, paths, packageType, currentPath);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
*
|
|
245
|
+
* Convert package.exports field to paths mapping
|
|
246
|
+
* Example
|
|
247
|
+
*
|
|
248
|
+
* Input:
|
|
249
|
+
* {
|
|
250
|
+
* "./sub": {
|
|
251
|
+
* "import": {
|
|
252
|
+
* "types": "./sub.js",
|
|
253
|
+
* "default": "./sub.cjs",
|
|
254
|
+
* }
|
|
255
|
+
* }
|
|
256
|
+
* }
|
|
257
|
+
*
|
|
258
|
+
* Output:
|
|
259
|
+
* {
|
|
260
|
+
* "./sub": {
|
|
261
|
+
* "import": "./sub.js",
|
|
262
|
+
* "require": "./sub.cjs",
|
|
263
|
+
* "types": "./sub.d.ts",
|
|
264
|
+
* }
|
|
265
|
+
* }
|
|
266
|
+
*
|
|
267
|
+
*/ function parseExport(exportsCondition, packageType) {
|
|
268
|
+
const paths = {};
|
|
269
|
+
const initialPath = '.';
|
|
270
|
+
if (typeof exportsCondition === 'string') {
|
|
271
|
+
paths[initialPath] = constructFullExportCondition(exportsCondition, packageType);
|
|
272
|
+
} else if (typeof exportsCondition === 'object') {
|
|
273
|
+
if (isExportLike(exportsCondition)) {
|
|
274
|
+
paths[initialPath] = constructFullExportCondition(exportsCondition, packageType);
|
|
275
|
+
} else {
|
|
276
|
+
Object.keys(exportsCondition).forEach((key)=>{
|
|
277
|
+
const exportCondition = exportsCondition[key];
|
|
278
|
+
findExport(key, exportCondition, paths, packageType, initialPath);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return paths;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Get package exports paths
|
|
286
|
+
*
|
|
287
|
+
* Example:
|
|
288
|
+
*
|
|
289
|
+
* ```json
|
|
290
|
+
* {
|
|
291
|
+
* "exports": {
|
|
292
|
+
* ".": {
|
|
293
|
+
* "require": "./dist/index.cjs",
|
|
294
|
+
* "module": "./dist/index.esm.js",
|
|
295
|
+
* "default": "./dist/index.esm.js"
|
|
296
|
+
* },
|
|
297
|
+
* "./foo": {
|
|
298
|
+
* "require": "./dist/foo.cjs",
|
|
299
|
+
* "module": "./dist/foo.esm.js",
|
|
300
|
+
* "default": "./dist/foo.esm.js"
|
|
301
|
+
* }
|
|
302
|
+
* }
|
|
303
|
+
*
|
|
304
|
+
* ```
|
|
305
|
+
*
|
|
306
|
+
* will be parsed to:
|
|
307
|
+
*
|
|
308
|
+
* ```js
|
|
309
|
+
* {
|
|
310
|
+
* '.': {
|
|
311
|
+
* main: './dist/index.cjs',
|
|
312
|
+
* module: './dist/index.esm.js',
|
|
313
|
+
* export: './dist/index.esm.js'
|
|
314
|
+
* },
|
|
315
|
+
* './foo': {
|
|
316
|
+
* main: './dist/foo.cjs',
|
|
317
|
+
* module: './dist/foo.esm.js',
|
|
318
|
+
* export: './dist/foo.esm.js'
|
|
319
|
+
* }
|
|
320
|
+
*
|
|
321
|
+
*
|
|
322
|
+
* pkg.main and pkg.module will be added to ['.'] if exists
|
|
323
|
+
*/ function getExportPaths(pkg, resolvedWildcardExports) {
|
|
324
|
+
var _pathsMap_;
|
|
325
|
+
let pathsMap = {};
|
|
326
|
+
const packageType = getPackageType(pkg);
|
|
327
|
+
const isEsmPackage = isESModulePackage(packageType);
|
|
328
|
+
const exportsConditions = resolvedWildcardExports != null ? resolvedWildcardExports : pkg.exports;
|
|
329
|
+
if (exportsConditions) {
|
|
330
|
+
const paths = parseExport(exportsConditions, packageType);
|
|
331
|
+
pathsMap = {
|
|
332
|
+
...pathsMap,
|
|
333
|
+
...paths
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
// main export '.' from main/module/typings
|
|
337
|
+
const defaultMainExport = constructFullExportCondition({
|
|
338
|
+
[isEsmPackage ? 'import' : 'require']: pkg.main,
|
|
339
|
+
module: pkg.module,
|
|
340
|
+
types: getTypings(pkg)
|
|
341
|
+
}, packageType);
|
|
342
|
+
if (!isEsmPackage && ((_pathsMap_ = pathsMap['.']) == null ? void 0 : _pathsMap_['require'])) {
|
|
343
|
+
// pathsMap's exports.require are prioritized.
|
|
344
|
+
defaultMainExport['require'] = pathsMap['.']['require'];
|
|
345
|
+
}
|
|
346
|
+
// Merge the main export into '.' paths
|
|
347
|
+
const mainExport = {
|
|
348
|
+
...pathsMap['.'],
|
|
349
|
+
...defaultMainExport
|
|
350
|
+
};
|
|
351
|
+
// main export is not empty
|
|
352
|
+
if (Object.keys(mainExport).length > 0) {
|
|
353
|
+
pathsMap['.'] = {
|
|
354
|
+
...pathsMap['.'],
|
|
355
|
+
...mainExport
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
return pathsMap;
|
|
359
|
+
}
|
|
360
|
+
function getPackageType(pkg) {
|
|
361
|
+
return pkg.type || 'commonjs';
|
|
362
|
+
}
|
|
363
|
+
function isESModulePackage(packageType) {
|
|
364
|
+
return packageType === 'module';
|
|
365
|
+
}
|
|
366
|
+
function getExportTypeFromFile(filename, pkgType) {
|
|
367
|
+
const isESModule = isESModulePackage(pkgType);
|
|
368
|
+
const isCjsExt = filename.endsWith('.cjs');
|
|
369
|
+
const isEsmExt = filename.endsWith('.mjs');
|
|
370
|
+
const exportType = isEsmExt ? 'import' : isCjsExt ? 'require' : isESModule ? 'import' : 'require';
|
|
371
|
+
return exportType;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function lint$1(pkg) {
|
|
375
|
+
const { name, main, exports } = pkg;
|
|
376
|
+
const isESM = isESModulePackage(pkg.type);
|
|
377
|
+
const exportPaths = getExportPaths(pkg);
|
|
378
|
+
if (!name) {
|
|
379
|
+
logger.warn('Missing package name');
|
|
380
|
+
}
|
|
381
|
+
const state = {
|
|
382
|
+
badMainExtension: false,
|
|
383
|
+
badMainExport: false,
|
|
384
|
+
invalidExportsFieldType: false,
|
|
385
|
+
badCjsRequireExport: {
|
|
386
|
+
value: false,
|
|
387
|
+
paths: []
|
|
388
|
+
},
|
|
389
|
+
badCjsImportExport: {
|
|
390
|
+
value: false,
|
|
391
|
+
paths: []
|
|
392
|
+
},
|
|
393
|
+
badEsmRequireExport: {
|
|
394
|
+
value: false,
|
|
395
|
+
paths: []
|
|
396
|
+
},
|
|
397
|
+
badEsmImportExport: {
|
|
398
|
+
value: false,
|
|
399
|
+
paths: []
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
// Validate ESM package
|
|
403
|
+
if (isESM) {
|
|
404
|
+
if (main && hasCjsExtension(main)) {
|
|
405
|
+
state.badMainExtension = true;
|
|
406
|
+
}
|
|
407
|
+
if (exports) {
|
|
408
|
+
if (typeof exports === 'string') {
|
|
409
|
+
if (hasCjsExtension(exports)) {
|
|
410
|
+
state.badMainExport = true;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
if (typeof exports !== 'object') {
|
|
414
|
+
state.invalidExportsFieldType = true;
|
|
415
|
+
} else {
|
|
416
|
+
Object.keys(exportPaths).forEach((key)=>{
|
|
417
|
+
const exportConditions = exportPaths[key];
|
|
418
|
+
if (typeof exportConditions === 'object') {
|
|
419
|
+
var // @ts-ignore TODO: fix the type
|
|
420
|
+
_exportConditions_require, // @ts-ignore TODO: fix the type
|
|
421
|
+
_exportConditions_import;
|
|
422
|
+
var _exportConditions_require_default;
|
|
423
|
+
const requirePath = (_exportConditions_require_default = (_exportConditions_require = exportConditions.require) == null ? void 0 : _exportConditions_require.default) != null ? _exportConditions_require_default : exportConditions.require;
|
|
424
|
+
var _exportConditions_import_default;
|
|
425
|
+
const importPath = (_exportConditions_import_default = (_exportConditions_import = exportConditions.import) == null ? void 0 : _exportConditions_import.default) != null ? _exportConditions_import_default : exportConditions.import;
|
|
426
|
+
const requireExt = requirePath && path__default.default.extname(requirePath);
|
|
427
|
+
const importExt = importPath && path__default.default.extname(importPath);
|
|
428
|
+
if (requireExt === '.mjs' || requireExt === '.js') {
|
|
429
|
+
state.badEsmRequireExport.value = true;
|
|
430
|
+
state.badEsmRequireExport.paths.push(requirePath);
|
|
431
|
+
}
|
|
432
|
+
if (importExt === '.cjs') {
|
|
433
|
+
state.badEsmImportExport.value = true;
|
|
434
|
+
state.badEsmImportExport.paths.push(importPath);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
} else {
|
|
441
|
+
// Validate CJS package
|
|
442
|
+
if (exports) {
|
|
443
|
+
if (typeof exports === 'string') {
|
|
444
|
+
if (!hasCjsExtension(exports)) {
|
|
445
|
+
state.badMainExport = true;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (typeof exports !== 'object') {
|
|
449
|
+
state.invalidExportsFieldType = true;
|
|
450
|
+
} else {
|
|
451
|
+
Object.keys(exportPaths).forEach((key)=>{
|
|
452
|
+
const exportConditions = exportPaths[key];
|
|
453
|
+
if (typeof exportConditions === 'object') {
|
|
454
|
+
var // @ts-ignore TODO: fix the type
|
|
455
|
+
_exportConditions_require, // @ts-ignore TODO: fix the type
|
|
456
|
+
_exportConditions_import;
|
|
457
|
+
var _exportConditions_require_default;
|
|
458
|
+
const requirePath = (_exportConditions_require_default = (_exportConditions_require = exportConditions.require) == null ? void 0 : _exportConditions_require.default) != null ? _exportConditions_require_default : exportConditions.require;
|
|
459
|
+
var _exportConditions_import_default;
|
|
460
|
+
const importPath = (_exportConditions_import_default = (_exportConditions_import = exportConditions.import) == null ? void 0 : _exportConditions_import.default) != null ? _exportConditions_import_default : exportConditions.import;
|
|
461
|
+
const requireExt = requirePath && path__default.default.extname(requirePath);
|
|
462
|
+
const importExt = importPath && path__default.default.extname(importPath);
|
|
463
|
+
if (requireExt === '.mjs') {
|
|
464
|
+
state.badCjsRequireExport.value = true;
|
|
465
|
+
state.badCjsRequireExport.paths.push(requirePath);
|
|
466
|
+
}
|
|
467
|
+
if (importExt === '.js' || importExt === '.cjs') {
|
|
468
|
+
state.badCjsImportExport.value = true;
|
|
469
|
+
state.badCjsImportExport.paths.push(importPath);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (state.badMainExtension) {
|
|
477
|
+
logger.warn('Cannot export `main` field with .cjs extension in ESM package, only .mjs and .js extensions are allowed');
|
|
478
|
+
}
|
|
479
|
+
if (state.badMainExport) {
|
|
480
|
+
logger.warn('Cannot export `exports` field with .cjs extension in ESM package, only .mjs and .js extensions are allowed');
|
|
481
|
+
}
|
|
482
|
+
if (state.invalidExportsFieldType) {
|
|
483
|
+
logger.warn('Invalid exports field type, only object or string is allowed');
|
|
484
|
+
}
|
|
485
|
+
if (state.badCjsRequireExport.value) {
|
|
486
|
+
logger.warn('Cannot export `require` field with .mjs extension in CJS package, only .cjs and .js extensions are allowed');
|
|
487
|
+
state.badCjsRequireExport.paths.forEach((p)=>{
|
|
488
|
+
logger.warn(` ${p}`);
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
if (state.badCjsImportExport.value) {
|
|
492
|
+
logger.warn('Cannot export `import` field with .js or .cjs extension in CJS package, only .mjs extensions are allowed');
|
|
493
|
+
state.badCjsImportExport.paths.forEach((p)=>{
|
|
494
|
+
logger.warn(` ${p}`);
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
if (state.badEsmRequireExport.value) {
|
|
498
|
+
logger.warn('Cannot export `require` field with .js or .mjs extension in ESM package, only .cjs extensions are allowed');
|
|
499
|
+
state.badEsmRequireExport.paths.forEach((p)=>{
|
|
500
|
+
logger.warn(` ${p}`);
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
if (state.badEsmImportExport.value) {
|
|
504
|
+
logger.warn('Cannot export `import` field with .cjs extension in ESM package, only .js and .mjs extensions are allowed');
|
|
505
|
+
state.badEsmImportExport.paths.forEach((p)=>{
|
|
506
|
+
logger.warn(` ${p}`);
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
}
|
|
145
510
|
|
|
146
|
-
var version = "4.
|
|
511
|
+
var version = "4.4.0";
|
|
147
512
|
|
|
148
513
|
function relativify(path) {
|
|
149
514
|
return path.startsWith('.') ? path : `./${path}`;
|
|
150
515
|
}
|
|
151
516
|
|
|
152
|
-
const DIST = 'dist';
|
|
153
|
-
const DEFAULT_TS_CONFIG = {
|
|
154
|
-
compilerOptions: {
|
|
155
|
-
module: 'ESNext',
|
|
156
|
-
moduleResolution: 'bundler'
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
517
|
// Output with posix style in package.json
|
|
160
518
|
function getDistPath(...subPaths) {
|
|
161
519
|
return `./${DIST}/${subPaths.join('/')}`;
|
|
@@ -213,7 +571,7 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
213
571
|
// Search folder/<index>.<ext> convention entries
|
|
214
572
|
for (const extension of availableExtensions){
|
|
215
573
|
const indexFile = path__default.default.join(dirent.name, `index.${extension}`);
|
|
216
|
-
if (fs__default.default.existsSync(indexFile)) {
|
|
574
|
+
if (fs__default.default.existsSync(indexFile) && !isTestFile(indexFile)) {
|
|
217
575
|
exportsEntries.set(dirent.name, indexFile);
|
|
218
576
|
break;
|
|
219
577
|
}
|
|
@@ -227,7 +585,7 @@ async function collectSourceEntries(sourceFolderPath) {
|
|
|
227
585
|
if (isBinFile) {
|
|
228
586
|
bins.set('.', dirent.name);
|
|
229
587
|
} else {
|
|
230
|
-
if (hasAvailableExtension(dirent.name)) {
|
|
588
|
+
if (hasAvailableExtension(dirent.name) && !isTestFile(dirent.name)) {
|
|
231
589
|
exportsEntries.set(baseName, dirent.name);
|
|
232
590
|
}
|
|
233
591
|
}
|
|
@@ -373,6 +731,7 @@ Options:
|
|
|
373
731
|
--prepare auto configure package.json exports for building
|
|
374
732
|
--external <mod> specify an external dependency, separate by comma
|
|
375
733
|
--no-external do not bundle external dependencies
|
|
734
|
+
--no-clean do not clean dist folder before building, default: false
|
|
376
735
|
--target <target> js features target: swc target es versions. default: es2015
|
|
377
736
|
--runtime <runtime> build runtime (nodejs, browser). default: browser
|
|
378
737
|
--env <env> inlined process env variables, separate by comma. default: NODE_ENV
|
|
@@ -383,21 +742,12 @@ Options:
|
|
|
383
742
|
function help() {
|
|
384
743
|
logger.log(helpMessage);
|
|
385
744
|
}
|
|
386
|
-
async function
|
|
745
|
+
async function lint(cwd) {
|
|
387
746
|
// Not package.json detected, skip package linting
|
|
388
747
|
if (!await hasPackageJson(cwd)) {
|
|
389
748
|
return;
|
|
390
749
|
}
|
|
391
|
-
|
|
392
|
-
const { formatMessage } = await import('publint/utils');
|
|
393
|
-
const { messages } = await publint({
|
|
394
|
-
pkgDir: cwd,
|
|
395
|
-
level: 'error'
|
|
396
|
-
});
|
|
397
|
-
const pkg = await getPackageMeta(cwd);
|
|
398
|
-
for (const message of messages){
|
|
399
|
-
console.log(formatMessage(message, pkg));
|
|
400
|
-
}
|
|
750
|
+
await lint$1(await getPackageMeta(cwd));
|
|
401
751
|
}
|
|
402
752
|
function parseCliArgs(argv) {
|
|
403
753
|
let args;
|
|
@@ -416,6 +766,7 @@ function parseCliArgs(argv) {
|
|
|
416
766
|
'--env': String,
|
|
417
767
|
'--external': String,
|
|
418
768
|
'--no-external': Boolean,
|
|
769
|
+
'--no-clean': Boolean,
|
|
419
770
|
'--prepare': Boolean,
|
|
420
771
|
'-h': '--help',
|
|
421
772
|
'-v': '--version',
|
|
@@ -442,6 +793,7 @@ function parseCliArgs(argv) {
|
|
|
442
793
|
runtime: args['--runtime'],
|
|
443
794
|
target: args['--target'],
|
|
444
795
|
external: !!args['--no-external'] ? null : args['--external'],
|
|
796
|
+
clean: !args['--no-clean'],
|
|
445
797
|
env: args['--env'],
|
|
446
798
|
prepare: !!args['--prepare']
|
|
447
799
|
};
|
|
@@ -449,7 +801,7 @@ function parseCliArgs(argv) {
|
|
|
449
801
|
}
|
|
450
802
|
async function run(args) {
|
|
451
803
|
var _args_external;
|
|
452
|
-
const { source, format, watch, minify, sourcemap, target, runtime, dts, env } = args;
|
|
804
|
+
const { source, format, watch, minify, sourcemap, target, runtime, dts, env, clean } = args;
|
|
453
805
|
const cwd = args.cwd || process.cwd();
|
|
454
806
|
const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined;
|
|
455
807
|
const bundleConfig = {
|
|
@@ -463,7 +815,8 @@ async function run(args) {
|
|
|
463
815
|
watch: !!watch,
|
|
464
816
|
minify: !!minify,
|
|
465
817
|
sourcemap: sourcemap === false ? false : true,
|
|
466
|
-
env: (env == null ? void 0 : env.split(',')) || []
|
|
818
|
+
env: (env == null ? void 0 : env.split(',')) || [],
|
|
819
|
+
clean
|
|
467
820
|
};
|
|
468
821
|
if (args.version) {
|
|
469
822
|
return logger.log(version);
|
|
@@ -475,6 +828,8 @@ async function run(args) {
|
|
|
475
828
|
return await prepare(cwd);
|
|
476
829
|
}
|
|
477
830
|
const entry = source ? path__default.default.resolve(cwd, source) : '';
|
|
831
|
+
// lint package
|
|
832
|
+
await lint(cwd);
|
|
478
833
|
try {
|
|
479
834
|
await bunchee.bundle(entry, bundleConfig);
|
|
480
835
|
} catch (err) {
|
|
@@ -492,7 +847,6 @@ async function run(args) {
|
|
|
492
847
|
// build mode
|
|
493
848
|
logger.log();
|
|
494
849
|
paint('✓', 'green', `bunchee ${version} build completed`);
|
|
495
|
-
await lintPackage(cwd);
|
|
496
850
|
}
|
|
497
851
|
async function main() {
|
|
498
852
|
let params, error;
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -4,8 +4,9 @@ var rollup = require('rollup');
|
|
|
4
4
|
var fsp = require('fs/promises');
|
|
5
5
|
var fs = require('fs');
|
|
6
6
|
var path = require('path');
|
|
7
|
-
var module$1 = require('module');
|
|
8
7
|
var require$$0 = require('tty');
|
|
8
|
+
var module$1 = require('module');
|
|
9
|
+
var rimraf = require('rimraf');
|
|
9
10
|
var pluginWasm = require('@rollup/plugin-wasm');
|
|
10
11
|
var rollupPluginSwc3 = require('rollup-plugin-swc3');
|
|
11
12
|
var commonjs = require('@rollup/plugin-commonjs');
|
|
@@ -14,6 +15,7 @@ var pluginNodeResolve = require('@rollup/plugin-node-resolve');
|
|
|
14
15
|
var replace = require('@rollup/plugin-replace');
|
|
15
16
|
var esmShim = require('@rollup/plugin-esm-shim');
|
|
16
17
|
var preserveDirectives = require('rollup-preserve-directives');
|
|
18
|
+
var CleanCSS = require('clean-css');
|
|
17
19
|
var pluginutils = require('@rollup/pluginutils');
|
|
18
20
|
var prettyBytes = require('pretty-bytes');
|
|
19
21
|
|
|
@@ -28,47 +30,9 @@ var json__default = /*#__PURE__*/_interopDefault(json);
|
|
|
28
30
|
var replace__default = /*#__PURE__*/_interopDefault(replace);
|
|
29
31
|
var esmShim__default = /*#__PURE__*/_interopDefault(esmShim);
|
|
30
32
|
var preserveDirectives__default = /*#__PURE__*/_interopDefault(preserveDirectives);
|
|
33
|
+
var CleanCSS__default = /*#__PURE__*/_interopDefault(CleanCSS);
|
|
31
34
|
var prettyBytes__default = /*#__PURE__*/_interopDefault(prettyBytes);
|
|
32
35
|
|
|
33
|
-
const availableExtensions = new Set([
|
|
34
|
-
'js',
|
|
35
|
-
'cjs',
|
|
36
|
-
'mjs',
|
|
37
|
-
'jsx',
|
|
38
|
-
'ts',
|
|
39
|
-
'tsx',
|
|
40
|
-
'cts',
|
|
41
|
-
'mts'
|
|
42
|
-
]);
|
|
43
|
-
const nodeResolveExtensions = [
|
|
44
|
-
'.mjs',
|
|
45
|
-
'.cjs',
|
|
46
|
-
'.js',
|
|
47
|
-
'.json',
|
|
48
|
-
'.node',
|
|
49
|
-
'.jsx'
|
|
50
|
-
];
|
|
51
|
-
const availableExportConventions = new Set([
|
|
52
|
-
'react-server',
|
|
53
|
-
'react-native',
|
|
54
|
-
'edge-light'
|
|
55
|
-
]);
|
|
56
|
-
const availableESExtensionsRegex = /\.(m|c)?[jt]sx?$/;
|
|
57
|
-
const SRC = 'src';
|
|
58
|
-
const dtsExtensionsMap = {
|
|
59
|
-
js: 'd.ts',
|
|
60
|
-
cjs: 'd.cts',
|
|
61
|
-
mjs: 'd.mts'
|
|
62
|
-
};
|
|
63
|
-
const disabledWarnings = new Set([
|
|
64
|
-
'MIXED_EXPORTS',
|
|
65
|
-
'PREFER_NAMED_EXPORTS',
|
|
66
|
-
'UNRESOLVED_IMPORT',
|
|
67
|
-
'THIS_IS_UNDEFINED',
|
|
68
|
-
'INVALID_ANNOTATION',
|
|
69
|
-
'UNUSED_EXTERNAL_IMPORT'
|
|
70
|
-
]);
|
|
71
|
-
|
|
72
36
|
function getDefaultExportFromCjs (x) {
|
|
73
37
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
74
38
|
}
|
|
@@ -121,6 +85,59 @@ picocolors.exports.createColors = createColors;
|
|
|
121
85
|
var picocolorsExports = picocolors.exports;
|
|
122
86
|
var pc = /*@__PURE__*/ getDefaultExportFromCjs(picocolorsExports);
|
|
123
87
|
|
|
88
|
+
const availableExtensions = new Set([
|
|
89
|
+
'js',
|
|
90
|
+
'cjs',
|
|
91
|
+
'mjs',
|
|
92
|
+
'jsx',
|
|
93
|
+
'ts',
|
|
94
|
+
'tsx',
|
|
95
|
+
'cts',
|
|
96
|
+
'mts'
|
|
97
|
+
]);
|
|
98
|
+
const nodeResolveExtensions = [
|
|
99
|
+
'.mjs',
|
|
100
|
+
'.cjs',
|
|
101
|
+
'.js',
|
|
102
|
+
'.json',
|
|
103
|
+
'.node',
|
|
104
|
+
'.jsx'
|
|
105
|
+
];
|
|
106
|
+
const suffixedExportConventions = new Set([
|
|
107
|
+
'react-server',
|
|
108
|
+
'react-native',
|
|
109
|
+
'edge-light',
|
|
110
|
+
'development',
|
|
111
|
+
'production'
|
|
112
|
+
]);
|
|
113
|
+
const availableESExtensionsRegex = /\.(m|c)?[jt]sx?$/;
|
|
114
|
+
const SRC = 'src';
|
|
115
|
+
const dtsExtensionsMap = {
|
|
116
|
+
js: 'd.ts',
|
|
117
|
+
cjs: 'd.cts',
|
|
118
|
+
mjs: 'd.mts'
|
|
119
|
+
};
|
|
120
|
+
const disabledWarnings = new Set([
|
|
121
|
+
'MIXED_EXPORTS',
|
|
122
|
+
'PREFER_NAMED_EXPORTS',
|
|
123
|
+
'UNRESOLVED_IMPORT',
|
|
124
|
+
'THIS_IS_UNDEFINED',
|
|
125
|
+
'INVALID_ANNOTATION',
|
|
126
|
+
'UNUSED_EXTERNAL_IMPORT'
|
|
127
|
+
]);
|
|
128
|
+
const tsExtensions = new Set([
|
|
129
|
+
'ts',
|
|
130
|
+
'tsx',
|
|
131
|
+
'cts',
|
|
132
|
+
'mts'
|
|
133
|
+
]);
|
|
134
|
+
const DEFAULT_TS_CONFIG = {
|
|
135
|
+
compilerOptions: {
|
|
136
|
+
module: 'ESNext',
|
|
137
|
+
moduleResolution: 'bundler'
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
124
141
|
const defaultColorFn = (text)=>text;
|
|
125
142
|
function color(prefixColor) {
|
|
126
143
|
return pc.isColorSupported ? pc[prefixColor] : defaultColorFn;
|
|
@@ -154,15 +171,24 @@ async function getPackageMeta(cwd) {
|
|
|
154
171
|
} catch (_) {}
|
|
155
172
|
return targetPackageJson;
|
|
156
173
|
}
|
|
174
|
+
function isTypescriptFile(filename) {
|
|
175
|
+
const ext = path__default.default.extname(filename).slice(1);
|
|
176
|
+
return tsExtensions.has(ext);
|
|
177
|
+
}
|
|
157
178
|
function fileExists(filePath) {
|
|
158
179
|
return fs__default.default.existsSync(filePath);
|
|
159
180
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
181
|
+
async function removeDir(dirPath) {
|
|
182
|
+
try {
|
|
183
|
+
const dirStat = await fsp__default.default.stat(dirPath);
|
|
184
|
+
if (dirStat.isDirectory()) {
|
|
185
|
+
await rimraf.rimraf(dirPath);
|
|
186
|
+
}
|
|
187
|
+
} catch (err) {
|
|
188
|
+
if (err.code !== 'ENOENT') {
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
166
192
|
}
|
|
167
193
|
const isNotNull = (n)=>Boolean(n);
|
|
168
194
|
function resolveSourceFile(cwd, filename) {
|
|
@@ -191,7 +217,7 @@ async function getSourcePathFromExportPath(cwd, exportPath, exportType) {
|
|
|
191
217
|
if (exportPath === '.') exportPath = './index';
|
|
192
218
|
// Find convention-based source file for specific export types
|
|
193
219
|
// $binary represents `pkg.bin`
|
|
194
|
-
if (
|
|
220
|
+
if (suffixedExportConventions.has(exportType) && exportType !== '$binary') {
|
|
195
221
|
const filename = await findSourceEntryFile(cwd, exportPath, exportType, ext);
|
|
196
222
|
if (filename) return filename;
|
|
197
223
|
}
|
|
@@ -207,7 +233,6 @@ function filePathWithoutExtension(file) {
|
|
|
207
233
|
}
|
|
208
234
|
const nonNullable = (n)=>Boolean(n);
|
|
209
235
|
const hasAvailableExtension = (filename)=>availableExtensions.has(path__default.default.extname(filename).slice(1));
|
|
210
|
-
const hasCjsExtension = (filename)=>path__default.default.extname(filename) === '.cjs';
|
|
211
236
|
// TODO: add unit test
|
|
212
237
|
const baseNameWithoutExtension = (filename)=>path__default.default.basename(filename, path__default.default.extname(filename));
|
|
213
238
|
|
|
@@ -249,14 +274,6 @@ async function convertCompilerOptions(cwd, json) {
|
|
|
249
274
|
return ts.convertCompilerOptionsFromJson(json, './');
|
|
250
275
|
}
|
|
251
276
|
|
|
252
|
-
function minifyCSS(content) {
|
|
253
|
-
return content.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$|(?:^|\s)(\s+)|\s*([\{\};,:])\s*|\s+(!)\s+/g, (match, p1, p2, p3, p4)=>{
|
|
254
|
-
if (p1) return p1 === ' ' ? '' : p1;
|
|
255
|
-
if (p2) return ' ';
|
|
256
|
-
if (p3) return p3;
|
|
257
|
-
if (p4) return '!';
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
277
|
const helpers = {
|
|
261
278
|
cssImport: {
|
|
262
279
|
// have to assign r.type = 'text/css' to make it work in Safari
|
|
@@ -284,6 +301,10 @@ export default sheet`;
|
|
|
284
301
|
}
|
|
285
302
|
}
|
|
286
303
|
};
|
|
304
|
+
const cleanCssInstance = new CleanCSS__default.default({});
|
|
305
|
+
function minify(code) {
|
|
306
|
+
return cleanCssInstance.minify(code).styles;
|
|
307
|
+
}
|
|
287
308
|
function inlineCss(options) {
|
|
288
309
|
const cssIds = new Set();
|
|
289
310
|
var _options_exclude;
|
|
@@ -296,7 +317,7 @@ function inlineCss(options) {
|
|
|
296
317
|
transform (code, id) {
|
|
297
318
|
if (!filter(id)) return;
|
|
298
319
|
if (options.skip) return '';
|
|
299
|
-
const cssCode =
|
|
320
|
+
const cssCode = minify(code);
|
|
300
321
|
cssIds.add(id);
|
|
301
322
|
return {
|
|
302
323
|
code: helpers.cssImport.create(cssCode),
|
|
@@ -305,7 +326,7 @@ function inlineCss(options) {
|
|
|
305
326
|
}
|
|
306
327
|
};
|
|
307
328
|
},
|
|
308
|
-
renderChunk (code
|
|
329
|
+
renderChunk (code) {
|
|
309
330
|
const dependenciesIds = this.getModuleIds();
|
|
310
331
|
let foundCss = false;
|
|
311
332
|
for (const depId of dependenciesIds){
|
|
@@ -428,6 +449,18 @@ function joinRelativePath(...segments) {
|
|
|
428
449
|
}
|
|
429
450
|
return result;
|
|
430
451
|
}
|
|
452
|
+
const getFirstExportPath = (fullExportCondition)=>{
|
|
453
|
+
// Handle all export cond { <require|import|default>: ... }
|
|
454
|
+
if (typeof fullExportCondition === 'object') {
|
|
455
|
+
for (const key of Object.keys(fullExportCondition)){
|
|
456
|
+
if (key.startsWith('.') || key === 'types') {
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
return fullExportCondition[key];
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return fullExportCondition;
|
|
463
|
+
};
|
|
431
464
|
function findExport(exportPath, exportCondition, paths, packageType, currentPath) {
|
|
432
465
|
// Skip `types` field, it cannot be the entry point
|
|
433
466
|
if (exportPath === 'types') return;
|
|
@@ -439,11 +472,12 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
|
|
|
439
472
|
...fullExportCondition
|
|
440
473
|
};
|
|
441
474
|
} else {
|
|
475
|
+
const exportJsBundlePath = getFirstExportPath(fullExportCondition);
|
|
442
476
|
// exportPath is exportType, import, require, ...
|
|
443
477
|
// merge to currentPath
|
|
444
478
|
paths[currentPath] = {
|
|
445
479
|
...paths[currentPath],
|
|
446
|
-
[exportPath]:
|
|
480
|
+
[exportPath]: exportJsBundlePath
|
|
447
481
|
};
|
|
448
482
|
}
|
|
449
483
|
return;
|
|
@@ -545,10 +579,10 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
|
|
|
545
579
|
*
|
|
546
580
|
*
|
|
547
581
|
* pkg.main and pkg.module will be added to ['.'] if exists
|
|
548
|
-
*/ function getExportPaths(pkg,
|
|
582
|
+
*/ function getExportPaths(pkg, resolvedWildcardExports) {
|
|
549
583
|
var _pathsMap_;
|
|
550
584
|
let pathsMap = {};
|
|
551
|
-
const packageType =
|
|
585
|
+
const packageType = getPackageType(pkg);
|
|
552
586
|
const isEsmPackage = isESModulePackage(packageType);
|
|
553
587
|
const exportsConditions = resolvedWildcardExports != null ? resolvedWildcardExports : pkg.exports;
|
|
554
588
|
if (exportsConditions) {
|
|
@@ -558,9 +592,6 @@ function findExport(exportPath, exportCondition, paths, packageType, currentPath
|
|
|
558
592
|
...paths
|
|
559
593
|
};
|
|
560
594
|
}
|
|
561
|
-
if (isEsmPackage && pkg.main && hasCjsExtension(pkg.main)) {
|
|
562
|
-
exit('Cannot export main field with .cjs extension in ESM package, only .mjs and .js extensions are allowed');
|
|
563
|
-
}
|
|
564
595
|
// main export '.' from main/module/typings
|
|
565
596
|
const defaultMainExport = constructFullExportCondition({
|
|
566
597
|
[isEsmPackage ? 'import' : 'require']: pkg.main,
|
|
@@ -668,7 +699,8 @@ const swcMinifyOptions = {
|
|
|
668
699
|
toplevel: true
|
|
669
700
|
}
|
|
670
701
|
};
|
|
671
|
-
|
|
702
|
+
// return { 'process.env.<key>': '<value>' }
|
|
703
|
+
function getBuildEnv(envs, exportConditions) {
|
|
672
704
|
if (!envs.includes('NODE_ENV')) {
|
|
673
705
|
envs.push('NODE_ENV');
|
|
674
706
|
}
|
|
@@ -679,10 +711,17 @@ function getBuildEnv(envs) {
|
|
|
679
711
|
}
|
|
680
712
|
return acc;
|
|
681
713
|
}, {});
|
|
714
|
+
// For development and production convention, we override the NODE_ENV value
|
|
715
|
+
const exportConditionNames = new Set(Object.keys(exportConditions));
|
|
716
|
+
if (exportConditionNames.has('development')) {
|
|
717
|
+
envVars['process.env.NODE_ENV'] = JSON.stringify('development');
|
|
718
|
+
} else if (exportConditionNames.has('production')) {
|
|
719
|
+
envVars['process.env.NODE_ENV'] = JSON.stringify('production');
|
|
720
|
+
}
|
|
682
721
|
return envVars;
|
|
683
722
|
}
|
|
684
723
|
/**
|
|
685
|
-
* return {
|
|
724
|
+
* return {
|
|
686
725
|
* <absolute source path>: <pkg>/<export>
|
|
687
726
|
* }
|
|
688
727
|
*/ function getReversedAlias(entries) {
|
|
@@ -712,6 +751,7 @@ async function buildInputConfig(entry, options, buildContext, exportCondition, d
|
|
|
712
751
|
externals.push(entryFilePath);
|
|
713
752
|
}
|
|
714
753
|
}
|
|
754
|
+
const envValues = getBuildEnv(options.env || [], exportCondition.export);
|
|
715
755
|
const { useTypeScript } = buildContext;
|
|
716
756
|
const { runtime, target: jscTarget, minify: shouldMinify } = options;
|
|
717
757
|
const hasSpecifiedTsTarget = Boolean(tsCompilerOptions.target && tsConfigPath);
|
|
@@ -794,7 +834,7 @@ async function buildInputConfig(entry, options, buildContext, exportCondition, d
|
|
|
794
834
|
preserveDirectives__default.default(),
|
|
795
835
|
prependDirectives(),
|
|
796
836
|
replace__default.default({
|
|
797
|
-
values:
|
|
837
|
+
values: envValues,
|
|
798
838
|
preventAssignment: true
|
|
799
839
|
}),
|
|
800
840
|
pluginNodeResolve.nodeResolve({
|
|
@@ -959,48 +999,48 @@ async function buildEntryConfig(bundleConfig, pluginContext, dts) {
|
|
|
959
999
|
}
|
|
960
1000
|
return await Promise.all(configs);
|
|
961
1001
|
}
|
|
1002
|
+
async function collectEntry(// export type, e.g. react-server, edge-light those special cases required suffix
|
|
1003
|
+
exportType, options) {
|
|
1004
|
+
const { cwd, pkg, entries, entryPath, exportCondRef, entryExport } = options;
|
|
1005
|
+
let exportCondForType = {
|
|
1006
|
+
...exportCondRef
|
|
1007
|
+
};
|
|
1008
|
+
// Special cases of export type, only pass down the exportPaths for the type
|
|
1009
|
+
if (suffixedExportConventions.has(exportType)) {
|
|
1010
|
+
exportCondForType = {
|
|
1011
|
+
[exportType]: exportCondRef[exportType]
|
|
1012
|
+
};
|
|
1013
|
+
// Basic export type, pass down the exportPaths with erasing the special ones
|
|
1014
|
+
} else {
|
|
1015
|
+
for (const exportType of suffixedExportConventions){
|
|
1016
|
+
delete exportCondForType[exportType];
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
let source = entryPath;
|
|
1020
|
+
if (source) {
|
|
1021
|
+
source = resolveSourceFile(cwd, source);
|
|
1022
|
+
} else {
|
|
1023
|
+
source = await getSourcePathFromExportPath(cwd, entryExport, exportType);
|
|
1024
|
+
}
|
|
1025
|
+
if (!source) {
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
const exportCondition = {
|
|
1029
|
+
source,
|
|
1030
|
+
name: entryExport,
|
|
1031
|
+
export: exportCondForType
|
|
1032
|
+
};
|
|
1033
|
+
const nameWithExportPath = pkg.name ? path__default.default.join(pkg.name, exportCondition.name) : exportCondition.name;
|
|
1034
|
+
const needsDelimiter = !nameWithExportPath.endsWith('.') && exportType;
|
|
1035
|
+
const entryImportPath = nameWithExportPath + (needsDelimiter ? '.' : '') + exportType;
|
|
1036
|
+
entries[entryImportPath] = exportCondition;
|
|
1037
|
+
}
|
|
962
1038
|
/*
|
|
963
1039
|
* build configs for each entry from package exports
|
|
964
1040
|
*
|
|
965
1041
|
* return { <pkg>/<export>: { input: InputOptions, output: OutputOptions[] }
|
|
966
1042
|
*/ async function collectEntries(pkg, entryPath, exportPaths, cwd) {
|
|
967
1043
|
const entries = {};
|
|
968
|
-
async function collectEntry(// export type, e.g. react-server, edge-light those special cases required suffix
|
|
969
|
-
exportType, exportCondRef, // export name, e.g. ./<export-path> in exports field of package.json
|
|
970
|
-
entryExport) {
|
|
971
|
-
let exportCondForType = {
|
|
972
|
-
...exportCondRef
|
|
973
|
-
};
|
|
974
|
-
// Special cases of export type, only pass down the exportPaths for the type
|
|
975
|
-
if (availableExportConventions.has(exportType)) {
|
|
976
|
-
exportCondForType = {
|
|
977
|
-
[exportType]: exportCondRef[exportType]
|
|
978
|
-
};
|
|
979
|
-
// Basic export type, pass down the exportPaths with erasing the special ones
|
|
980
|
-
} else {
|
|
981
|
-
for (const exportType of availableExportConventions){
|
|
982
|
-
delete exportCondForType[exportType];
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
let source = entryPath;
|
|
986
|
-
if (source) {
|
|
987
|
-
source = resolveSourceFile(cwd, source);
|
|
988
|
-
} else {
|
|
989
|
-
source = await getSourcePathFromExportPath(cwd, entryExport, exportType);
|
|
990
|
-
}
|
|
991
|
-
if (!source) {
|
|
992
|
-
return undefined;
|
|
993
|
-
}
|
|
994
|
-
const exportCondition = {
|
|
995
|
-
source,
|
|
996
|
-
name: entryExport,
|
|
997
|
-
export: exportCondForType
|
|
998
|
-
};
|
|
999
|
-
const nameWithExportPath = pkg.name ? path__default.default.join(pkg.name, exportCondition.name) : exportCondition.name;
|
|
1000
|
-
const needsDelimiter = !nameWithExportPath.endsWith('.') && exportType;
|
|
1001
|
-
const entryImportPath = nameWithExportPath + (needsDelimiter ? '.' : '') + exportType;
|
|
1002
|
-
entries[entryImportPath] = exportCondition;
|
|
1003
|
-
}
|
|
1004
1044
|
const binaryExports = pkg.bin;
|
|
1005
1045
|
if (binaryExports) {
|
|
1006
1046
|
// binDistPaths: [ [ 'bin1', './dist/bin1.js'], [ 'bin2', './dist/bin2.js'] ]
|
|
@@ -1036,11 +1076,19 @@ async function buildEntryConfig(bundleConfig, pluginContext, dts) {
|
|
|
1036
1076
|
}
|
|
1037
1077
|
const collectEntriesPromises = Object.keys(exportPaths).map(async (entryExport)=>{
|
|
1038
1078
|
const exportCond = exportPaths[entryExport];
|
|
1079
|
+
const collectEntryOptions = {
|
|
1080
|
+
cwd,
|
|
1081
|
+
pkg,
|
|
1082
|
+
entries,
|
|
1083
|
+
entryPath,
|
|
1084
|
+
exportCondRef: exportCond,
|
|
1085
|
+
entryExport
|
|
1086
|
+
};
|
|
1039
1087
|
if (entryExport.startsWith('.')) {
|
|
1040
|
-
await collectEntry('',
|
|
1041
|
-
for (const
|
|
1042
|
-
if (exportCond[
|
|
1043
|
-
await collectEntry(
|
|
1088
|
+
await collectEntry('', collectEntryOptions);
|
|
1089
|
+
for (const exportCondType of suffixedExportConventions){
|
|
1090
|
+
if (exportCond[exportCondType]) {
|
|
1091
|
+
await collectEntry(exportCondType, collectEntryOptions);
|
|
1044
1092
|
}
|
|
1045
1093
|
}
|
|
1046
1094
|
}
|
|
@@ -1204,6 +1252,10 @@ function getExportNameWithoutExportCondition(exportName) {
|
|
|
1204
1252
|
}
|
|
1205
1253
|
function logOutputState(sizeCollector) {
|
|
1206
1254
|
const stats = sizeCollector.getSizeStats();
|
|
1255
|
+
if (stats.size === 0) {
|
|
1256
|
+
logger.warn('No build info can be logged');
|
|
1257
|
+
return;
|
|
1258
|
+
}
|
|
1207
1259
|
const allFileNameLengths = Array.from(stats.values()).flat(1).map(([filename])=>filename.length);
|
|
1208
1260
|
const maxFilenameLength = Math.max(...allFileNameLengths);
|
|
1209
1261
|
const statsArray = [
|
|
@@ -1313,12 +1365,12 @@ async function bundle(entryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1313
1365
|
const pkg = await getPackageMeta(cwd);
|
|
1314
1366
|
const resolvedWildcardExports = await resolveWildcardExports(pkg.exports, cwd);
|
|
1315
1367
|
const packageType = getPackageType(pkg);
|
|
1316
|
-
const exportPaths = getExportPaths(pkg,
|
|
1368
|
+
const exportPaths = getExportPaths(pkg, resolvedWildcardExports);
|
|
1317
1369
|
const isMultiEntries = hasMultiEntryExport(exportPaths) // exportPathsLength > 1
|
|
1318
1370
|
;
|
|
1319
1371
|
const hasBin = Boolean(pkg.bin);
|
|
1320
|
-
|
|
1321
|
-
|
|
1372
|
+
let tsConfig = await resolveTsConfig(cwd);
|
|
1373
|
+
let hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath);
|
|
1322
1374
|
const defaultTsOptions = {
|
|
1323
1375
|
tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath,
|
|
1324
1376
|
tsCompilerOptions: (tsConfig == null ? void 0 : tsConfig.tsCompilerOptions) || {}
|
|
@@ -1329,6 +1381,7 @@ async function bundle(entryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1329
1381
|
// e.g. "exports": "./dist/index.js" -> use "./index.<ext>" as entry
|
|
1330
1382
|
entryPath = entryPath || await getSourcePathFromExportPath(cwd, '.', 'default') || '';
|
|
1331
1383
|
}
|
|
1384
|
+
// Handle CLI input
|
|
1332
1385
|
if (entryPath) {
|
|
1333
1386
|
let mainEntryPath;
|
|
1334
1387
|
let typesEntryPath;
|
|
@@ -1346,11 +1399,10 @@ async function bundle(entryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1346
1399
|
}, packageType);
|
|
1347
1400
|
}
|
|
1348
1401
|
}
|
|
1349
|
-
const bundleOrWatch = (rollupConfig)=>{
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
typeof input.input === 'string' ? path.relative(cwd, input.input) : exportPath;
|
|
1402
|
+
const bundleOrWatch = async (rollupConfig)=>{
|
|
1403
|
+
if (options.clean) {
|
|
1404
|
+
await removeOutputDir(rollupConfig.output);
|
|
1405
|
+
}
|
|
1354
1406
|
if (options.watch) {
|
|
1355
1407
|
return Promise.resolve(runWatch(rollupConfig));
|
|
1356
1408
|
}
|
|
@@ -1373,6 +1425,14 @@ async function bundle(entryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1373
1425
|
}
|
|
1374
1426
|
}
|
|
1375
1427
|
const entries = await collectEntries(pkg, entryPath, exportPaths, cwd);
|
|
1428
|
+
const hasTypeScriptFiles = Object.values(entries).some((entry)=>isTypescriptFile(entry.source));
|
|
1429
|
+
if (hasTypeScriptFiles && !hasTsConfig) {
|
|
1430
|
+
const tsConfigPath = path.resolve(cwd, 'tsconfig.json');
|
|
1431
|
+
defaultTsOptions.tsConfigPath = tsConfigPath;
|
|
1432
|
+
await fsp__default.default.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
|
|
1433
|
+
logger.log(`Detected using TypeScript but tsconfig.json is missing, created a ${pc.blue('tsconfig.json')} for you.`);
|
|
1434
|
+
hasTsConfig = true;
|
|
1435
|
+
}
|
|
1376
1436
|
const sizeCollector = createOutputState({
|
|
1377
1437
|
entries
|
|
1378
1438
|
});
|
|
@@ -1402,7 +1462,7 @@ async function bundle(entryPath, { cwd: _cwd, ...options } = {}) {
|
|
|
1402
1462
|
}
|
|
1403
1463
|
return result;
|
|
1404
1464
|
}
|
|
1405
|
-
function runWatch({ input, output }
|
|
1465
|
+
function runWatch({ input, output }) {
|
|
1406
1466
|
const watchOptions = [
|
|
1407
1467
|
{
|
|
1408
1468
|
...input,
|
|
@@ -1436,6 +1496,12 @@ function runWatch({ input, output }, metadata) {
|
|
|
1436
1496
|
});
|
|
1437
1497
|
return watcher;
|
|
1438
1498
|
}
|
|
1499
|
+
async function removeOutputDir(output) {
|
|
1500
|
+
const dirs = new Set(output.map(({ dir })=>dir));
|
|
1501
|
+
for (const dir of dirs){
|
|
1502
|
+
if (dir) await removeDir(dir);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1439
1505
|
function runBundle({ input, output }) {
|
|
1440
1506
|
return rollup.rollup(input).then((bundle)=>{
|
|
1441
1507
|
const writeJobs = output.map((options)=>bundle.write(options));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bunchee",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.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",
|
|
@@ -57,8 +57,9 @@
|
|
|
57
57
|
"@swc/core": "^1.3.102",
|
|
58
58
|
"@swc/helpers": "^0.5.3",
|
|
59
59
|
"arg": "^5.0.2",
|
|
60
|
+
"clean-css": "^5.3.3",
|
|
60
61
|
"pretty-bytes": "^5.6.0",
|
|
61
|
-
"
|
|
62
|
+
"rimraf": "^5.0.5",
|
|
62
63
|
"rollup": "^4.9.4",
|
|
63
64
|
"rollup-plugin-dts": "^6.1.0",
|
|
64
65
|
"rollup-plugin-swc3": "^0.11.0",
|
|
@@ -80,6 +81,7 @@
|
|
|
80
81
|
"@huozhi/testing-package": "1.0.0",
|
|
81
82
|
"@swc/jest": "^0.2.29",
|
|
82
83
|
"@swc/types": "^0.1.5",
|
|
84
|
+
"@types/clean-css": "^4.2.11",
|
|
83
85
|
"@types/jest": "29.0.0",
|
|
84
86
|
"@types/node": "^20.4.1",
|
|
85
87
|
"bunchee": "link:./",
|
|
@@ -106,7 +108,11 @@
|
|
|
106
108
|
"^.+\\.(t|j)sx?$": [
|
|
107
109
|
"@swc/jest"
|
|
108
110
|
]
|
|
109
|
-
}
|
|
111
|
+
},
|
|
112
|
+
"testPathIgnorePatterns": [
|
|
113
|
+
"/node_modules/",
|
|
114
|
+
"<rootDir>/test/integration/.*/*src"
|
|
115
|
+
]
|
|
110
116
|
},
|
|
111
117
|
"packageManager": "pnpm@8.8.0"
|
|
112
118
|
}
|