Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volta not allowing global installs #555

Open
andrewplummer opened this issue Oct 6, 2019 · 14 comments

Comments

@andrewplummer
Copy link

commented Oct 6, 2019

Volta throws an error Volta error: Global package installs are not supported. on adding a global yarn/npm package. I understand the reasoning for this for projects but a valid use case of global installs are scripts to be run locally outside a project directory, and volta fundamentally breaks this.

I've seen VOLTA_UNSAFE_GLOBAL env posted, however this still doesn't allow requiring the package globally, so it doesn't really serve as a workaround. Is there any other recourse?

@charlespierce

This comment has been minimized.

Copy link
Contributor

commented Oct 6, 2019

Hi @andrewplummer, thanks for reaching out! Can you expand a bit on the use-case you’re needing global installs for? In general, a library that’s installed globally by npm or yarn can’t be imported into an arbitrary script with require().

It can generally be used by other globally installed scripts, and there are a few cases where that can come up, so I’d like to know if your use-case is one we’ve run into before or something new.

At the moment, there isn’t a good story for allowing global installs to share information with one-another, that’s something we need to figure out. Knowing a wider range of uses would make it easier to see the whole picture, so we can come up with a good solution.

@andrewplummer

This comment has been minimized.

Copy link
Author

commented Oct 6, 2019

In general, a library that’s installed globally by npm or yarn can’t be imported into an arbitrary script with require()

Sure it can! I have a number of one-off scripts for when I need to do things that bash just isn't quite up to (manipulating JSON data is a good example).

Here's a good example from a script I have called pretty-print-json

#!/usr/bin/env node

const fs   = require('fs');
const path = require('path');
const argv = require('argv');

const args = argv
  .option([
    {
      short: 'r',
      name: 'replace',
      type: 'boolean',
      description: 'Replace inline (default false).'
    },
    {
      short: 't',
      name: 'tabs',
      type: 'boolean',
      description: 'Use tabs (default false).'
    }
  ]).run();

if (!args.targets.length) {
  throw new Error('No targets provided.');
}

args.targets.forEach(function(p) {
  const fullPath = path.resolve(p);
  const obj = require(fullPath);
  const tabs = args.options.tabs ? '\t' : 2;
  const str = JSON.stringify(obj, null, tabs)
  if (args.options.replace) {
    fs.writeFileSync(fullPath, str);
  } else {
    console.log(str);
  }
});
@charlespierce

This comment has been minimized.

Copy link
Contributor

commented Oct 6, 2019

Interesting! That goes against my testing on this issue. Out of curiosity, where is that pretty-print-json script in your filesystem? And are you using npm or yarn for global installs, as they put the files in different spots.

If we can reproduce this generally, then that’s definitely a new use-case, so thanks!

@andrewplummer

This comment has been minimized.

Copy link
Author

commented Oct 6, 2019

I have it along with a few other scripts in ~/.bin/ ...

I use both, would prefer to use yarn but I'll take what I can get!

@charlespierce

This comment has been minimized.

Copy link
Contributor

commented Oct 6, 2019

Thanks for the info, I’ll do some testing when I’m back at my desk tomorrow and see if I can reliably reproduce that behavior! If so, we’ll need an even better story for interop with global packages.

@ljharb

This comment has been minimized.

Copy link

commented Oct 6, 2019

That script isn’t installed and doesn’t have any dependencies; how does it relate to globally installed npm packages?

@andrewplummer

This comment has been minimized.

Copy link
Author

commented Oct 6, 2019

@ljharb to clarify argv is the package that I would be installing globally here.

@ljharb

This comment has been minimized.

Copy link

commented Oct 6, 2019

@andrewplummer ah, thanks, i missed that.

The problem here though is you aren't declaring which version of argv your script is compatible with, which means it can silently break at any time. The widely accepted way to handle this in the industry is to make a package for your script, with argv as a dep and your script as a "bin", and then while you could globally install it, you could also use npx to invoke it directly at any time.

@andrewplummer

This comment has been minimized.

Copy link
Author

commented Oct 6, 2019

The problem here though is you aren't declaring which version of argv your script is compatible with, which means it can silently break at any time.

Yep, it's not meant to be stable, just a one off script for local use.

The widely accepted way to handle this in the industry is to make a package for your script [...]

Sure, if you're writing a library for consumption by others. But this is intended to be quick and dirty and there's a use case for that too (it's part of the reason package managers allow global installs in the first place). The hassle of having to write a package simply to create a shell script is definitely non-trivial.

@charlespierce

This comment has been minimized.

Copy link
Contributor

commented Oct 7, 2019

Hi @andrewplummer, I just tested this locally on both MacOS and Linux, and regardless of whether or not I have argv installed globally, I always get an error about not being able to find the package when trying to run your script above.

Do you possibly have a custom NODE_PATH environment variable set on your system?

@ljharb

This comment has been minimized.

Copy link

commented Oct 7, 2019

global modules are indeed not requireable by default (nor should be), you'd have to have NODE_PATH set up to be able to do that deprecated thing.

@andrewplummer

This comment has been minimized.

Copy link
Author

commented Oct 8, 2019

@charlespierce of course, NODE_PATH has always been required for global packages. I believe nvm adds it for you

@andrewplummer

This comment has been minimized.

Copy link
Author

commented Oct 8, 2019

Actually scratch that, I believe they used to but it appears they don't anymore. Actually a good workaround here would be to simply set it in each of the required shell scripts. The only issue then is that volta is blocking a global install... it could simply allow it with some kind of override flag, I realize this isn't standard behavior.

@charlespierce

This comment has been minimized.

Copy link
Contributor

commented Oct 11, 2019

@andrewplummer We actually do support an override for this behavior. If you run the yarn global add or npm i -g command with the environment variable VOLTA_UNSAFE_GLOBAL=1 set, then it will bypass the check and allow the global install:

$ VOLTA_UNSAFE_GLOBAL=1 yarn global add argv

And then whatever work you need to do on the script side to ensure that the require happens correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.