monocrate 0.5.0 → 0.7.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 +75 -148
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,193 +1,120 @@
|
|
|
1
1
|
# Monocrate
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/monocrate)
|
|
4
|
+
[](https://github.com/imaman/monocrate/actions/workflows/ci.yml)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
From monorepo to npm in one command.
|
|
6
8
|
|
|
7
|
-
##
|
|
9
|
+
## Why
|
|
8
10
|
|
|
9
|
-
Publishing
|
|
11
|
+
Publishing from a monorepo breaks when your package depends on internal packages. npm doesn't understand workspace references like `@myorg/utils`. You're forced to either publish every internal package separately, manually copy and merge files, or bundle everything into a single file (losing module structure and type declarations).
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
2. **Manual bundling** - Copy files, manually merge package.json dependencies, hope you didn't miss anything
|
|
13
|
-
3. **Complex build pipelines** - Esbuild/Rollup/Webpack configurations that bundle everything into a single file, losing the module structure
|
|
13
|
+
Monocrate gives you:
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
- **One command** — point at your package, done
|
|
16
|
+
- **Self-contained output** — internal dependencies are included, nothing else to publish
|
|
17
|
+
- **Preserved module structure** — no flattening into a single file, tree-shaking works
|
|
18
|
+
- **Type declarations included** — `.d.ts` files just work
|
|
19
|
+
- **Open-source mirroring** — `--mirror-to` copies sources to a public repo alongside publishing
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
monorepo/
|
|
21
|
-
packages/
|
|
22
|
-
app/ <-- You want to publish this
|
|
23
|
-
utils/ <-- app depends on this
|
|
24
|
-
core/ <-- utils depends on this
|
|
25
|
-
|
|
26
|
-
$ monocrate bundle @myorg/app --output ./publish
|
|
27
|
-
|
|
28
|
-
publish/
|
|
29
|
-
index.js <-- app's compiled code
|
|
30
|
-
_deps/
|
|
31
|
-
_myorg_utils/ <-- utils' compiled code
|
|
32
|
-
_myorg_core/ <-- core's compiled code
|
|
33
|
-
package.json <-- Merged dependencies from all packages
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Installation
|
|
21
|
+
## Install
|
|
37
22
|
|
|
38
23
|
```bash
|
|
39
24
|
npm install -g monocrate
|
|
40
25
|
```
|
|
41
26
|
|
|
42
|
-
|
|
27
|
+
## Usage
|
|
43
28
|
|
|
44
29
|
```bash
|
|
45
|
-
|
|
30
|
+
# Prepare for inspection without publishing
|
|
31
|
+
monocrate prepare packages/my-app
|
|
32
|
+
|
|
33
|
+
# Publish directly to npm
|
|
34
|
+
monocrate publish packages/my-app --bump patch
|
|
46
35
|
```
|
|
47
36
|
|
|
48
|
-
|
|
37
|
+
### Commands
|
|
49
38
|
|
|
50
|
-
|
|
39
|
+
**`prepare <packages...>`** — Assemble packages but don't publish. Useful for inspecting output or manual publishing.
|
|
51
40
|
|
|
52
|
-
|
|
53
|
-
# Ensure all packages have been compiled to their dist/ directories
|
|
54
|
-
npm run build --workspaces
|
|
55
|
-
```
|
|
41
|
+
**`publish <packages...>`** — Assemble and publish to npm.
|
|
56
42
|
|
|
57
|
-
|
|
43
|
+
### Options
|
|
58
44
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
| Flag | Description |
|
|
46
|
+
|------|-------------|
|
|
47
|
+
| `-b, --bump` | Version bump: `patch`, `minor`, `major`, or explicit version like `1.2.3`. Defaults to `minor`. |
|
|
48
|
+
| `-o, --output` | Output directory. Defaults to a temp directory. |
|
|
49
|
+
| `-r, --root` | Monorepo root. Auto-detected if omitted. |
|
|
50
|
+
| `-m, --mirror-to` | Mirror source files to another directory (for open-source mirrors). |
|
|
51
|
+
| `--report` | Write the resolved version to a file instead of stdout. |
|
|
62
52
|
|
|
63
|
-
|
|
53
|
+
### Examples
|
|
64
54
|
|
|
65
55
|
```bash
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
# Bump patch version and publish
|
|
57
|
+
monocrate publish packages/cli --bump patch
|
|
68
58
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
Monocrate can be used as a library in your build scripts:
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
import { bundle } from 'monocrate';
|
|
59
|
+
# Publish multiple packages with synchronized versions
|
|
60
|
+
monocrate publish packages/core packages/cli
|
|
75
61
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
monorepoRoot: '/path/to/monorepo',
|
|
79
|
-
outputDir: '/tmp/my-app-bundle',
|
|
80
|
-
});
|
|
62
|
+
# Prepare to a specific directory for inspection
|
|
63
|
+
monocrate prepare packages/app --output ./publish-staging
|
|
81
64
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
console.log('Included packages:', result.includedPackages);
|
|
85
|
-
console.log('Dependencies:', result.mergedDependencies);
|
|
86
|
-
} else {
|
|
87
|
-
console.error('Bundle failed:', result.error);
|
|
88
|
-
console.error('Details:', result.details);
|
|
89
|
-
}
|
|
65
|
+
# Mirror sources to a public repo after publishing
|
|
66
|
+
monocrate publish packages/sdk --mirror-to ../public-repo/packages
|
|
90
67
|
```
|
|
91
68
|
|
|
92
|
-
|
|
69
|
+
## How It Works
|
|
93
70
|
|
|
94
|
-
|
|
71
|
+
1. Discovers all packages in the monorepo via workspace configuration
|
|
72
|
+
2. Builds a dependency graph starting from your target package
|
|
73
|
+
3. Copies each package's publishable files (determined by `npm pack`) to the output
|
|
74
|
+
4. Rewrites import statements from package names to relative paths (using `exports` or `main` fields)
|
|
75
|
+
5. Generates a `package.json` with merged third-party dependencies
|
|
95
76
|
|
|
96
|
-
|
|
97
|
-
import { bundlePackage } from 'monocrate';
|
|
77
|
+
### Output Structure
|
|
98
78
|
|
|
99
|
-
// Automatically discovers packages from workspace configuration
|
|
100
|
-
const result = await bundlePackage('@myorg/app', '/tmp/bundle');
|
|
101
79
|
```
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
### Version Conflict Strategies
|
|
117
|
-
|
|
118
|
-
When multiple packages depend on the same third-party package with different versions:
|
|
119
|
-
|
|
120
|
-
- **`'highest'`** - Silently use the highest semver-compatible version
|
|
121
|
-
- **`'warn'`** - Use highest version, but log a warning
|
|
122
|
-
- **`'error'`** - Fail the bundle operation
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
const result = await bundle({
|
|
126
|
-
// ...
|
|
127
|
-
versionConflictStrategy: 'error', // Strict mode
|
|
128
|
-
});
|
|
80
|
+
monorepo/
|
|
81
|
+
packages/
|
|
82
|
+
app/ ← you want to publish this
|
|
83
|
+
utils/ ← app depends on this
|
|
84
|
+
core/ ← utils depends on this
|
|
85
|
+
|
|
86
|
+
output/
|
|
87
|
+
package.json ← merged deps, in-repo refs removed
|
|
88
|
+
<app files> ← app's publishable files
|
|
89
|
+
deps/
|
|
90
|
+
packages/
|
|
91
|
+
utils/ ← utils' publishable files (imports rewritten)
|
|
92
|
+
core/ ← core's publishable files (imports rewritten)
|
|
129
93
|
```
|
|
130
94
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
1. **Discover packages** - Reads workspace configuration (npm, yarn, or pnpm) to find all packages in the monorepo
|
|
134
|
-
|
|
135
|
-
2. **Build dependency graph** - Starting from your target package, recursively finds all in-repo dependencies and builds a topologically-sorted graph
|
|
136
|
-
|
|
137
|
-
3. **Validate builds** - Ensures all packages have been compiled (have a `dist/` directory)
|
|
138
|
-
|
|
139
|
-
4. **Assemble bundle** - Copies compiled code:
|
|
140
|
-
- Root package's `dist/` goes to output root
|
|
141
|
-
- Dependencies' `dist/` go to `_deps/<package-name>/`
|
|
142
|
-
|
|
143
|
-
5. **Transform package.json** - Generates a publish-ready package.json:
|
|
144
|
-
- Removes workspace-specific fields (`workspaces`, `private`, `devDependencies`)
|
|
145
|
-
- Removes in-repo dependencies
|
|
146
|
-
- Merges third-party dependencies from all included packages
|
|
147
|
-
|
|
148
|
-
## Bundle Result
|
|
149
|
-
|
|
150
|
-
The `bundle()` function returns a discriminated union:
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
// Success
|
|
154
|
-
{
|
|
155
|
-
success: true,
|
|
156
|
-
outputPath: string, // Path to the bundle
|
|
157
|
-
packageJson: PackageJson, // Generated package.json
|
|
158
|
-
mergedDependencies: object, // All third-party deps
|
|
159
|
-
includedPackages: string[], // List of bundled packages
|
|
160
|
-
versionConflicts: VersionConflict[], // Any conflicts found
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Failure
|
|
164
|
-
{
|
|
165
|
-
success: false,
|
|
166
|
-
error: string, // Error message
|
|
167
|
-
details?: string, // Additional context
|
|
168
|
-
cause?: Error, // Underlying error
|
|
169
|
-
}
|
|
170
|
-
```
|
|
95
|
+
Entry points (`main`, `types`, `exports`) work unchanged because each package's file structure stays in the same relative position.
|
|
171
96
|
|
|
172
97
|
## Requirements
|
|
173
98
|
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
-
|
|
99
|
+
- Node.js 20+
|
|
100
|
+
- Packages must have valid entry points (`exports` or `main` field in package.json)
|
|
101
|
+
- Monorepo must use npm, yarn, or pnpm workspaces
|
|
177
102
|
|
|
178
|
-
##
|
|
179
|
-
|
|
180
|
-
Monocrate automatically detects your package manager from:
|
|
103
|
+
## Programmatic API
|
|
181
104
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- Lock files (`pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`)
|
|
105
|
+
```typescript
|
|
106
|
+
import { monocrate } from 'monocrate';
|
|
185
107
|
|
|
186
|
-
|
|
108
|
+
const result = await monocrate({
|
|
109
|
+
pathToSubjectPackages: ['packages/my-app'],
|
|
110
|
+
cwd: process.cwd(),
|
|
111
|
+
publish: false,
|
|
112
|
+
bump: 'minor',
|
|
113
|
+
});
|
|
187
114
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
115
|
+
console.log(result.resolvedVersion); // "1.3.0"
|
|
116
|
+
console.log(result.outputDir); // "/tmp/monocrate-xyz/my-app"
|
|
117
|
+
```
|
|
191
118
|
|
|
192
119
|
## License
|
|
193
120
|
|