alvis / presetter

🛹 Reuse and manage build scripts, devDependencies and config files from your favourite presets, instead of copy and paste!
MIT License
68 stars 2 forks source link

A preset that has a (peer) dependency on a package in a private repo #9

Closed faassen closed 2 years ago

faassen commented 3 years ago

I have a preset that has a peer dependency on a package that's published on a private github repo. When I use presetter use it takes a long time and then finally crashes complaining it cannot find this dependency on registry.npmjs.org which makes sense as it isn't there.

I tried to put this configuration in a .npmrc in the module that wants to use the preset, but it didn't work. (I'd prefer to have this .npmrc to be part of the preset anyway).

I tried passing through this configuration through the npm_package_repository_url environment variable but it wasn't successful.

Perhaps there's a better way to do this I'm not aware of, or perhaps presetter needs support for this in some way.

alvis commented 3 years ago

I have played around with more scenarios today & here are the findings:

✅ Installing a preset from a private github repo: it's totally fine as installing a preset from a public repo. The caveat is that you have to make sure the repo is installable, i.e. having a prepare life cycle script if your code needed to be compiled, such as typescript ❌ Installing a preset from a local path using the file:// protocol: No you can't because npm doesn't install any peerDependanies from a local module. In fact, it only links under node_modules. ❌ Installing a preset from a private npm registry such as github packages or GCP artifact registry: Today it's not supported since it requires passing the auth token to npm. However, some work is on the way to support this in future.

faassen commented 3 years ago

In my case I am installing a preset from a private github repo (which works) which has a dependency on a package that's in a private npm registry, which I don't see in your checkboxes so I thought I'd make that explicit. So I'm not installing the preset from the private rpm registry in my experiment. This isn't working yet.

It's however true that I need to be able to install a preset from a private npm registry. The work on the way to make this possible - is this in npm or in presetter?

In my scenario, everything's private:

So to make my scenario work I need:

alvis commented 3 years ago

@faassen I have updated presetter to support private registries. Give it a try.

Here is the instruction.

  1. Install presetter from the feat branch via the following in your project
npm install -D 'https://gitpkg.now.sh/alvis/presetter/packages/presetter?feat&scripts.postinstall=npm%20i%20presetter-preset-strict%20%26%26%20npm%20--version%20%26%26%20npm%20run%20bootstrap'
  1. Run npx presetter use <preset in private or public registry> as usual
faassen commented 3 years ago

I think there's some weird reference to ../preset-strict in there that I don't have. I get this:

> presetter@3.0.1 postinstall /home/faassen/projects/projtest/node_modules/presetter
> npm i presetter-preset-strict && npm --version && npm run bootstrap

npm ERR! code ENOLOCAL
npm ERR! Could not install from "../preset-strict" as it does not contain a package.json file.

I am trying to understand the reference to presetter-preset-strict in your URL, why is it there?

I tried modifying it to this:

npm install -D 'https://gitpkg.now.sh/alvis/presetter/packages/presetter?feat&scripts.postinstall=npm%20--version%20%26%26%20npm%20run%20bootstrap'

But that failed with this:

npm run ts-node -- --eval "require('./source/preset.ts').bootstrapPreset({ force: true })" && npm run script -- prepare

> presetter@3.0.1 ts-node /home/faassen/projects/projtest/node_modules/presetter
> ts-node --cwd-mode --compiler-options="{\"esModuleInterop\":true,\"target\":\"es6\"}" --transpile-only --require tsconfig-paths/register "--eval" "require('./source/preset.ts').bootstrapPreset({ force: true })"

sh: line 1: ts-node: command not found
npm ERR! code ELIFECYCLE
alvis commented 3 years ago

Oh. Sorry I forgot to mention, private registry support only with npm7+, so node 16 up. It's due to the limitation of @npm/config.

For the install script, try this one instead:

npm install -D presetter-preset-strict 'https://gitpkg.now.sh/alvis/presetter/packages/presetter?feat&scripts.postinstall=npm%20--version%20%26%26%20npm%20run%20bootstrap'
faassen commented 3 years ago

I'm surprised, as I've been using private registries with node 14 and npm 6 without a problem; is it that the API of npm 6 doesn't support it even though it does have the functionality?

Unfortunately we're still stuck on node 14, so now I need to figure out whether there's a way around this or whether we're blocked by an upgrade of that.

alvis commented 3 years ago

It's a mystery to me as well. The problem is that when you try to load .npmrc with @npmcli/config under node 14, it throws an unknown error. It's fine however on node 16+.

What I understand is that @npmcli/config is a new package for npm7+ and npm uses a different mechanism to resolve the credential before.

I'd try to spare by break time looking into it. But as node 16 has already entered LTS with 14 on its way to phase out, I may need outside help if it's not a quick fix.

faassen commented 3 years ago

Okay, thanks! I'm going to continue my experiment with node 16+ for the time being.

If it should be that I need to support node 14, perhaps I can look into it to try to contribute.

faassen commented 3 years ago

Trying this with node 16:

Error: could not resolve
    at PlaceDep.failPeerConflict (/home/faassen/projects/projtest/node_modules/presetter/node_modules/@npmcli/arborist/lib/place-dep.js:544:25)

And then later:

    at setupPreset (/home/faassen/projects/projtest/node_modules/presetter/source/preset.ts:204:3) {
  code: 'ERESOLVE',
  edge: {
    type: 'dev',
    name: 'presetter-preset-strict',
    spec: '^3.0.1',
    error: 'MISSING',
    from: { location: '/home/faassen/projects/projtest' }
  },
  dep: {
    name: 'presetter-preset-strict',
    version: '3.0.1',
    whileInstalling: {
      name: 'projtest',
      version: '1.0.0',
      path: '/home/faassen/projects/projtest'
    },
    location: 'node_modules/presetter-preset-strict',
    isWorkspace: false,
    dependents: [ [Object] ]
  },
  current: null,
  peerConflict: {
    current: {
      name: 'prettier',
      version: '1.19.1',
      location: 'node_modules/prettier',
      isWorkspace: false,
      dependents: [Array]
    },
    peer: {
      name: 'prettier',
      version: '2.4.1',
      whileInstalling: [Object],
      location: 'node_modules/prettier',
      isWorkspace: false,
      dependents: [Array]
    }
  },
  strictPeerDeps: false,
  force: false,
  isMine: true
}

It's true that my testing preset uses prettier 1.19.1. Apparently because I'm using presetter which uses the strict preset, I'm getting a conflict. In an ideal world I shouldn't have to worry about this implementation detail of presetter, though.

I'm going to try with a more recent version of prettier next.

faassen commented 3 years ago

Okay, I tried to use an updated version of my preset module which uses the same version of prettier (I had to update both the peer and dev dependency to make that work), now I'm on to a new error. I'm using a private module in the private preset, and that doesn't seem to be properly loaded yet. Here's the error (scrubbed for identifying details):

404 Not Found - GET https://registry.npmjs.org/<name private package used by preset> - Not found

I thought these are installed as devDependencies into my project by presetter; I have an .npmrc and it lets me install it manually using the npm command.

alvis commented 3 years ago

I'm guessing if the private registry setting is missing.

In line with npm, when using a private registry you have to use

npx --registry <path to a private registry> presetter use <a preset package in your private registry>

Would you mind sharing with my the exact command you used above?

alvis commented 2 years ago

@faassen node 14 and private registry supports have been added in v3.1. It should support all of your use cases now :)