bunchee 6.0.0-beta.1 → 6.0.0-rc.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 CHANGED
@@ -40,6 +40,20 @@ cd ./my-lib
40
40
  mkdir src && touch ./src/index.ts
41
41
  ```
42
42
 
43
+ #### Build
44
+
45
+ Then files in `src` folders will be treated as entry files and match the export names in package.json. For example:
46
+ `src/index.ts` will match the exports name `"."` or the only main export.
47
+
48
+ Now just run `npm run build` (or `pnpm build` / `yarn build`) if you're using these package managers, `bunchee` will find the entry files and build them.
49
+ The output format will based on the exports condition and also the file extension. Given an example:
50
+
51
+ - It's CommonJS for `require` and ESM for `import` based on the exports condition.
52
+ - 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.
53
+
54
+ > [!NOTE]
55
+ > All the `dependencies` and `peerDependencies` will be marked as external automatically and not included in the bundle. If you want to include them in the bundle, you can use the `--no-external` option.
56
+
43
57
  #### Prepare
44
58
 
45
59
  ```sh
@@ -128,19 +142,17 @@ If you're using TypeScript with Node 10 and Node 16 module resolution, you can u
128
142
 
129
143
  </details>
130
144
 
131
- #### Build
145
+ #### Lint
132
146
 
133
- Then files in `src` folders will be treated as entry files and match the export names in package.json. For example:
134
- `src/index.ts` will match the exports name `"."` or the only main export.
147
+ `lint` command will check the package.json configuration is valid or not, it can valid few things like:
135
148
 
136
- Now just run `npm run build` (or `pnpm build` / `yarn build`) if you're using these package managers, `bunchee` will find the entry files and build them.
137
- The output format will based on the exports condition and also the file extension. Given an example:
149
+ - if the entry files are matched with the exports conditions.
150
+ - if the entry files are matched with the exports paths.
138
151
 
139
- - It's CommonJS for `require` and ESM for `import` based on the exports condition.
140
- - 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.
141
-
142
- > [!NOTE]
143
- > All the `dependencies` and `peerDependencies` will be marked as external automatically and not included in the bundle. If you want to include them in the bundle, you can use the `--no-external` option.
152
+ ```sh
153
+ # Use bunchee to lint if the package.json configuration is valid
154
+ npm exec bunchee lint
155
+ ```
144
156
 
145
157
  ## Usage
146
158
 
package/dist/bin/cli.js CHANGED
@@ -6,6 +6,7 @@ var perf_hooks = require('perf_hooks');
6
6
  var fs = require('fs');
7
7
  var fsp = require('fs/promises');
8
8
  var require$$0 = require('tty');
9
+ var picomatch = require('picomatch');
9
10
  var index_js = require('../index.js');
10
11
  require('module');
11
12
  var glob = require('glob');
@@ -18,6 +19,7 @@ var yargs__default = /*#__PURE__*/_interopDefault(yargs);
18
19
  var fs__default = /*#__PURE__*/_interopDefault(fs);
19
20
  var fsp__default = /*#__PURE__*/_interopDefault(fsp);
20
21
  var require$$0__default = /*#__PURE__*/_interopDefault(require$$0);
22
+ var picomatch__default = /*#__PURE__*/_interopDefault(picomatch);
21
23
  var prettyBytes__default = /*#__PURE__*/_interopDefault(prettyBytes);
22
24
 
