Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bunchee

Package Overview
Dependencies
Maintainers
0
Versions
156
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bunchee - npm Package Compare versions

Comparing version 5.6.1 to 6.0.0-rc.0

240

dist/bin/cli.js

@@ -11,2 +11,3 @@ #!/usr/bin/env node

require('module');
var glob = require('glob');
var prettyBytes = require('pretty-bytes');

@@ -145,3 +146,3 @@

warn (...arg) {
console.warn(color('yellow')('⚠️'), ...arg);
console.warn(color('yellow')('!'), ...arg);
},

@@ -156,2 +157,7 @@ error (...arg) {

const { sep } = require('path');
function relativify(path) {
return path.startsWith('.') ? path : `.${sep}${path}`;
}
function exit(err) {

@@ -181,4 +187,2 @@ logger.error(err);

}
// 'index.server.js' -> 'index'
const getFileBasename = (str)=>str.split('.')[0];
const hasCjsExtension = (filename)=>path__default.default.extname(filename) === '.cjs';

@@ -210,2 +214,11 @@ const getMainFieldExportType = (pkg)=>{

}
// shared.ts -> ./shared
// shared.<export condition>.ts -> ./shared
// index.ts -> ./index
// index.development.ts -> ./index.development
function sourceFilenameToExportFullPath(filename) {
const baseName = baseNameWithoutExtension(filename);
let exportPath = baseName;
return relativify(exportPath);
}

@@ -533,8 +546,4 @@ function collectExportPath(exportValue, exportKey, currentPath, exportTypes, exportToDist) {

var version = "5.6.1";
var version = "6.0.0-rc.0";
function relativify(path) {
return path.startsWith('.') ? path : `./${path}`;
}
async function writeDefaultTsconfig(tsConfigPath) {

@@ -545,11 +554,2 @@ await fs.promises.writeFile(tsConfigPath, JSON.stringify(DEFAULT_TS_CONFIG, null, 2), 'utf-8');

// shared.ts -> ./shared
// shared.<export condition>.ts -> ./shared
// index.ts -> ./index
// index.development.ts -> ./index.development
function sourceFilenameToExportFullPath(filename) {
const baseName = baseNameWithoutExtension(filename);
let exportPath = baseName;
return relativify(exportPath);
}
// ./index -> default

@@ -607,91 +607,61 @@ // ./index.development -> development

const subpath = originalSubpath.replace(BINARY_TAG, 'bin');
const absoluteDirPath = path__default.default.join(sourceFolderPath, subpath);
const isDirectory = fs__default.default.existsSync(absoluteDirPath) ? (await fsp__default.default.stat(absoluteDirPath)).isDirectory() : false;
if (isDirectory) {
const absoluteDirPath = path.join(sourceFolderPath, subpath);
const dirName = path.dirname(subpath) // Get directory name regardless of file/directory
;
const baseName = path.basename(subpath) // Get base name regardless of file/directory
;
const dirPath = path.join(sourceFolderPath, dirName);
// Match <name>{,/index}.{<ext>,<runtime>.<ext>}
const globalPatterns = [
`${baseName}.{${[
...availableExtensions
].join(',')}}`,
`${baseName}.{${[
...runtimeExportConventions
].join(',')}}.{${[
...availableExtensions
].join(',')}}`,
`${baseName}/index.{${[
...availableExtensions
].join(',')}}`,
`${baseName}/index.{${[
...runtimeExportConventions
].join(',')}}.{${[
...availableExtensions
].join(',')}}`
];
const files = await glob.glob(globalPatterns, {
cwd: dirPath,
nodir: true,
ignore: '**/_*'
});
for (const file of files){
const ext = path.extname(file).slice(1);
if (!availableExtensions.has(ext) || isTestFile(file)) continue;
const sourceFileAbsolutePath = path.join(dirPath, file);
const exportPath = relativify(fs.existsSync(absoluteDirPath) && (await fsp__default.default.stat(absoluteDirPath)).isDirectory() ? subpath : originalSubpath);
if (isBinaryPath) {
const binDirentList = await fsp__default.default.readdir(absoluteDirPath, {
withFileTypes: true
});
for (const binDirent of binDirentList){
if (binDirent.isFile()) {
const binFileAbsolutePath = path__default.default.join(absoluteDirPath, binDirent.name);
if (fs__default.default.existsSync(binFileAbsolutePath)) {
bins.set(normalizeExportPath(originalSubpath), binFileAbsolutePath);
}
}
}
bins.set(normalizeExportPath(originalSubpath), sourceFileAbsolutePath);
} else {
// Search folder/index.<ext> convention entries
for (const extension of availableExtensions){
const indexAbsoluteFile = path__default.default.join(absoluteDirPath, `index.${extension}`);
// Search folder/index.<special type>.<ext> convention entries
for (const specialExportType of runtimeExportConventions){
const indexSpecialAbsoluteFile = path__default.default.join(absoluteDirPath, `index.${specialExportType}.${extension}`);
if (fs__default.default.existsSync(indexSpecialAbsoluteFile)) {
// Add special export path
// { ./<export path>.<special cond>: { <special cond>: 'index.<special cond>.<ext>' } }
const exportPath = relativify(subpath);
const specialExportPath = exportPath + '.' + specialExportType;
const sourceFilesMap = exportsEntries.get(specialExportPath) || {};
sourceFilesMap[specialExportType] = indexSpecialAbsoluteFile;
exportsEntries.set(specialExportPath, sourceFilesMap);
}
}
if (fs__default.default.existsSync(indexAbsoluteFile) && !isTestFile(indexAbsoluteFile)) {
const exportPath = relativify(subpath);
const sourceFilesMap = exportsEntries.get(exportPath) || {};
const exportType = getExportTypeFromExportPath(exportPath);
sourceFilesMap[exportType] = indexAbsoluteFile;
exportsEntries.set(exportPath, sourceFilesMap);
}
const parts = path.basename(file).split('.');
const exportType = parts.length > 2 ? parts[1] : getExportTypeFromExportPath(exportPath);
const specialExportPath = exportType !== 'index' && parts.length > 2 ? exportPath + '.' + exportType : exportPath // Adjust for direct file matches
;
const sourceFilesMap = exportsEntries.get(specialExportPath) || {};
sourceFilesMap[exportType] = sourceFileAbsolutePath;
if (specialExportConventions.has(exportType)) {
const fallbackExportPath = sourceFilenameToExportFullPath(originalSubpath);
const fallbackSourceFilesMap = exportsEntries.get(fallbackExportPath) || {};
Object.assign(sourceFilesMap, fallbackSourceFilesMap);
}
exportsEntries.set(specialExportPath, sourceFilesMap);
}
} else {
// subpath could be a file
const dirName = path.dirname(subpath);
const baseName = path.basename(subpath);
// Read current file's directory
const dirPath = path__default.default.join(sourceFolderPath, dirName);
if (!fs__default.default.existsSync(dirPath)) {
return;
}
const dirents = await fsp__default.default.readdir(dirPath, {
withFileTypes: true
});
for (const dirent of dirents){
// index.development.js -> index.development
const direntBaseName = baseNameWithoutExtension(dirent.name);
const ext = path.extname(dirent.name).slice(1);
if (!dirent.isFile() || direntBaseName !== baseName || !availableExtensions.has(ext)) {
continue;
}
if (isTestFile(dirent.name)) {
continue;
}
const sourceFileAbsolutePath = path__default.default.join(dirPath, dirent.name);
if (isBinaryPath) {
bins.set(originalSubpath, sourceFileAbsolutePath);
} else {
let sourceFilesMap = exportsEntries.get(originalSubpath) || {};
const exportType = getExportTypeFromExportPath(originalSubpath);
sourceFilesMap[exportType] = sourceFileAbsolutePath;
if (specialExportConventions.has(exportType)) {
// e.g. ./foo/index.react-server -> ./foo/index
const fallbackExportPath = sourceFilenameToExportFullPath(originalSubpath);
const fallbackSourceFilesMap = exportsEntries.get(fallbackExportPath) || {};
sourceFilesMap = {
...fallbackSourceFilesMap,
...sourceFilesMap
};
}
exportsEntries.set(originalSubpath, sourceFilesMap);
}
}
}
}
// For `prepare`
// For `prepare` command
async function collectSourceEntries(sourceFolderPath) {
const bins = new Map();
const exportsEntries = new Map();
if (!fs__default.default.existsSync(sourceFolderPath)) {
if (!fs.existsSync(sourceFolderPath)) {
return {

@@ -702,27 +672,29 @@ bins,

}
const entryFileDirentList = await fsp__default.default.readdir(sourceFolderPath, {
withFileTypes: true
// Match with global patterns
// bin/**/*.<ext>, bin/**/index.<ext>
const binPattern = `bin/**/*.{${[
...availableExtensions
].join(',')}}`;
const srcPattern = `**/*.{${[
...availableExtensions
].join(',')}}`;
const binMatches = await glob.glob(binPattern, {
cwd: sourceFolderPath,
nodir: true,
ignore: '**/_*'
});
// Collect source files for `exports` field
for (const dirent of entryFileDirentList){
if (getFileBasename(dirent.name) === 'bin') {
continue;
}
const exportPath = sourceFilenameToExportFullPath(dirent.name);
const srcMatches = await glob.glob(srcPattern, {
cwd: sourceFolderPath,
nodir: true,
ignore: '**/_*'
});
for (const file of binMatches){
// convert relative path to export path
const exportPath = sourceFilenameToExportFullPath(file);
await collectSourceEntriesByExportPath(sourceFolderPath, exportPath, bins, exportsEntries);
}
// Collect source files for `bin` field
const binDirent = entryFileDirentList.find((dirent)=>getFileBasename(dirent.name) === 'bin');
if (binDirent) {
if (binDirent.isDirectory()) {
const binDirentList = await fsp__default.default.readdir(path__default.default.join(sourceFolderPath, binDirent.name), {
withFileTypes: true
});
for (const binDirent of binDirentList){
const binExportPath = path.posix.join(BINARY_TAG, getFileBasename(binDirent.name));
await collectSourceEntriesByExportPath(sourceFolderPath, binExportPath, bins, exportsEntries);
}
} else {
await collectSourceEntriesByExportPath(sourceFolderPath, BINARY_TAG, bins, exportsEntries);
}
for (const file of srcMatches){
const binExportPath = file.replace(/^bin/, BINARY_TAG)// Remove index.<ext> to [^index].<ext> to build the export path
.replace(/(\/index)?\.[^/]+$/, '');
await collectSourceEntriesByExportPath(sourceFolderPath, binExportPath, bins, exportsEntries);
}

@@ -967,2 +939,5 @@ return {

Commands:
prepare auto configure package.json exports for building
Options:

@@ -975,3 +950,3 @@ -v, --version output the version number

-h, --help output usage information
--prepare auto configure package.json exports for building
--external <mod> specify an external dependency, separate by comma

@@ -1000,3 +975,7 @@ --no-external do not bundle external dependencies

async function parseCliArgs(argv) {
const args = await yargs__default.default(helpers.hideBin(argv)).option('cwd', {
const args = await yargs__default.default(helpers.hideBin(argv)).option('watch', {
type: 'boolean',
alias: 'w',
description: 'watch src files changes'
}).option('cwd', {
type: 'string',

@@ -1023,6 +1002,2 @@ description: 'specify current working directory'

description: 'type of output (esm, amd, cjs, iife, umd, system)'
}).option('watch', {
type: 'boolean',
alias: 'w',
description: 'watch src files changes'
}).option('minify', {

@@ -1055,5 +1030,2 @@ type: 'boolean',

description: 'specify an external dependency, separate by comma'
}).option('prepare', {
type: 'boolean',
description: 'auto configure package.json exports for building'
}).option('tsconfig', {

@@ -1065,2 +1037,6 @@ type: 'string',

description: 'bundle type declaration files'
}).command('prepare', 'auto configure package.json exports for building', ()=>{}, (argv)=>{
return prepare(argv.cwd || process.cwd());
}).command('lint', 'lint package.json', ()=>{}, (argv)=>{
return lint(argv.cwd || process.cwd());
}).version(version).help('help', 'output usage information').showHelpOnFail(true).parse();

@@ -1072,3 +1048,3 @@ const source = args._[0];

file: args['output'],
watch: args['watch'],
watch: !!args['watch'],
minify: args['minify'],

@@ -1086,3 +1062,2 @@ sourcemap: !!args['sourcemap'],

env: args['env'],
prepare: !!args['prepare'],
tsconfig: args['tsconfig']

@@ -1114,7 +1089,4 @@ };

};
if (args.prepare) {
return await prepare(cwd);
}
const cliEntry = source ? path__default.default.resolve(cwd, source) : '';
// lint package
// lint package by default
await lint(cwd);

@@ -1121,0 +1093,0 @@ const { default: ora } = await import('ora');

{
"name": "bunchee",
"version": "5.6.1",
"version": "6.0.0-rc.0",
"description": "zero config bundler for js/ts/jsx libraries",

@@ -39,15 +39,16 @@ "bin": "./dist/bin/cli.js",

"dependencies": {
"@rollup/plugin-commonjs": "^28.0.0",
"@rollup/plugin-commonjs": "^28.0.1",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-replace": "^6.0.1",
"@rollup/plugin-wasm": "^6.2.2",
"@rollup/pluginutils": "^5.1.0",
"@swc/core": "^1.7.14",
"@swc/core": "^1.9.3",
"@swc/helpers": "^0.5.11",
"clean-css": "^5.3.3",
"glob": "^11.0.0",
"magic-string": "^0.30.11",
"ora": "^8.0.1",
"pretty-bytes": "^5.6.0",
"rollup": "^4.24.0",
"rollup": "^4.27.4",
"rollup-plugin-dts": "^6.1.1",

@@ -77,3 +78,3 @@ "rollup-plugin-swc3": "^0.11.1",

"@types/jest": "29.0.0",
"@types/node": "^20.4.1",
"@types/node": "^22.9.3",
"@types/yargs": "^17.0.33",

@@ -87,3 +88,3 @@ "bunchee": "link:./",

"prettier": "^3.0.0",
"react": "^18.2.0",
"react": "^18.3.1",
"typescript": "^5.6.2"

@@ -90,0 +91,0 @@ },

@@ -47,8 +47,8 @@ # bunchee

# Use bunchee to prepare package.json configuration
npm exec bunchee --prepare
npm exec bunchee prepare
# "If you're using other package manager such as pnpm"
# pnpm bunchee --prepare
# pnpm bunchee prepare
# "Or use with npx"
# npx bunchee@latest --prepare
# npx bunchee@latest prepare
```

@@ -256,5 +256,5 @@

### Shared Modules (Experimental)
### Shared Modules
There're always cases that you need to share code among bundles but they don't have to be a separate entry or exports. You want to have them bundled into a shared chunk and then use them in different bundles. You can use shared module convention `[name].[layer]-runtime.[ext]` to create shared modules bundles.
In some cases, you may need to share code across multiple bundles without promoting them to separate entries or exports. These modules should be bundled into shared chunks that can be reused by various bundles. By convention, files or directories prefixed with an underscore (`_<name>.<ext>` or `_<name>/index.<ext>`) are treated as **shared modules**. They're private and not exposed publicly as entry points or exports.

@@ -265,3 +265,3 @@ <details>

```js
// src/util.shared-runtime.js
// src/_util.js
export function sharedUtil() {

@@ -272,7 +272,7 @@ /* ... */

Then you can use them in different entry files:
You can then use them in different entry files:
```js
// src/index.js
import { sharedUtil } from './util.shared-runtime'
import { sharedUtil } from './_util'
```

@@ -282,10 +282,10 @@

// src/lite.js
import { sharedUtil } from './util.shared-runtime'
import { sharedUtil } from './_util'
```
`bunchee` will bundle the shared module into a separate **layer** which matches the file name convention, in the above case it's "shared", and that bundle will be referenced by the different entry bundles.
`bunchee` will bundle the shared module into a separate chunk, keeping it private and ensuring it's referenced by multiple entry bundles.
</details>
With multiple runtime bundles, such as having `default` and `react-server` together. They could have the modules that need to be shared and kept as only one instance among different runtime bundles. You can use the shared module convention to create shared modules bundles for different runtime bundles.
For scenarios involving multiple runtime bundles, such as `default` and `react-server`, modules that need to be shared and remain as a single instance across different runtime bundles can also follow this convention. The leading underscore (`_`) ensures that these modules are private to your application while facilitating reuse.

@@ -297,11 +297,11 @@ <details>

'use client'
// src/app-context.shared-runtime.js
// src/_app-context.js
export const AppContext = React.createContext(null)
```
Then you can use them in different entry files:
These modules can be imported in various runtime entry files:
```js
// src/index.js
import { AppContext } from './app-context.shared-runtime'
import { AppContext } from './_app-context'
```

@@ -311,9 +311,11 @@

// src/index.react-server.js
import { AppContext } from './app-context.shared-runtime'
import { AppContext } from './_app-context'
```
`app-context.shared-runtime` will be bundled into a separate chunk that only has one instance and be shared among different runtime bundles.
The `_app-context` module will be bundled into a shared chunk that exists as a single instance across different runtime bundles.
</details>
This convention keeps shared modules private while enabling efficient bundling and reuse across your codebase.
### CLI

@@ -320,0 +322,0 @@

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc