Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/enormora/packtory
Effortless code bundling and publishing for npm packages
https://github.com/enormora/packtory
bundler bundling monorepo npm package packaging publish publishing versioning
Last synced: 2 months ago
JSON representation
Effortless code bundling and publishing for npm packages
- Host: GitHub
- URL: https://github.com/enormora/packtory
- Owner: enormora
- License: mit
- Created: 2023-09-11T09:46:18.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-29T18:14:14.000Z (2 months ago)
- Last Synced: 2024-10-29T20:18:02.903Z (2 months ago)
- Topics: bundler, bundling, monorepo, npm, package, packaging, publish, publishing, versioning
- Language: TypeScript
- Homepage:
- Size: 1.23 MB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 10
-
Metadata Files:
- Readme: readme.md
- License: LICENSE
Awesome Lists containing this project
README
packtory
Effortless code bundling and publishing for npm packages
🚀 **Simplify and Automate Your Code Bundling and Publishing Workflow with packtory** 🚀
Tired of restrictive monorepo conventions? Fed up with complex workspace setups? Want your monorepo to feel as smooth as a single codebase, effortlessly referencing local files? Think semantic versioning (semver) adds unnecessary complexity, and every version should be treated as potentially breaking anyway? Look no further.
Say goodbye to:
- 🔗 Cumbersome workspaces
- 📦 Dependency linking during development
- 🙅♂️ Manual file selection (e.g. via `.npmignore` or `files`)
- 📄 Shipping unnecessary files (e.g. build configs, tests)
- 🔄 Manual versioning## 🌟 **Introducing packtory: Your Code Organization and Packaging Game Changer** 🌟
**Key Features:**
- **Organize with Freedom**: Manage your monorepo without confining conventions or workspace limitations. packtory simplifies it, just like a single codebase.
- **Effortless Dependency Bundling**: Forget manual dependency linking. packtory automatically detects and bundles dependencies, freeing you to focus on your code.
- **Clean and Efficient Packaging**: Package only essential files, excluding devDependencies, CI configurations, and tests. Keep your npm package clean and efficient.
- **Revolutionary Automatic Versioning**: Choose manual versioning or let packtory handle it. In automatic mode, it calculates versions intelligently, ensuring reproducibility without complexity.
- **Seamless CI Pipeline Integration**: Easily integrate packtory into your CI pipelines for automatic publishing with every commit. No more intricate checks to decide what to publish.## Quick Start
The quickest way to leverage packtory is through its command-line interface (CLI).
**Installation:**
```bash
npm install -D @packtory/cli
```**Configuration:**
Create a configuration file named `packtory.config.js` in your project's root:
```js
import path from 'node:path';
import fs from 'node:fs';export const config = {
// Customize your registry settings, if needed
registrySettings: { token: process.env.NPM_TOKEN },// Common settings shared among packages
commonPackageSettings: {
sourcesFolder: path.join(process.cwd(), 'dist/'),
mainPackageJson: fs.readFileSync('./package.json', { encoding: 'utf8' })
},// Define your packages
packages: [
{
name: 'first-package',
entryPoints: [ { js: 'first.js' } ],
},
{
name: 'second-package',
entryPoints: [ { js: 'second.js' } ],
entryPoints: ,
bundleDependencies: ['first']
}
]
};
```**Publishing:**
Execute the following command from the root of your project, no worries it runs in dry-run mode by default:
```
npx packtory publish
```For more details about the CLI application have a look at the [full documentation](./source/packages/command-line-interface/readme.md).
## Concept
### Bundling
Packtory guarantees minimal packages with:
- No published `devDependencies`
- No unnecessary files, including CI configurations**How Bundling Works:**
1. All source files referenced from the entry point files are resolved into a graph.
2. Imports of `node_modules` and node built-ins are detected and tracked to create a minimal `package.json` later.
3. If bundle dependencies are given, some import statements will be rewritten. For example, if a file in package `first` imports a file in package `second`, the import statement will be rewritten accordingly (e.g., from `import bar from './bar.js'` to `import bar from 'second/bar.js'`).
4. A `package.json` will be generated, and the version numbers of `node_modules` will be taken from the `mainPackageJson` provided in the configuration.### Publishing
**How Publishing Works:**
Packtory supports two versioning modes:
1. **Automatic Versioning (Default) 🔄:**
- Fetch the version details of the latest information available from the registry.
- Download and extract the tarball of the latest version in-memory.
- Compare the contents of all files from the downloaded tarball with the contents of all files resolved from the bundler:
- If all files are the same, no new version is needed.
- If there are any differences, increase the latest version number by one (patch version), generate a new `package.json`, create a tarball, and publish the new version.
- If no version is available in the registry, an initial version will be built and published with version `0.0.1` (default but can be changed in the configuration).2. **Manual Versioning:**
- Provide the exact version number in the configuration.This explanation provides a comprehensive overview of the bundling and publishing processes in Packtory. Feel free to make any further adjustments or let me know if there's anything specific you'd like to emphasize.
## Configuration
The configuration for `packtory` is an object with the following properties:
1. **`registrySettings`** (Required):
- An object with at least a required `token` for authentication.
- Optionally, you can provide a custom `registryUrl` for non-default registries.2. **`commonPackageSettings`** (Optional):
- Defines settings that can be shared for all packages.
- Allowed settings: `sourcesFolder`, `mainPackageJson`, `includeSourceMapFiles`, `additionalFiles`, `additionalPackageJsonAttributes`.3. **`packages`** (Required, Array):
- An array of per-package configurations.
- Each per-package configuration has the following settings:- **`name`** (Required, String):
- Must be unique; the name of the package.
- **`sourcesFolder`** (Required):
- The absolute path to the base folder of the source files.
- All other file paths are resolved relative to this path.- **`mainPackageJson`** (Required):
- The parsed content of the project's `package.json`.
- Needed to obtain version numbers of third-party dependencies.- **`entryPoints`** (Required, Array of Objects):
- An array of entry points with the following shape: `{ js: 'file.js', declarationFile: 'file.d.ts' }`.
- The `js` property is required, while `declarationFile` is optional.- **`includeSourceMapFiles`** (Optional, Boolean, Default: `false`):
- If `true`, the bundler will look for and include source map files in the final package.
- **`additionalFiles`** (Optional, Array of File Descriptions):
- An array to add additional files to the package that are not automatically resolved.
- Example: `{ sourceFilePath: 'LICENSE', targetFilePath: 'LICENSE' }`.
- If defined in both per-package and common settings, they are merged.- **`additionalPackageJsonAttributes`** (Optional, Object):
- An object to be merged directly into the generated `package.json`.
- Useful for setting meta properties like `description` or `keywords`.
- If defined in both per-package and common settings, they are merged.- **`bundleDependencies`** (Optional, Array of Strings):
- An array of package names to mark as dependencies, allowing the bundler to substitute import statements accordingly.
- **`bundlePeerDependencies`** (Optional, Array of Strings):
- Similar to `bundleDependencies` but represented as `peerDependencies` in the generated `package.json`.**Note**: Per-package settings override or merge with common settings when both are defined.
This comprehensive configuration allows fine-tuning for individual packages and provides flexibility in defining dependencies and additional files.
## Example Use-Cases
### 1. Creating CLI Tools
Suppose you have a project with a utility library (`image-resizer-lib`) and a corresponding CLI tool (`image-resizer-cli`) with bin entry points. `packtory` simplifies the bundling and publishing of these packages while ensuring clean and minimal npm packages.
```javascript
// packtory.config.js
export const config = {
registrySettings: { token: process.env.NPM_TOKEN },
commonPackageSettings: {
sourcesFolder: path.join(process.cwd(), 'dist/'),
mainPackageJson: fs.readFileSync('./package.json', { encoding: 'utf8' })
},
packages: [
{
name: 'image-resizer-lib',
entryPoints: [{ js: 'lib.js' }]
},
{
name: 'image-resizer-cli',
entryPoints: [{ js: 'cli.js' }],
bundleDependencies: ['image-resizer-lib']
}
]
};
```### 2. Managing Complex Dependencies
Consider a scenario where you have an ecosystem of packages like `awesome-logger`, `awesome-logger-adapter`, and `awesome-logger-adapter-awesome-target`. `packtory` simplifies the bundling and publishing process, automatically managing dependencies between these packages.
```javascript
// packtory.config.js
export const config = {
registrySettings: { token: process.env.NPM_TOKEN },
commonPackageSettings: {
sourcesFolder: path.join(process.cwd(), 'src/'),
mainPackageJson: fs.readFileSync('./package.json', { encoding: 'utf8' })
},
packages: [
{
name: 'awesome-logger',
entryPoints: [{ js: 'index.js' }]
},
{
name: 'awesome-logger-adapter',
entryPoints: [{ js: 'adapter.js' }],
bundleDependencies: ['awesome-logger']
},
{
name: 'awesome-logger-adapter-awesome-target',
entryPoints: [{ js: 'target.js' }],
bundleDependencies: ['awesome-logger', 'awesome-logger-adapter']
}
]
};
```These examples demonstrate how `packtory` adapts to different project structures and facilitates the efficient bundling and publishing of packages with varying dependencies.