Skip to content

Commit 4d30eef

Browse files
committed
feat: enable installation from GitHub for monorepo packages
This change allows Leva and its plugins to be installed directly from GitHub using pnpm. This is useful for testing unreleased features or using forked versions before PRs are merged. The implementation uses lifecycle event detection and path-based patterns to identify git installations and automatically build production artifacts during installation. This ensures consumers receive fully built packages without requiring local development dependencies. Changes: - Add postinstall script with git install detection via lifecycle events - Add prepare scripts to root and all packages for publish/git install support - Support pnpm's store tmp directory pattern for reliable detection - Enable git installation for all plugin packages (spring, dates, bezier, plot) - Skip builds appropriately for sub-dependencies and local development Installation example: pnpm add "leva@github:user/leva#branch&path:/packages/leva"
1 parent f667265 commit 4d30eef

File tree

9 files changed

+123
-10
lines changed

9 files changed

+123
-10
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
]
1414
},
1515
"scripts": {
16-
"postinstall": "husky install && preconstruct dev",
16+
"postinstall": "node scripts/postinstall.js",
1717
"build": "preconstruct build",
1818
"watch": "preconstruct watch",
1919
"dev": "preconstruct dev",
@@ -94,7 +94,6 @@
9494
"eslint-plugin-react-hooks": "^4.3.0",
9595
"husky": "^7.0.4",
9696
"patch-package": "^6.4.7",
97-
"postinstall-postinstall": "^2.1.0",
9897
"prettier": "^2.5.1",
9998
"pretty-quick": "^3.1.3",
10099
"react": "^18.0.0",

packages/leva/package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
"main": "dist/leva.cjs.js",
55
"module": "dist/leva.esm.js",
66
"types": "dist/leva.cjs.d.ts",
7+
"files": [
8+
"dist",
9+
"src",
10+
"plugin"
11+
],
12+
"scripts": {
13+
"prepare": "node ../../scripts/prepare-package.js"
14+
},
715
"license": "MIT",
816
"repository": {
917
"type": "git",

packages/plugin-bezier/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
"main": "dist/leva-ui-plugin-bezier.cjs.js",
55
"module": "dist/leva-ui-plugin-bezier.esm.js",
66
"types": "dist/leva-ui-plugin-bezier.cjs.d.ts",
7+
"files": [
8+
"dist",
9+
"src"
10+
],
11+
"scripts": {
12+
"prepare": "node ../../scripts/prepare-package.js"
13+
},
714
"license": "MIT",
815
"repository": {
916
"type": "git",

packages/plugin-dates/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
"main": "dist/leva-ui-plugin-dates.cjs.js",
55
"module": "dist/leva-ui-plugin-dates.esm.js",
66
"types": "dist/leva-ui-plugin-dates.cjs.d.ts",
7+
"files": [
8+
"dist",
9+
"src"
10+
],
11+
"scripts": {
12+
"prepare": "node ../../scripts/prepare-package.js"
13+
},
714
"license": "MIT",
815
"repository": {
916
"type": "git",

packages/plugin-plot/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
"main": "dist/leva-ui-plugin-plot.cjs.js",
55
"module": "dist/leva-ui-plugin-plot.esm.js",
66
"types": "dist/leva-ui-plugin-plot.cjs.d.ts",
7+
"files": [
8+
"dist",
9+
"src"
10+
],
11+
"scripts": {
12+
"prepare": "node ../../scripts/prepare-package.js"
13+
},
714
"license": "MIT",
815
"repository": {
916
"type": "git",

packages/plugin-spring/package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
"main": "dist/leva-ui-plugin-spring.cjs.js",
55
"module": "dist/leva-ui-plugin-spring.esm.js",
66
"types": "dist/leva-ui-plugin-spring.cjs.d.ts",
7+
"files": [
8+
"dist",
9+
"src"
10+
],
11+
"scripts": {
12+
"prepare": "node ../../scripts/prepare-package.js"
13+
},
714
"license": "MIT",
815
"repository": {
916
"type": "git",

scripts/postinstall.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const { execSync } = require('child_process')
2+
const { existsSync } = require('fs')
3+
4+
// Skip if explicitly disabled
5+
if (process.env.SKIP_BUILD === '1' || process.env.SKIP_POSTINSTALL === '1') {
6+
process.exit(0)
7+
}
8+
9+
// Detect if this is a git install via pnpm's synthetic script names
10+
// pnpm creates 'npm-install', 'yarn-install', or 'pnpm-install' scripts
11+
// ONLY when preparing git dependencies
12+
const lifecycleEvent = process.env.npm_lifecycle_event
13+
14+
// Detect git install via pnpm's store tmp directory pattern
15+
// pnpm prepares git dependencies in /pnpm/store/v{version}/tmp/
16+
const cwd = process.cwd()
17+
const isPnpmStoreTmp = /[/\\]pnpm[/\\]store[/\\]v\d+[/\\]tmp[/\\]/.test(cwd)
18+
19+
const isGitInstall =
20+
lifecycleEvent === 'npm-install' ||
21+
lifecycleEvent === 'yarn-install' ||
22+
lifecycleEvent === 'pnpm-install' ||
23+
isPnpmStoreTmp
24+
25+
// Skip if installed as sub-dependency in local development
26+
// (Don't skip for git installs - the ../../package.json would be the consuming project)
27+
if (!isGitInstall) {
28+
const isSubDependency = existsSync('../../package.json')
29+
if (isSubDependency) {
30+
process.exit(0)
31+
}
32+
}
33+
34+
if (isGitInstall) {
35+
// Git install: build production files
36+
console.log('Building Leva for GitHub installation...')
37+
try {
38+
execSync('npx preconstruct build', { stdio: 'inherit' })
39+
} catch (e) {
40+
console.error('Build failed:', e.message)
41+
process.exit(1)
42+
}
43+
} else {
44+
// Local development: use dev mode for fast linking
45+
try {
46+
execSync('npx preconstruct dev', { stdio: 'inherit' })
47+
} catch (e) {
48+
console.error('Failed to run preconstruct dev:', e.message)
49+
process.exit(1)
50+
}
51+
}

scripts/prepare-package.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const { execSync } = require('child_process')
2+
const { existsSync } = require('fs')
3+
const path = require('path')
4+
5+
// Skip if explicitly disabled
6+
if (process.env.SKIP_BUILD === '1') {
7+
process.exit(0)
8+
}
9+
10+
const lifecycleEvent = process.env.npm_lifecycle_event
11+
12+
// Git install: synthetic events from pnpm/npm/yarn
13+
const isGitInstall =
14+
lifecycleEvent === 'npm-install' || lifecycleEvent === 'yarn-install' || lifecycleEvent === 'pnpm-install'
15+
16+
// Publishing: prepare runs before pack/publish
17+
// When running from a package, go up to workspace root
18+
// process.cwd() is the package directory (e.g., packages/leva)
19+
const workspaceRoot = path.resolve(process.cwd(), '../..')
20+
const isInWorkspace = existsSync(path.join(workspaceRoot, 'package.json'))
21+
22+
// Only build if:
23+
// 1. Git install (for consumers), OR
24+
// 2. Publishing (not in workspace = preparing for publish)
25+
if (isGitInstall || !isInWorkspace) {
26+
try {
27+
execSync('preconstruct build', {
28+
stdio: 'inherit',
29+
cwd: workspaceRoot,
30+
})
31+
} catch (e) {
32+
console.error('Build failed:', e.message)
33+
process.exit(1)
34+
}
35+
}

yarn.lock

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,7 +2454,6 @@ __metadata:
24542454
eslint-plugin-react-hooks: ^4.3.0
24552455
husky: ^7.0.4
24562456
patch-package: ^6.4.7
2457-
postinstall-postinstall: ^2.1.0
24582457
prettier: ^2.5.1
24592458
pretty-quick: ^3.1.3
24602459
react: ^18.0.0
@@ -15863,13 +15862,6 @@ __metadata:
1586315862
languageName: node
1586415863
linkType: hard
1586515864

15866-
"postinstall-postinstall@npm:^2.1.0":
15867-
version: 2.1.0
15868-
resolution: "postinstall-postinstall@npm:2.1.0"
15869-
checksum: e1d34252cf8d2c5641c7d2db7426ec96e3d7a975f01c174c68f09ef5b8327bc8d5a9aa2001a45e693db2cdbf69577094d3fe6597b564ad2d2202b65fba76134b
15870-
languageName: node
15871-
linkType: hard
15872-
1587315865
"potpack@npm:^1.0.1":
1587415866
version: 1.0.2
1587515867
resolution: "potpack@npm:1.0.2"

0 commit comments

Comments
 (0)