Skip to content

Instantly share code, notes, and snippets.

@stephen-peck
Created September 7, 2017 15:58
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stephen-peck/719ec5419c670677f94e97f7ea40ab56 to your computer and use it in GitHub Desktop.
Save stephen-peck/719ec5419c670677f94e97f7ea40ab56 to your computer and use it in GitHub Desktop.
Forking and patching npm modules from a monorepo

Forking and patching npm modules from a monorepo

Commonly, npm modules are source controlled using a single dedicated repo for each module. When forking and patching such an existing npm module, typical approaches are either:

  • reference a specific git commit in your forked repo
    "dependencies": {
        "patchedmodule": "git+https://github.com/myuser/patchedmodule.git#mypatch"
    }
    "dependencies": {
        "patchedmodule": "https://github.com/myuser/patchedmodule/tarball/<commit hash>"
    }

Difficulty of patching from a monorepo

These common approaches depend on the module's published structure matching that of their backing repository.

If you need to patch a monorepo, where multiple npm modules are source controlled using a single repo, such as those managed using Lerna that will not be the case - files for each module will no longer be at the root of the repo, but in some folder structure below.

e.g. in the case of Lerna the repo structore will be:

    lerna-repo/
        packages/
            <forkedmodule>/
                package.json
        package.json
        lerna.json

Workaround

The most workable approach I've found for such monorepo cases is based on the tarball URL approach above, but since we cannot rely on the tarball generated for download (due to it having the wrong folder structure), we need another way of making such a tarball publicly available.

We will store the tarball under source control (on a dedicated branch) so that it can be referenced as a dependency using a predictable URL to the raw file.

This isn't perfect - ideally we don't want output artifacts in the git repo at all - but it is a relatively painless approach to sharing a usable patch of a third party module; a single file added on a dedicated branch.

The steps:

  • Fork the monorepo
  • Patch with your changes
  • Commit your changes
  • Create a new branch
  • Perform any module build steps that aren't managed by prepublish
  • npm pack - to create an installable tarball for the module
  • Commit the tarball on your new branch
  • Push back to github

Then to reference the package:

  • Update the package dependency to use a tarball URL
    "dependencies": {
        "patchedmodule": "https://github.com/<username>/<repo>/raw/<branch>/[path]/<tarball>

For example, to reference a patched version '0.7.8' of module 'metro-bundler' on branch 'release/patched'

    https://github.com/axsy-dev/metro-bundler/raw/release/patched/packages/metro-bundler/metro-bundler-0.7.8.tgz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment