pnpm list -g shows some packages as "not saved", what does it mean? - pnpm

❯ pnpm list -g
Legend: production dependency, optional only, dev only
/home/mechell/.nvm/versions/node/v14.5.0/pnpm-global/4
dependencies:
nodemon 2.0.4
pnpm 5.3.0
not saved (you should add these dependencies to package.json if you need them):
#types/color-name link:node_modules/.pnpm/#types/color-name#1.1.1/node_modules/#types/color-name%
So what does this mean? When installing typescript as global have more of these and I'm not sure if it's missing it and will it break something...

It means that these packages are installed on your system but not listed in a package.json dependency list. It can happen if the shamefully-hoist option is used (for compatibility reasons) or if npm or yarn installs something - without you knowing - whilst you are using pnpm.
If you do not want to see these "not saved" packages - as I've seen no option pertaining to this in the source code of pnpm - you can do this:
pnpm ls | awk '/^not saved/{stop=1} stop==0{print}'
this will only work on unix/linux based systems, and the awk command will basically remove every line after the one that starts with "not saved".
You can alias it to pnpmls in your ~/.bash_profile or similar and then you only ever have to type pnpmls.
alias pnpmls='pnpm ls | awk "/^not saved/{stop=1} stop==0{print}"'
I am adding it to my bash_profile right now ;)

Related

Do NPM packages have to be installed globally to access their functionality via the command line?

I am having trouble understanding how the -g flag works in NPM. Specifically I'm struggling to understand how it relates to command-line functionality exposed by NPM modules.
I assumed that the difference between installing a package locally and globally was simply that a local package would not be available outside of the particular project. And of course that a globally installed package would be available in any project. I'm from a Rails background so this for me would be similar to installing a gem into a particular RVM versus installing it into the global RVM. It would simply affect which places it was available.
However there seems to be more significance than just scope in NPM. For packages that have command-line functionality, like wait-on, the package (as far as I can tell) is not available on the command line unless it's installed globally.
Local install doesn't make the command-line functionality available:
$ npm install wait-on
$ wait-on
=> -bash: /usr/local/bin/wait-on: No such file or directory
Global install does expose the command-line functionality
$ npm install wait-on -g
$ wait-on
=> Usage: wait-on {OPTIONS} resource [...resource]
Description:
wait-on is a command line utility which will wait for files, ports,
sockets, and http(s) resources to become available (or not available
using reverse flag). Exits with success code (0) when all resources
are ready. Non-zero exit code if interrupted or timed out.
Options may also be specified in a config file (js or json). For
example --config configFile.js would result in configFile.js being
required and the resulting object will be merged with any
Can you expose the command-line functionality using a local install?
Is it possible to install locally but also get the command line functionality? This would be very helpful for my CI setup as it's far easier to cache local modules than global modules so where possible I'd prefer to install locally.
If you are using npm 5.2.0 or later, the npx command is included by default. It will allow you to run from the local node modules: npx wait-on
For reference: https://www.npmjs.com/package/npx
I think you can access locally installed modules from the command line only if you add them to your "scripts" section of your package.json. So to use the locally installed version of wait-on, you can add an entry in "scripts" section of package.json like so "wait-on": "wait-on". Then to run it, you would have to do npm run wait-on. You can also do "wo": "wait-on" and then do npm run wo basically meaning what comes after the run is the script entry. In node_modules, there is a .bin folder and inside of this folder is all the executables that you can access this way.
Installing locally makes the package available to the current project (where it stores all of the node modules in node_modules). This is usually only good for using a module like so var module = require('module'); or importing a module.
It will not be available as a command that the shell can resolve until you install it globally npm install -g module where npm will install it in a place where your path variable will resolve this command.
You can find a pretty decent explanation here.
It is also useful to put commands in the scripts block in package.json as it automatically resolve local commands. That means you could have a script that depended on a package without having an undocumented dependency on the same.
If you need to run it locally on cmd, you have to go inside the node_modules and run from the path.

graphql-codegen not running with config file

In my package.json file I've got script entry that runs graphql-codegen but it complains that the --config argument is invalid:
$> yarn gen
yarn run v1.21.1
$ graphql-codegen --config codegen.yml
Error: Unknown argument: config
...
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Since I believe the default file name is codegen.yml anyway, I try to run it with out that argument and nothing gets generated:
$> yarn graphql-codegen
yarn run v1.21.1
$ /home/aaron/projects/my_app/node_modules/.bin/graphql-codegen
Done in 0.17s.
Any ideas?
for me this solved the issue
Yarn
yarn add -D #graphql-codegen/cli
npm
npm i -D #graphql-codegen/cli
installation guide doc
Ok, I'm not sure exactly what I did to fix this. I believe that I had also installed graphql-codegen globally and tried to uninstall it with sudo npm uninstall graphql-codegen which removed a bunch of packages but the executable still exists:
$>which graphql-codegen
/usr/bin/graphql-codegen
However I decided to run yarn graphql-codegen init on a whim to see if init was valid and because I couldn't remember if I hadn't tried that already. I got the set up questions like normal so I ctrl+C'ed and just ran yarn graphql-codegen and it worked! Then I ran yarn graphql-codegen --watch to test that it took options and that also worked.
If anyone gets this issue, I hope these tips help you.
Try it: rm -rf ./node_modules && npm install
rm http://manpages.ubuntu.com/manpages/trusty/man1/rm.1.html
remove files or directories
-f, --force ignore nonexistent files and arguments, never prompt
-r, -R, --recursive remove directories and their contents recursively
node_modules https://docs.npmjs.com/cli/v7/configuring-npm/folders
You can think of the node_modules folder like a cache
for the external modules that your project depends upon. When you npm
install them, they are downloaded from the web and copied into the
node_modules folder and nodejs is trained to look for them there when
you import them (without a specific path).
npm install https://docs.npmjs.com/cli/install/
This command installs a package and any packages that it depends on.
If the package has a package-lock, or an npm shrinkwrap file, or a
yarn lock file, the installation of dependencies will be driven by
that, respecting the following order of precedence:
npm-shrinkwrap.json
package-lock.json
yarn.lock
Might also be that you have apollo's graphql-codegen package installed, which also exposes a binary called graphql-codegen, which accepts args schema and output, but not config.
For me the solution was to install #graphql-codegen/cli.
graphql.config.yml
schema: http://localhost:8081/graphql
extensions:
codegen:
generates:
./schema.graphql:
- schema-ast
package.json
{
"codegen": "graphql codegen --config graphql.config.yml"
}
I've fixed the problem by using graphql-code-generator instead:
"scripts": {
"graphql:generate": "graphql-code-generator"
}

I didn't run "Yarn add react-native" to a folder, will I run into issues when starting a project? I'm a noob and am just starting out

I used the CLI to install React Native, Node and Python but was not aware if I needed to save it to a file first.
I ran the yarn command:
➜ ~yarn add <package>
I would get this warning message when running yarn check:
➜ ~ yarn check
warning package.json: No license field
warning No license field
warning "jest-haste-map#fsevents#node-pre-gyp#^0.12.0" could be deduped from "0.12.0" to "node-pre-gyp#0.12.0"
Questions:
1. Do I only ~ yarn add when I start a project?
2. Since I've installed python, node, and react-native without creating a project folder will I run into issues down the road?
3. Do I add the json file with the licenses manually when starting a project with yarn?
4. Am I hopeless? lol
I've tried uninstalling and reinstalling from yarn and updating yarn. Also, I've tried installing python and node from Homebrew to see if that changes anything.
Below is a log of the output from the CLI after running ~ yarn check
Last login: Sat Aug 24 02:21:38 on ttys001
➜ ~ yarn check
yarn check v1.17.3
warning package.json: No license field
warning No license field
warning "jest-haste-map#fsevents#node-pre-gyp#^0.12.0" could be deduped from "0.12.0" to "node-pre-gyp#0.12.0"
success Folder in sync.
✨ Done in 1.99s.
Solution I figured it out! So after poking around I realized that once I started a project I had a yarn.lock and package.json file one level up in the directory where the file was located. What I did was I deleted yarn.lock and package.json associated with the folder in the directory. After that was complete I then went into my project and installed the correct packages.
You're not hopeless. This project may be, you've bitten off waaaay more than you can chew yet.
To answer your main question:
yarn add and it's cousin npm install will install the thing you tell them to in the node_modules folder in the directory you run the command in. The reason it's yelling at you is because usually you'll want to save the thing you installed as a dependency of your project, and you can't do that without a package.json file. You should run npm init to set up the package.json file for your project, then running yarn add will actually save it to the dependencies list so that you have a reproducible. If you have a package.json file already, it sounds like you maybe created it by hand (since it's missing a license field?) rather than have npm set it up for you, which is a bad idea.
Two more things:
React Native is awesome! ...But, it's a tool for people who already have good familiarity with Javascript command line/tooling/ecosystem/coding/React to build mobile apps. It is a lousy choice for a first project if you're just getting started with programming. Building a webpage with React is a lot easier, but even that may be too much.
If you really want to build a React Native app and you just can't wait look at this to get started.
But seriously, learn Javascript then npm then yarn then React then React Native. In that order.

Is it possible to go back and change the last input you entered into a command prompt questionnaire?

If I accidentally entered a typo into a command prompt questionnaire, is there a way to go backwards and edit that input?
For example, when I run npm init, I'm given a bunch questions. If I accidentally write a typo in the package name field and press enter, the questionaire moves on to version:. Is there a way to quickly go back to package name and fix my typo?
My experience with the terminal and npm is limited, but I found out that you cannot undo a command line. However, I'm wonder if you CAN undo an answer to a command prompt, since this is a little different- The command hasn't really run yet until all the prompts are done.
Sat Apr 27 npm Dashie$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (npm) oops-typo
version: (1.0.0)
An undo functionality like you are describing would have to be implemented by the developers of the cli tool you are using (in this case, npm).
I think the best I can offer as a means to fix your mistake on the command line, without having to open an editor and modify the package.json file from there, is to use the json npm package.
So in the particular case displayed in your question, you would keep going with the install and afterwards you could simply do:
$ npm i -g json
$ json -I -f package.json -e "this.name='your package name'"
You can edit the package name in the package.json file created when you use init.

Golang equivalent of npm install -g

If I had a compiled Golang program that I wanted to install such that I could run it with a bash command from anywhere on my computer, how would I do that? For example, in nodejs
npm install -g express
Installs express such that I can run the command
express myapp
and express will generate a file directory for a node application called "myapp" in whatever my current directory is. Is there an equivalent command for go? I believe now with the "go install" command you have to be in the directory that contains the executable in order to run it
Thanks in advance!
Update: If you're using Go 1.16, this answer still works, but go install has changed and is now the recommended method for installing executable packages. See Karim's answer for an explanation: https://stackoverflow.com/a/68559728/10490740
Using Go >= 1.11, if your current directory is within a module-based project, or you've set GO111MODULE=on in your environment, go get will not install packages "globally". It will add them to your project's go.mod file instead.
As of Go 1.11.1, setting GO111MODULE=off works to circumvent this behavior:
GO111MODULE=off go get github.com/usr/repo
Basically, by disabling the module feature for this single command, it will install to GOPATH as expected.
Projects not using modules can still go get normally to install binaries to $GOPATH/bin.
There's a lengthy conversation and multiple issues logged about this change in behavior branching from here: golang/go - cmd/go: go get should not add a dependency to go.mod #27643.
Starting with Go >= 1.16 the recommended way to install an executable is to use
go install package#version
For example, go install github.com/fatih/gomodifytags#latest.
Executables (main packages) are installed to the directory named by the GOBIN environment variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set. You need to add this directory to your PATH variable to run executables globally. In my case, I've added this line to my ~/.zshrc file. (if you are using bash, add it to the ~/.bash_profile file):
export PATH="$HOME/go/bin:$PATH"
Go team published a blog post about this change, here's the explanation quote:
We used to recommend go get -u program to install an executable, but this use caused too much confusion with the meaning of go get for adding or changing module version requirements in go.mod.
Refer to go install documentation for more details
As far as I know, there is no direct equivalent to npm install -g. The closest equivalent would not be go install, but go get. From the help page (go help get):
usage: go get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]
Get downloads and installs the packages named by the import paths,
along with their dependencies.
By default, go get installs binaries to $GOPATH/bin, so the easiest way to make those binaries callable from everywhere is to add that directory to your $PATH.
For this, put the following line into your .bashrc (or .zshrc, depending on which shell you're using):
export PATH="$PATH:$GOPATH/bin"
Alternatively, you could also copy or link the executables to /usr/local/bin:
ln -s $GOPATH/bin/some-binary /usr/local/bin/some-binary
Short solution for Linux users:
Use the go get command as usual
Add the following lines to .bashrc:
# This is the default GOPATH, you should confirm with the 'go env' command
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Restart terminal or source it. Installed binaries will be available globally.
For Go v1.8+
go install package_name#latest
Caveat: this answer is outdated following the 2020 deprecation of go get. The solution presented here won't work with newer Go runtime installs.
The closest analogue of this in Go would be go get. By default, it will fetch a Go package from a supplied repository URL, and requires a $GOPATH variable to be set in your shell so that Go knows where to store the packages (and subsequently where to find them when compiling code depending on go get-ted packages).
Example syntax:
$ go get github.com/user/repo
The behaviour supplied by npm's -g flag is default, and packages installed using go get are normally available globally.
See go get --help for more information about the command.
As mentioned by #helmbert, adding your $GOPATH to your $PATH is useful if you're installing standalone packages.
if you are using zsh :
first: install your package using :
go install package#version
then , you edit your .zshrc file
nano ~/.zshrc
Add this line to the end of .zshrc file :
export PATH="$HOME/go/bin:$PATH"
last but not least :
source ~/.zshrc
then open a new terminal and execute your command :)
TL;DR at the bottom. I'm going to walk you through how I came to this conclusion, and why the more obvious solutions don't work.
Upon seeing this question, I thought "If I could set root's GOPATH=/usr, it would install things in /usr/bin/ and /usr/src!"
So I tried the obvious thing:
Add GOPATH=/usr to root's .bashrc.
And it worked!
Sort of.
Not really.
Turns out, sudo doesn't execute root's .bashrc. For "security" or something like that.
Do env_set or something in /etc/sudoers
Turns out, /etc/sudoers can only remove environment variables. There's no env_set directive.
(As far as I can find)
Dig through man sudoers.
Where does sudo get it's default set of environment variables from?
Well, the first one in the list is /etc/environment, so that's the one I used.
sudo echo "GOPATH=/usr" >> /etc/environment
sudo go get <repo>
Binaries will be put in /usr/bin, and sources will be put in /usr/src.
Running go as non-root will use GOPATH the "normal" way.
If you don't have go installed, you may use the gobinaries. it builds an on-demand binary of the project from github repo.
The command to install the go package would be:
curl -sf https://gobinaries.com/rakyll/hey | sh

Resources