Closed josefaidt closed 5 months ago
Hello @josefaidt - Can you have some time to make this issue progress? Thank 😆
Alternatively, if it's easier to add support for using patch-package, that would go a long way too.
Attempting to create a patch using bunx patch-package <package-name>
fails. The patch-package
outputs the following error:
Copy code
**ERROR** No package-lock.json, npm-shrinkwrap.json, or yarn.lock file.
You must use either npm@>=5, yarn, or npm-shrinkwrap to manage this project's
dependencies.
However, if you have pre-existing patches in the ./patches
directory, you can successfully apply them using the
bunx patch-package
command (or via package.json -> scripts -> "postinstall": "patch-package"
)
As a temporary workaround to generate a patches/package+name+version.patch
file
npm install
to generate a package-lock.json
file (temporarily, we'll remove it later)node-modules/<package-name>
npx patch-package <package-name>
to create the patches/package+name+version.patch
filerm package-lock.json && bun install
I found a new workaround:
bun install --yarn
it just converts bun.lockb into a yarn.lock . (or bun ./bun.lockb > ./yarn.lock
)node-modules/<package-name>
bunx patch-package <package-name>
rm yarn.lock
"postinstall": "bunx patch-package"
https://github.com/ds300/patch-packageIt would be nice to see this to facilitate https://github.com/angular/angular/issues/46719
Any plans to implement this? @Jarred-Sumner
I found a new workaround:
- run
bun install --yarn
it just converts bun.lockb into a yarn.lock- make the necessary modifications inside
node-modules/<package-name>
bunx patch-package <package-name>
- package.json -> scripts ->
"postinstall": "patch-package"
ds300/patch-package
this works with one minor tweak: "postinstall": "bunx patch-package"
if patch-package is not in your dependencies
+1 pnpm patch is no nice to have and definetely a blocking feature before adopting bun in some of my repos
I found a new workaround:
- run
bun install --yarn
it just converts bun.lockb into a yarn.lock- make the necessary modifications inside
node-modules/<package-name>
bunx patch-package <package-name>
- package.json -> scripts ->
"postinstall": "patch-package"
ds300/patch-package
This wont work though for platforms like vercel that determines the package manager by which lockfile you have in the repo, so if you have a yarn.lock
they will use yarn to install deps unless i put in manual overrides :/
I'm very certain you only need the yarn.lock
so that patch-package
can determine what package to retrieve for you to be able to modify them. You don't need to commit the yarn.lock
file after creating the patch.
I got patch-package
working with Bun! Simply add --yarn
when you bun install
. This creates a yarn.lock
file for you.
bun install --yarn
You can now use patch-package
:
bunx patch-package moti
I found a new workaround:
run
bun install --yarn
it just converts bun.lockb into a yarn.lockmake the necessary modifications inside
node-modules/<package-name>
bunx patch-package <package-name>
package.json -> scripts ->
"postinstall": "patch-package"
This wont work though for platforms like vercel that determines the package manager by which lockfile you have in the repo, so if you have a
yarn.lock
they will use yarn to install deps unless i put in manual overrides :/
It works, my production repos are using it. Moreover, vercel already supports bun for building.
Instead of adding a bun patch
command i propose adding a bun vendor package
command that
node_modules/package
to a vendor/package
foldernode_modules
This command can be used
node_modules
we probably will do bun pm patch
we've looked into adding it but are unhappy with the performance of various diff/patch libraries
seem patch-package
not work for non-npm dependencies such as git even i manually prepare the patch file,
is there any workaround?
please don't worry about performance for the first version (of course unless it is unreasonably slow). a good enough is better than not having this feature at all
+1 for having some kind of solution even if its performance is not on par with rest of the project.
- unx patch-package
I followed your steps but I'm getting the following error.
bunx patch-package drizzle-kit
patch-package 8.0.0
• Creating temporary folder
• Installing drizzle-kit@0.20.13 with yarn
21 | function spawnSync(command, args, options) {
22 | // Parse the arguments
23 | const parsed = parse(command, args, options);
24 |
25 | // Spawn the child process
26 | const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
^
TypeError: Executable not found in $PATH: "yarn"
code: "ERR_INVALID_ARG_TYPE"
at node:child_process:173:47
at spawnSync (/private/tmp/patch-package@latest--bunx/node_modules/cross-spawn/index.js:26:20)
at spawnSafeSync (/private/tmp/patch-package@latest--bunx/node_modules/patch-package/dist/spawnSafe.js:11:20)
at makePatch (/private/tmp/patch-package@latest--bunx/node_modules/patch-package/dist/makePatch.js:131:17)
at /private/tmp/patch-package@latest--bunx/node_modules/patch-package/dist/index.js:72:13
at forEach (:1:21)
at /private/tmp/patch-package@latest--bunx/node_modules/patch-package/dist/index.js:71:9
at /private/tmp/patch-package@latest--bunx/node_modules/patch-package/index.js:3:1
21 | function spawnSync(command, args, options) {
22 | // Parse the arguments
23 | const parsed = parse(command, args, options);
24 |
25 | // Spawn the child process
26 | const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
^
TypeError: Executable not found in $PATH: "yarn"
code: "ERR_INVALID_ARG_TYPE"
at node:child_process:173:47
at spawnSync (/private/tmp/patch-package@latest--bunx/node_modules/cross-spawn/index.js:26:20)
at spawnSafeSync (/private/tmp/patch-package@latest--bunx/node_modules/patch-package/dist/spawnSafe.js:11:20)
at makePatch (/private/tmp/patch-package@latest--bunx/node_modules/patch-package/dist/makePatch.js:131:17)
at /private/tmp/patch-package@latest--bunx/node_modules/patch-package/dist/index.js:72:13
at forEach (:1:21)
at /private/tmp/patch-package@latest--bunx/node_modules/patch-package/dist/index.js:71:9
at /private/tmp/patch-package@latest--bunx/node_modules/patch-package/index.js:3:1
Is installing yarn
a must?
In the meantime, I just slapped together some naive implementation of a patcher (just copies packages by name from node_modules
to a ./patches
dir with a command, then destructively pastes them back to node_modules
with another command) to scratch this itch. It should work with anything (npm, yarn, pnpm, bun, etc.) with the same API (just swap out npx
for bunx
where appropriate).
https://github.com/corysimmons/patcheer
It seems to work well for my needs and should be as fast as $ cp
In the meantime, I just slapped together some naive implementation of a patcher (just copies packages by name from
node_modules
to a./patches
dir with a command, then destructively pastes them back tonode_modules
with another command) to scratch this itch. It should work with anything (npm, yarn, pnpm, bun, etc.) with the same API (just swap outnpx
forbunx
where appropriate).https://github.com/corysimmons/patcheer
It seems to work well for my needs and should be as fast as
$ cp
Why can't we just edit the code in node_modules
? I'm guessing it will be overwritten by the original package's code when redeployed to production. But then, how is your solution any different?
I forked a bun-friendly fork of patch-package
, built it and pushed the dist/
to the repo. Works for me 🤷
Fork and build this, if you want to try the same: https://github.com/Strengthless/patch-package
Why can't we just edit the code in node_modules? I'm guessing it will be overwritten by the original package's code when redeployed to production. But then, how is your solution any different?
Exactly. Anytime someone (or your server when you deploy) runs bun install
on your project, it is just going to install the packages straight from npmjs.com. To get around this, you commit your ./patches
directory, then there are special npm script names like "postinstall"
that will execute whatever is in there. So you could do "postinstall": "echo \"All my packages downloaded and installed!\""
.
In most of these patching libraries, you just run the command to apply all your patches.
In my project it's "postinstall": "npx patcheer apply"
(which will just forcefully/destructively/recursively copy/pastes whatever dirs are in ./patches
to ./node_modules
)
In patch-package (the most popular package for this kind of stuff) it's "postinstall": "patch-package"
(which does a lot of complicated stuff--making it lag behind in support when these new package managers come out).
It is entirely possible my project is insanely naive and there are good reasons for a patching library to be so big, but again, my lib more than suits my needs unless someone tells me otherwise or I run into something crazy. 🤷
Update: Apparently, Bun just doesn't work on Vercel with the postinstall
hook (it works locally just fine?). Since I'm working alone, I can use Bun locally (for the speed 🚗💨) and commit the Bun lockfile, and in the Vercel Dashboard I can force my build command to be npm i
so postinstall
works again.
On a team, or on a production project with over a few hundred users, this would be a dealbreaker as I'd want my local env to 1:1 prod as much as possible.
(per @rikur's comment immediately below... Bun builds work on Vercel if you just
bun i -D postinstall-postinstall
)
@corysimmons FYI I got around the postinstall issue by using postinstall-postinstall
package 🙃
@corysimmons FYI I got around the postinstall issue by using
postinstall-postinstall
package 🙃
@rikur Do you see Applying patches...
message in your Vercel build logs? I have done the following:
postinstall-postinstall
patch-package
"postinstall": "patch-package"
script to package.json
bun install --yarn
workaround mentioned above)But I don't see any message in my Vercel build logs to mention that the patches are being applied.
@resthedev I can't speak for patch-package
but @rikur's fix worked for my patching package with my Vercel build. I just set my Vercel build command to bun i
(I didn't append the --yarn
flag), then bun add -D postinstall-postinstall
& committed/pushed. And the build succeeded. 🎉
@resthedev I can't speak for
patch-package
but @rikur's fix worked for my patching package with my Vercel build. I just set my Vercel build command tobun i
(I didn't append the--yarn
flag), thenbun add -D postinstall-postinstall
& committed/pushed. And the build succeeded. 🎉
I see. Do you mean you put bun i
in the Vercel "build" command or the "install" command?
Yes, it should recognize it based on there only being a bun.lockb
file in your project root and automatically run bun install
but I don't trust it so I just manually add bun i
to it.
I was migrating to Bun and realized I wouldn't be able to use patch-package
. I guess I'll have to wait.
@gustavopch I provide a workaround a couple of comments above yours.
bun add -D patcheer postinstall-postinstall
bunx patcheer copy <package_name>
./patches/<package_name>
bunx patcheer apply
"postinstall": "bunx patcheer apply"
to your scripts
in your package.json
.bun install
.This should work locally and in any hosting env that supports Bun (i.e. it's working on Vercel for me). Ping me if something doesn't work.
Unsubscribing from this thread now. 💨
@corysimmons Even if I do this, it only modifies the node_modules, and the actual running code doesn't change. But are there cases where this actually works? I'm using expo with bun.
@Jarred-Sumner some workaround in the meantime?
@AngeloCloudAcademy you can try this with postinstall-postinstall
. Been using it for months now without issues.
https://github.com/oven-sh/bun/issues/2336#issuecomment-1915943659
i'm doing this in the meantime
I got
patch-package
working with Bun! Simply add--yarn
when youbun install
. This creates ayarn.lock
file for you.bun install --yarn
You can now use
patch-package
:bunx patch-package moti
this works, also adding yarn.lock
to .gitignore
so that it doesn't get commited
After numerous amount of experiments, I found that patching patch-package
by itself to rewrite a called package manager to bun
from yarn
, works. (Confirmed in local environment without yarn
, GitHub Actions, Vercel)
Specify a --yarn
flag like bun install --yarn
or add the following lines to your bunfig.toml
in order to generate yarn.lock
file.
This is needed since patch-package
currently does not support bun's binary lockfile format. (See https://github.com/ds300/patch-package/issues/489)
[install.lockfile]
print = "yarn" # Whether to generate a non-Bun lockfile alongside bun.lockb
[!WARNING] I personally recommend the later one since you need to generate the yarn v1 lockfile every time you update dependencies.
patch-package
Then, add patch-package
to dev dependencies.
bun add -D patch-package
patch-package
Open node_modules/patch-package/dist/makePatch.js
and look for spawnSafe_1.spawnSafeSync
that spawns yarn
, then replace it with bun
like this diff:
diff --git a/node_modules/patch-package/dist/makePatch.js b/node_modules/patch-package/dist/makePatch.js
index d8d0925..874284a 100644
--- a/node_modules/patch-package/dist/makePatch.js
+++ b/node_modules/patch-package/dist/makePatch.js
@@ -120,7 +120,7 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
try {
// try first without ignoring scripts in case they are required
// this works in 99.99% of cases
- spawnSafe_1.spawnSafeSync(`yarn`, ["install", "--ignore-engines"], {
+ spawnSafe_1.spawnSafeSync(`bun`, ["install"], {
cwd: tmpRepoNpmRoot,
logStdErrOnError: false,
});
@@ -128,7 +128,7 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
catch (e) {
// try again while ignoring scripts in case the script depends on
// an implicit context which we haven't reproduced
- spawnSafe_1.spawnSafeSync(`yarn`, ["install", "--ignore-engines", "--ignore-scripts"], {
+ spawnSafe_1.spawnSafeSync(`bun`, ["install", "--ignore-scripts"], {
cwd: tmpRepoNpmRoot,
});
}
[!NOTE] You can remove
--ignore-engines
flag without worrying since bun does not supportengines
field inpackage.json
at the moment. (See https://github.com/oven-sh/bun/issues/5846)
patches/
This command looks like pure madness, but surprisingly it worked 😮
bun patch-package patch-package
Now, patches/patch-package+8.0.0.patch
should be created.
postinstall
command to package.json
As it is written in patch-package
documentation.
{
"name": "reoiam-dev",
"version": "0.0.0",
"workspaces": [
"apps/*",
"packages/*"
],
"scripts": {
"postinstall": "patch-package",
},
bun patch-package @acme/some-package
Also, run git clean -dfX && bun i
to check if it is working.
Example commits: https://github.com/ReoHakase/reoiam-dev/pull/122/commits/2c016376918356d46ae59a2199e687aec085fb76 https://github.com/ReoHakase/reoiam-dev/pull/122/commits/8aae34e0c072b389b165a04870ba9a631355d1a6
I would also like to add that it would be awesome to support something like Yarn does with resolutions:
package.json
:
{
"resolutions": {
"some-library:1.2.3": "patch:patch-file",
"other-library:1.0.0": "http://alternate-source/file.tgz",
"final-library:100.0.0": "./dir/final-library-fork"
}
}
This support pretty much every use case:
I followed the steps by @ReoHakase and it worked for public packages. But to make it work with our private registry I had to do the following changes:
diff --git a/node_modules/patch-package/dist/makePatch.js b/node_modules/patch-package/dist/makePatch.js
index d8d0925..7c488cd 100644
--- a/node_modules/patch-package/dist/makePatch.js
+++ b/node_modules/patch-package/dist/makePatch.js
@@ -109,18 +109,18 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
resolutions: resolveRelativeFileDependencies_1.resolveRelativeFileDependencies(appPath, appPackageJson.resolutions || {}),
}));
const packageVersion = getPackageVersion_1.getPackageVersion(path_1.join(path_1.resolve(packageDetails.path), "package.json"));
- [".npmrc", ".yarnrc", ".yarn"].forEach((rcFile) => {
+ [".npmrc", ".yarnrc", ".yarn", "bunfig.toml", ".env"].forEach((rcFile) => {
const rcPath = path_1.join(appPath, rcFile);
if (fs_extra_1.existsSync(rcPath)) {
fs_extra_1.copySync(rcPath, path_1.join(tmpRepo.name, rcFile), { dereference: true });
}
});
if (packageManager === "yarn") {
- console_1.default.info(chalk_1.default.grey("•"), `Installing ${packageDetails.name}@${packageVersion} with yarn`);
+ console_1.default.info(chalk_1.default.grey("•"), `Installing ${packageDetails.name}@${packageVersion} with bun`);
try {
// try first without ignoring scripts in case they are required
// this works in 99.99% of cases
- spawnSafe_1.spawnSafeSync(`yarn`, ["install", "--ignore-engines"], {
+ spawnSafe_1.spawnSafeSync(`bun`, ["install"], {
cwd: tmpRepoNpmRoot,
logStdErrOnError: false,
});
@@ -128,7 +128,7 @@ function makePatch({ packagePathSpecifier, appPath, packageManager, includePaths
catch (e) {
// try again while ignoring scripts in case the script depends on
// an implicit context which we haven't reproduced
- spawnSafe_1.spawnSafeSync(`yarn`, ["install", "--ignore-engines", "--ignore-scripts"], {
+ spawnSafe_1.spawnSafeSync(`bun`, ["install", "--ignore-scripts"], {
cwd: tmpRepoNpmRoot,
});
}
I had to specify "bunfig.toml", ".env"
extra in the list of files to copy into the temporary folder. This is to make sure that bun can find the private registry in the bunfig.toml
file.
bunfig.toml
to add the following
[install.lockfile]
print = "yarn" # Whether to generate a non-Bun lockfile alongside bun.lockb
bun add -D patch-package
node_modules/patch-package/dist/makePatch.js
as shown abovebun patch-package patch-package
postinstall
script
{
"name": "reoiam-dev",
"version": "0.0.0",
"workspaces": [
"apps/*",
"packages/*"
],
"scripts": {
"postinstall": "patch-package",
}
bun install --force
patch-package
flowsFor those tracking this issue, I am currently working on this. Patching a package will behave similarly to pnpm, through the bun patch <pkg>
and bun patch-commit <path>
commands.
Yarn's patch protocol will also be supported.
My work-in-progress PR for this feature is here.
The merged implementation of bun patch
does not meet our quality bar. Leaving this open until #11719 is completed
Fixed by @zackradisic in #11858
Attempted to use this and am running into this issue? Am I doing something wrong here?
@Scalahansolo
My fixes in this PR (#12022) might fix this. There were issues running bun patch
in workspaces and with scoped packages
Still doesn't work in our monorepo on 1.1.16
cc @zackradisic
@Scalahansolo can you file an issue and @zackradisic will fix it?
Is there a way to prepare multiple packages for patching at once?
Something like bun patch pkg1 pkg2
and same for bun patch --commit pkg1 pkg2
What is the problem this feature would solve?
I am currently working with a few dependencies that will cause errors at runtime due to their imports, and I'd also like to apply general changes without suggesting changes to the projects.
Today I'm using
pnpm
to manage dependencies andbun
to run the project, which is fine for the most part. Unfortunatelypatch-package
will not work as it is looking for npm & yarn lockfiles.What is the feature you are proposing to solve the problem?
bun patch
pnpm patch
bun patch <dependency-name>
allows the developer to modify dependenciesbun patch --apply <dependency-name>
applies the patch/private/var/folders
and requires the developer to pass the full directory path when applying a patch withpnpm patch-commit <directory-path>
What alternatives have you considered?
No response