ds300 / patch-package

Fix broken node modules instantly πŸƒπŸ½β€β™€οΈπŸ’¨
MIT License
10.44k stars 295 forks source link

patch-package needs to look in the parent's node_modules when invoked on a dependency of another project #356

Open jeffory-orrok opened 3 years ago

jeffory-orrok commented 3 years ago

I am a contributor to a project that has a complex architecture. There is a a job runner whose jobs make calls to third-party APIs through a collection of specialized plugins. The plugins are in turn generated by an independently running factory app which runs in two processes -- one to handle a web front end for human consumption and the other which is the back end that exposes an API where the real work of generating the plugins happens.

The project has begun to use patch-package on both parts of the plugin factory and also within some of the plugins themselves. The trouble is that the factory's back end is installed as a dependency to the front end, and likewise the plugins are installed as dependencies in the cloud version of the job runner, so when patch-package tries to look in node_modules, it doesn't find anything because the (sub)dependencies have been installed up in the parent's node_modules, and we end up with errors like

Error: Patch file found for package grpc-js which is not present at node_modules/@grpc/grpc-js

because @grpc/grpc-js has instead been installed in ../../ (there are two ../ because there's a namespace directory). We sort of kludged a workaround in the case of the factory because my team has control of both the front end and the back end, and so we've just duplicated the patches in both projects. The scenario with the cloud version of the job runner can't be solved the same way because it's under the control of another team, and besides that, duplicating patches is not scalable (there are hundreds of possible plugins).

I was wondering if anyone has encountered a situation like this, and if so, what the solution was. Thanks.

zhfnjust commented 3 years ago

Yes , i have the some error

image

zhfnjust commented 3 years ago

I try change cwd and in mylib/postinstall.js.

it works, but still have other problems. The problem is: When the patch is updated, applying the patch again will fail. After I failed to patch in postinstall.js, I will try to reinstall, automatically , the modules that need to be patched, and then run npx patch-package again, this words when we in the development directory of mylib, but After I published mylib to npm, when other people's projects depend on mylib, and reinstalling , automatically, modules that need to be patched will fail

function isDev() {
    const cwd = process.cwd();
    if (cwd.indexOf("node_modules") > -1) {
        return false;
    }

    return true;
}

function apply(changeDir) {

    const cwd = process.cwd();
    console.log('workspace:', cwd)
    if (!_isDev) {
        if (changeDir) {
            process.chdir('../../');
            console.log('changed workspace:', process.cwd())
        }

        execSync("npx patch-package --patch-dir node_modules/scryptlib/patches --error-on-fail", { stdio: 'inherit' })
    } else {
        execSync("npx patch-package --error-on-fail", { stdio: 'inherit' });
    }
}

try {
    apply(true);
    printFinish();
} catch (error) {

    try {
            // reinstalling ,automatically , the modules that need to be patched
           // this works in development environment but failed after publishing to npm 
            execSync("npm i bsv", { stdio: 'inherit' });
            execSync("npm i json-bigint", { stdio: 'inherit' });
            apply(false);
            printFinish();

    } catch (error) {
        console.error('retry failed', error);
        exit(-1)
    }
}
namgk commented 2 years ago

I'm having the same problem with a monorepo

jeffory-orrok commented 2 years ago

Random thought: I just stumbled upon require.resolve and am wondering if it could be used to correctly obtain the patch target

Royaladvisor26 commented 2 years ago

Random thought: I just stumbled upon require.resolve and am wondering if it could be used to correctly obtain the patch target

@jeffory-orrok Any luck with require.resolve?

yixi8524 commented 1 year ago

+1 same issue with npm local file dependencies, sometime npm will install the libs into parent folder node modules.

Gaarahan commented 1 year ago

Same problem with monorepo: All dep will install into root node_modules. but what i need is patch in sub-module.

my-app/
β”œβ”€ node_modules/
β”‚  β”œβ”€ dep-xxx/             -- where need patch dep installed
β”œβ”€ packages/
β”‚  β”œβ”€ sub-module/
β”‚  β”‚  β”œβ”€ package.json      -- need dep-xxx & patch-package script location
β”œβ”€ package.json
buraks commented 1 year ago

@Gaarahan have you had any luck finding a workaround? I have the same problem with my yarn workspaces setup.

JaakkoLipsanen commented 1 year ago

Any workarounds for this?

APTy commented 1 year ago

I'm still new to node monorepos, but it seems to me a limitation of at least npm workspaces and not patch-package. Even though sub-packages use a package.json, only a root node_modules folder and package-lock.json exists.

For now, I've worked around this by creating a postinstall at the root package.json level and running it before my sub-module builds. Works for me, but I may have a non-standard setup, ymmv

kudlav commented 3 months ago

Duplicate of https://github.com/ds300/patch-package/issues/198