@savvy-web/rslib-builder 0.13.1 → 0.14.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
@@ -19,11 +19,7 @@ Build modern ESM Node.js libraries with minimal configuration. Handles TypeScrip
19
19
  ## Installation
20
20
 
21
21
  ```bash
22
- npm install --save-dev \
23
- @savvy-web/rslib-builder \
24
- @rslib/core \
25
- @microsoft/api-extractor \
26
- @typescript/native-preview
22
+ npm install --save-dev @savvy-web/rslib-builder @rslib/core @microsoft/api-extractor @typescript/native-preview
27
23
  ```
28
24
 
29
25
  ## Quick Start
package/index.d.ts CHANGED
@@ -1179,6 +1179,7 @@ export declare class NodeLibraryBuilder {
1179
1179
  externals: never[];
1180
1180
  apiModel: true;
1181
1181
  bundle: true;
1182
+ cjsInterop: false;
1182
1183
  };
1183
1184
  /**
1184
1185
  * Merges user-provided options with default options.
@@ -1543,6 +1544,15 @@ export declare interface NodeLibraryBuilderOptions {
1543
1544
  * @defaultValue true
1544
1545
  */
1545
1546
  bundle?: boolean;
1547
+ /**
1548
+ * Enable CJS default export interop for CommonJS output files.
1549
+ * When true, CJS files are patched so `require('module')` returns
1550
+ * the default export directly instead of `{ default: value }`.
1551
+ * Named exports are preserved as properties on the default value.
1552
+ * Only affects CJS format output; ESM is unchanged.
1553
+ * @defaultValue false
1554
+ */
1555
+ cjsInterop?: boolean;
1546
1556
  }
1547
1557
 
1548
1558
  /**
package/index.js CHANGED
@@ -2224,6 +2224,10 @@ async function buildPackageJson(packageJson, isProduction = false, processTSExpo
2224
2224
  result = applyRslibTransformations(pnpmTransformed, packageJson, processTSExports, entrypoints, exportToOutputMap, bundle);
2225
2225
  } else result = applyRslibTransformations(packageJson, packageJson, processTSExports, entrypoints, exportToOutputMap, bundle);
2226
2226
  if (formatConditions && result.exports) result.exports = applyFormatConditions(result.exports, formatConditions);
2227
+ if (formatConditions?.dualFormat && result.bin) {
2228
+ const prefixedBin = applyFormatPrefixToBin(result.bin, formatConditions.format ?? "esm");
2229
+ if (prefixedBin) result.bin = prefixedBin;
2230
+ }
2227
2231
  if (transform) result = transform(result);
2228
2232
  return result;
2229
2233
  }
@@ -2239,6 +2243,15 @@ function addFormatDirPrefix(path, format) {
2239
2243
  if (path.startsWith("./")) return `./${format}/${path.slice(2)}`;
2240
2244
  return `./${format}/${path}`;
2241
2245
  }
2246
+ function applyFormatPrefixToBin(bin, format) {
2247
+ if ("string" == typeof bin) return bin.endsWith(".js") ? addFormatDirPrefix(bin, format) : bin;
2248
+ if (bin && "object" == typeof bin) {
2249
+ const result = {};
2250
+ for (const [command, path] of Object.entries(bin))if (void 0 !== path) result[command] = path.endsWith(".js") ? addFormatDirPrefix(path, format) : path;
2251
+ return result;
2252
+ }
2253
+ return bin;
2254
+ }
2242
2255
  function applyFormatConditions(exports, options) {
2243
2256
  if (!exports || "object" != typeof exports || Array.isArray(exports)) return exports;
2244
2257
  const { format = "esm", entryFormats, dualFormat } = options;
@@ -2688,6 +2701,20 @@ const VirtualEntryPlugin = (options)=>{
2688
2701
  }
2689
2702
  };
2690
2703
  };
2704
+ const CJS_INTEROP_FOOTER = `
2705
+ if (module.exports && module.exports.__esModule && 'default' in module.exports) {
2706
+ var _def = module.exports.default;
2707
+ if (_def !== null && _def !== undefined && (typeof _def === 'object' || typeof _def === 'function')) {
2708
+ var _keys = Object.keys(module.exports);
2709
+ for (var _i = 0; _i < _keys.length; _i++) {
2710
+ var _key = _keys[_i];
2711
+ if (_key !== 'default' && _key !== '__esModule' && !(_key in _def)) {
2712
+ _def[_key] = module.exports[_key];
2713
+ }
2714
+ }
2715
+ }
2716
+ module.exports = _def;
2717
+ }`;
2691
2718
  /* v8 ignore next -- @preserve */ class NodeLibraryBuilder {
2692
2719
  static VALID_TARGETS = [
2693
2720
  "dev",
@@ -2704,7 +2731,8 @@ const VirtualEntryPlugin = (options)=>{
2704
2731
  ],
2705
2732
  externals: [],
2706
2733
  apiModel: true,
2707
- bundle: true
2734
+ bundle: true,
2735
+ cjsInterop: false
2708
2736
  };
2709
2737
  static mergeOptions(options = {}) {
2710
2738
  const copyPatterns = [
@@ -2725,6 +2753,7 @@ const VirtualEntryPlugin = (options)=>{
2725
2753
  externals: options.externals ?? NodeLibraryBuilder.DEFAULT_OPTIONS.externals,
2726
2754
  apiModel: options.apiModel ?? NodeLibraryBuilder.DEFAULT_OPTIONS.apiModel,
2727
2755
  bundle: options.bundle ?? NodeLibraryBuilder.DEFAULT_OPTIONS.bundle,
2756
+ cjsInterop: options.cjsInterop ?? NodeLibraryBuilder.DEFAULT_OPTIONS.cjsInterop,
2728
2757
  ...void 0 !== options.entry && {
2729
2758
  entry: options.entry
2730
2759
  },
@@ -2910,6 +2939,11 @@ const VirtualEntryPlugin = (options)=>{
2910
2939
  entry
2911
2940
  },
2912
2941
  define: sourceDefine
2942
+ },
2943
+ ...options.cjsInterop && "cjs" === primaryFormat && {
2944
+ footer: {
2945
+ js: CJS_INTEROP_FOOTER
2946
+ }
2913
2947
  }
2914
2948
  };
2915
2949
  const hasRegularEntries = void 0 !== options.entry || NodeLibraryBuilder.packageHasExports();
@@ -2931,6 +2965,21 @@ const VirtualEntryPlugin = (options)=>{
2931
2965
  });
2932
2966
  }
2933
2967
  },
2968
+ {
2969
+ name: "strip-bin-entries",
2970
+ setup (api) {
2971
+ api.modifyRsbuildConfig((config)=>{
2972
+ const envKey = `${target}-${secondaryFormat}`;
2973
+ const envConfig = config.environments?.[envKey];
2974
+ if (envConfig?.source?.entry) {
2975
+ const filtered = {};
2976
+ for (const [name, value] of Object.entries(envConfig.source.entry))if (!name.startsWith("bin/")) filtered[name] = value;
2977
+ envConfig.source.entry = filtered;
2978
+ }
2979
+ return config;
2980
+ });
2981
+ }
2982
+ },
2934
2983
  DtsPlugin({
2935
2984
  ...options.tsconfigPath && {
2936
2985
  tsconfigPath: options.tsconfigPath
@@ -2945,6 +2994,7 @@ const VirtualEntryPlugin = (options)=>{
2945
2994
  dtsPathPrefix: secondaryFormat
2946
2995
  })
2947
2996
  ];
2997
+ const secondaryEntry = entry ? Object.fromEntries(Object.entries(entry).filter(([name])=>!name.startsWith("bin/"))) : void 0;
2948
2998
  const secondaryLib = {
2949
2999
  id: `${target}-${secondaryFormat}`,
2950
3000
  outBase: bundle ? baseOutputDir : "src",
@@ -2969,10 +3019,15 @@ const VirtualEntryPlugin = (options)=>{
2969
3019
  ...options.tsconfigPath && {
2970
3020
  tsconfigPath: options.tsconfigPath
2971
3021
  },
2972
- ...entry && {
2973
- entry
3022
+ ...secondaryEntry && {
3023
+ entry: secondaryEntry
2974
3024
  },
2975
3025
  define: sourceDefine
3026
+ },
3027
+ ...options.cjsInterop && "cjs" === secondaryFormat && {
3028
+ footer: {
3029
+ js: CJS_INTEROP_FOOTER
3030
+ }
2976
3031
  }
2977
3032
  };
2978
3033
  libConfigs.push(secondaryLib);
@@ -3038,6 +3093,11 @@ const VirtualEntryPlugin = (options)=>{
3038
3093
  tsconfigPath: options.tsconfigPath
3039
3094
  },
3040
3095
  define: sourceDefine
3096
+ },
3097
+ ...options.cjsInterop && "cjs" === overrideFormat && {
3098
+ footer: {
3099
+ js: CJS_INTEROP_FOOTER
3100
+ }
3041
3101
  }
3042
3102
  };
3043
3103
  libConfigs.push(overrideLib);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/rslib-builder",
3
- "version": "0.13.1",
3
+ "version": "0.14.1",
4
4
  "private": false,
5
5
  "description": "RSlib-based build system for Node.js libraries with automatic package.json transformation, TypeScript declaration bundling, and multi-target support",
6
6
  "keywords": [