23
25
  const availableExtensions = new Set([
@@ -217,6 +219,14 @@ function sourceFilenameToExportFullPath(filename) {
217
219
  const exportPath = filename.slice(0, -ext.length);
218
220
  return relativify(exportPath);
219
221
  }
222
+ // If the file is matching the private module convention file export path.
223
+ // './lib/_foo' -> true
224
+ // './_util/index' -> true
225
+ // './lib/_foo/bar' -> true
226
+ // './foo' -> false
227
+ function isPrivateExportPath(exportPath) {
228
+ return /\/_/.test(exportPath);
229
+ }
220
230
 
221
231
  function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exportToDist) {
222
232
  // End of searching, export value is file path.
@@ -371,6 +381,49 @@ function validateTypesFieldCondition(pair) {
371
381
  }
372
382
  return false;
373
383
  }
384
+ const isPathIncluded = (filesField, filePath)=>{
385
+ return filesField.some((pattern)=>{
386
+ const normalizedPattern = path__default.default.normalize(pattern);
387
+ const matcher = picomatch__default.default(normalizedPattern);
388
+ return matcher(filePath);
389
+ });
390
+ };
391
+ function validateFilesField(packageJson) {
392
+ const state = {
393
+ definedField: false,
394
+ missingFiles: []
395
+ };
396
+ const filesField = packageJson.files || [];
397
+ const exportsField = packageJson.exports || {};
398
+ state.definedField = !!packageJson.files;
399
+ const resolveExportsPaths = (exports)=>{
400
+ const paths = [];
401
+ if (typeof exports === 'string') {
402
+ paths.push(exports);
403
+ } else if (typeof exports === 'object') {
404
+ for(const key in exports){
405
+ paths.push(...resolveExportsPaths(exports[key]));
406
+ }
407
+ }
408
+ return paths;
409
+ };
410
+ const exportedPaths = resolveExportsPaths(exportsField).map((p)=>path__default.default.normalize(p));
411
+ const commonFields = [
412
+ 'main',
413
+ 'module',
414
+ 'types',
415
+ 'module-sync'
416
+ ];
417
+ for (const field of commonFields){
418
+ if (field in packageJson) {
419
+ exportedPaths.push(packageJson[field]);
420
+ }
421
+ }
422
+ state.missingFiles = exportedPaths.filter((exportPath)=>{
423
+ return !isPathIncluded(filesField, exportPath);
424
+ });
425
+ return state;
426
+ }
374
427
  function lint$1(pkg) {
375
428
  const { name, main, exports } = pkg;
376
429
  const isESM = isESModulePackage(pkg.type);
@@ -494,6 +547,15 @@ function lint$1(pkg) {
494
547
  }
495
548
  }
496
549
  }
550
+ const fieldState = validateFilesField(pkg);
551
+ if (!fieldState.definedField) {
552
+ logger.warn('Missing files field in package.json');
553
+ } else if (fieldState.missingFiles.length) {
554
+ logger.warn('Missing files in package.json');
555
+ fieldState.missingFiles.forEach((p)=>{
556
+ logger.warn(` ${p}`);
557
+ });
558
+ }
497
559
  if (state.badMainExtension) {
498
560
  logger.warn('Cannot export `main` field with .mjs extension in CJS package, only .js extension is allowed');
499
561
  }
@@ -539,7 +601,7 @@ function lint$1(pkg) {
539
601
  }
540
602
  }
541
603
 
542
- var version = "6.0.0-beta.1";
604
+ var version = "6.0.0-rc.1";
543
605
 
544
606
  async function writeDefaultTsconfig(tsConfigPath) {
545
607
  await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');
@@ -916,12 +978,21 @@ function logOutputState(stats) {
916
978
  }).forEach((item, index)=>{
917
979
  const [filename, , size] = item;
918
980
  const normalizedExportName = normalizeExportName(exportName);
919
- const prefix = index === 0 ? normalizedExportName : ' '.repeat(normalizedExportName.length);
981
+ const exportNameWithPadding = index === 0 ? // For other formats, just show the padding spaces.
982
+ normalizedExportName : ' '.repeat(normalizedExportName.length);
920
983
  const filenamePadding = ' '.repeat(Math.max(maxLengthOfExportName, 'Exports'.length) - normalizedExportName.length);
921
984
  const isType = isTypeFile(filename);
922
- const sizePadding = ' '.repeat(Math.max(maxFilenameLength, 'File'.length) - filename.length);
923
985
  const prettiedSize = prettyBytes__default.default(size);
924
- console.log(prefix, filenamePadding, `${pc[isType ? 'dim' : 'bold'](filename)}`, sizePadding, prettiedSize);
986
+ const sizePadding = ' '.repeat(Math.max(maxFilenameLength, 'File'.length) - filename.length);
987
+ // Logging shared in debug mode
988
+ if (isPrivateExportPath(exportName)) {
989
+ if (index === 0 && process.env.DEBUG) {
990
+ const sizePadding = ' '.repeat(Math.max(maxFilenameLength, 'File'.length) - 'private shared'.length);
991
+ console.log(pc.dim(normalizeExportName(exportName)), filenamePadding, pc.dim('private shared'), sizePadding, pc.dim(prettiedSize));
992
+ }
993
+ return;
994
+ }
995
+ console.log(exportNameWithPadding, filenamePadding, `${pc[isType ? 'dim' : 'bold'](filename)}`, sizePadding, prettiedSize);
925
996
  });
926
997
  });
927
998
  }
@@ -930,7 +1001,8 @@ const helpMessage = `
930
1001
  Usage: bunchee [options]
931
1002
 
932
1003
  Commands:
933
- prepare auto configure package.json exports for building
1004
+ prepare auto setup package.json for building
1005
+ lint lint configuration in package.json
934
1006
 
935
1007
  Options:
936
1008
  -v, --version output the version number
@@ -1027,6 +1099,12 @@ async function parseCliArgs(argv) {
1027
1099
  }).command('lint', 'lint package.json', ()=>{}, (argv)=>{
1028
1100
  return lint(argv.cwd || process.cwd());
1029
1101
  }).version(version).help('help', 'output usage information').showHelpOnFail(true).parse();
1102
+ const cmd = args._[0];
1103
+ if (cmd === 'prepare' || cmd === 'lint') {
1104
+ return {
1105
+ cmd
1106
+ };
1107
+ }
1030
1108
  const source = args._[0];
1031
1109
  const parsedArgs = {
1032
1110
  source,
@@ -1172,6 +1250,9 @@ async function main() {
1172
1250
  // if (!error) help()
1173
1251
  return exit(error);
1174
1252
  }
1253
+ if ('cmd' in params) {
1254
+ return;
1255
+ }
1175
1256
  await run(params);
1176
1257
  }
1177
1258
  function logWatcherBuildTime(result, spinner) {
package/dist/index.d.ts CHANGED
@@ -31,6 +31,7 @@ type PackageMetadata = {
31
31
  main?: string;
32
32
  bin?: string | Record<string, string>;
33
33
  module?: string;
34
+ files?: string[];
34
35
  type?: 'commonjs' | 'module';
35
36
  dependencies?: Record<string, string>;
36
37
  peerDependencies?: Record<string, string>;
package/dist/index.js CHANGED
@@ -1056,7 +1056,7 @@ async function writeDefaultTsconfig(tsConfigPath) {
1056
1056
  const FILENAME_REGEX = /__filename/;
1057
1057
  const DIRNAME_REGEX = /__dirname/;
1058
1058
  // not char, or space before require(.resolve)?(
1059
- const GLOBAL_REQUIRE_REGEX = /(?:^|[^.\w'"`])\brequire(\.resolve)?\(\s*[\r\n]*(['"`])/;
1059
+ const GLOBAL_REQUIRE_REGEX = /(?:^|[^.\w'"`])\brequire(\.resolve)?\(\s*[\r\n]*(\w|['"`])/;
1060
1060
  const PolyfillComment = '/** rollup-private-do-not-use-esm-shim-polyfill */';
1061
1061
  const createESMShim = ({ filename, dirname, globalRequire })=>{
1062
1062
  const useNodeUrl = filename || dirname;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunchee",
3
- "version": "6.0.0-beta.1",
3
+ "version": "6.0.0-rc.1",
4
4
  "description": "zero config bundler for js/ts/jsx libraries",
5
5
  "bin": "./dist/bin/cli.js",
6
6
  "main": "./dist/index.js",
@@ -48,6 +48,7 @@
48
48
  "glob": "^11.0.0",
49
49
  "magic-string": "^0.30.11",
50
50
  "ora": "^8.0.1",
51
+ "picomatch": "^4.0.2",
51
52
  "pretty-bytes": "^5.6.0",
52
53
  "rollup": "^4.27.4",
53
54
  "rollup-plugin-dts": "^6.1.1",
@@ -75,6 +76,7 @@
75
76
  "@types/clean-css": "^4.2.11",
76
77
  "@types/jest": "29.0.0",
77
78
  "@types/node": "^22.9.3",
79
+ "@types/picomatch": "^3.0.1",
78
80
  "@types/yargs": "^17.0.33",
79
81
  "bunchee": "link:./",
80
82
  "cross-env": "^7.0.3",
@@ -114,10 +116,10 @@
114
116
  "test:ci": "[ -z $CI ] || pnpm test",
115
117
  "clean": "rm -rf ./dist",
116
118
  "typecheck": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
117
- "cli": "cross-env SWC_NODE_IGNORE_DYNAMIC=1 node -r @swc-node/register",
118
- "ts-bunchee": "pnpm cli ./src/bin/index.ts",
119
+ "run-ts": "cross-env SWC_NODE_IGNORE_DYNAMIC=1 node -r @swc-node/register",
120
+ "ts-bunchee": "pnpm run-ts ./src/bin/index.ts",
119
121
  "build-dir": "pnpm ts-bunchee --cwd",
120
- "build": "pnpm cli ./src/bin/index.ts --runtime node",
122
+ "build": "pnpm run-ts ./src/bin/index.ts --runtime node",
121
123
  "format": "prettier --write ."
122
124
  }
123
125
  }