Created
April 13, 2022 18:28
-
-
Save cdaringe/66c7cd5f95f74766f9eb1e699fdd7399 to your computer and use it in GitHub Desktop.
pnpm-patch-package.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @description | |
* Support patch-package in pnpm projects. | |
* | |
* `pnpm` can be tricky to use with patch-package. To minimize friction creating patches, | |
* this script helps automate patching by using npm and a temp workspace to generate | |
* patch files. | |
* | |
* @usage | |
* 0. ensure the dependencies of interest are top level dependencies/devDependencies (no patching transitive deps) | |
* 1. pnpm install, then make edits to your dependencies in your node_modules | |
* 2. edit the below `relativePatchedFilenames` | |
* 3. run `node <this-script>` | |
* 4. preview the emitted patch | |
* 5. use the emitted command to copy the patch into the project | |
*/ | |
const relativePatchedFilenames = ["node_modules/foo/index.js"]; | |
const path = require("path"); | |
const srcProjectDirname = process.cwd(); | |
const readLocalPkgJson = () => require(path.resolve(srcProjectDirname, "package.json")); | |
const patchPackageVersion = readLocalPkgJson().devDependencies["patch-package"]; | |
const cp = require("child_process"); | |
const log = (str) => console.log(`[pnpm-pp]`, str); | |
const cmd = (args, opts) => { | |
log(args); | |
cp.execSync(args, { ...opts, stdio: "inherit" }); | |
}; | |
const tempAppDirname = "/tmp/app"; // or os.tmpDir(), whatever | |
const cmdInPatchApp = (args, opts) => cmd(args, { ...opts, cwd: tempAppDirname }); | |
const pkgUp = (filename) => { | |
const pkgJsonDirname = path.dirname(filename); | |
if (pkgJsonDirname === "/") throw new Error(`pkg not found for file`); | |
const pkgJsonFilename = path.resolve(pkgJsonDirname, "package.json"); | |
try { | |
const pkgJson = require(pkgJsonFilename); | |
return pkgJson.name; | |
} catch { | |
return pkgUp(pkgJsonDirname); | |
} | |
}; | |
const pkgsToPatch = [ | |
...new Set(relativePatchedFilenames.map((relative) => path.resolve(srcProjectDirname, relative)).map(pkgUp)).values(), | |
]; | |
cmd(`mkdir -p ${tempAppDirname}`); | |
[ | |
`git init`, | |
`echo node_modules > .gitignore`, | |
`npm init -y`, | |
`rm -rf patches`, | |
`npm install -DE patch-package@${patchPackageVersion} ${pkgsToPatch.join(" ")}`, | |
...relativePatchedFilenames.map( | |
(relative) => `cp "${path.resolve(srcProjectDirname, relative)}" "${path.resolve(tempAppDirname, relative)}"` | |
), | |
...pkgsToPatch.map((pkg) => `npx patch-package ${pkg}`), | |
`ls -al patches`, | |
].forEach((cmd) => cmdInPatchApp(cmd)); | |
console.log(`\n\nTo accept:\n\tcp ${tempAppDirname}/patches/* "${srcProjectDirname}/patches"`); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment