Skip to content
This repository has been archived by the owner. It is now read-only.

run-scripts are too noisy while used in development #8821

Closed
ngryman opened this Issue Jul 4, 2015 · 44 comments

Comments

Projects
None yet
@ngryman
Copy link

ngryman commented Jul 4, 2015

Hi,

As many other users, I'm starting to use npm as a development tool for simple projects. Now that the ecosystem provides enough matured cli tools to do most of the things we want, gulp or grunt can be overkill for small projects.

tl;dr: run-scripts seems to be mostly addressed to package users, not developers. As developers, we would like to be able to use npm for development, and run in silent mode.

As you already know, a run-script that exits with a non-zero error code triggers additional logging and a npm-debug.log. These are not necessary in a development flow usage, as you:

  • expect to understand what's going wrong, because you are the developer, not the user.
  • expect tools to fail during development (lint, test, build, ...).
  • process failures and report them with the adapted tool.

To counter this, developers can use the || true trick which is very dangerous, or manually add --silent which is unnecessary verbose.

I totally understand the effort of communicating to the user that some script has failed and that is not related to npm. But I don't understand it anymore when it's addressed to the developer itself.
It seems that run-scripts usage is evolving in a way that was perhaps not intended by npm.

It would be awesome if we had a control on that log level somehow. Multiple solutions could be explored.

dev-scripts

Would be the brother of run-script and invoked like this: npm dev. It would run in silent mode. The name can change, but it would be clear that these kind of scripts are used for development purposes only. It's like devDependencies but for scripts.

more shortcuts

test for example is available as npm test and runs in silent mode (note that npm run test runs in verbose mode). Adding more shortcuts targeting most development use cases could do the job: lint, build, ...

package.json: additional config variable

Like the existing loglevel variable but for run-scripts.

package.json: deeper script property

Adding the possibility to specify a nested object like this for scripts:

"scripts": {
  "lint": {
    "command": "eslint lib/*.js",
    "loglevel": "silent"
  }
}

support of an environment variable

Something like NPM_RUNSCRIPT_LOGLEVEL=silent npm run lint would be slient. We could setup our dev / ci environment accordingly.


We can choose one or several of those propositions, but my personal taste would go in dev-scripts as it would be a clean and simple way of giving more control to the developer.

Thanks!


Refs: #5452, #5809, #3270.

@sindresorhus

This comment has been minimized.

Copy link

sindresorhus commented Jul 10, 2015

👍 That extra noise is pretty annoying.

@adametry

This comment has been minimized.

Copy link

adametry commented Jul 31, 2015

The ~18 lines of speculation, finger pointing, and instruction aren't very helpful when npm owner ls [name] prints my account name.

@ngryman

This comment has been minimized.

Copy link
Author

ngryman commented Oct 1, 2015

Bump 🙊

I know you guys are busy, does a PR would help? Do you prefer one solution?

Thanks!

@othiym23

This comment has been minimized.

Copy link
Contributor

othiym23 commented Feb 11, 2016

This issue is one of a constellation of feature requests around finding and enacting the least obtrusive user experience for typical package development workflows. Some of the other pieces of this are #9567 and #10491. There's consensus within the CLI team that choosing better defaults for what gets displayed when by the lifecycle process is a project worth doing; ultimately we need to define some use cases and (if possible) do some user testing to ensure that we're actually going to improve things for typical users.

It's not yet clear to me that suppressing lifecycle script output by default is the best place to start, because a number of those lifecycle scripts produce information that they intend to be passed on to developers (like, say, linters and other static analysis tools). Hence the absence of a patch-welcome tag, and the presence of needs-discussion. We're probably not going to get to this until late in 2016, but if you want to play around with different ways of dealing with this and send it to us as a PR, we'd be happy to provide feedback and review.

@ngryman

This comment has been minimized.

Copy link
Author

ngryman commented Feb 11, 2016

I think we should ask people what solution they prefer.
I've created a poll for this: http://bit.ly/1U6jkYV.

I've tweeted it here: https://twitter.com/ngryman/status/697912524415447040.
@sindresorhus could you spread the word, it would be awesome :)

@sindresorhus

This comment has been minimized.

Copy link

sindresorhus commented Feb 17, 2016

There's an easy solution to this; just make custom run scripts + npm test & npm start, not output the noise. You still retain the debugging noise info for hooks used during install, like postinstall.

@ngryman

This comment has been minimized.

Copy link
Author

ngryman commented Feb 17, 2016

@sindresorhus I totally agree, but I wanted to find a consensus where both could live together.
Perhaps only install should be verbose as it's probably the only task that users will execute, hence additional info.

@nathanmarks

This comment has been minimized.

Copy link

nathanmarks commented Feb 18, 2016

@ngryman It makes using npm as a build/dev tool really frustrating when you forget to add the -s and your terminal window when running tests ends up like:

(the test error detail is hidden above the visible output)

      ✖ should set the flex prop correctly


  total:     44
  passing:   41
  failing:   3
  duration:  3.1s



npm ERR! Darwin 15.2.0
npm ERR! argv "/usr/local/Cellar/node/5.4.1/bin/node" "/usr/local/bin/npm" "run" "test:dev"
npm ERR! node v5.4.1
npm ERR! npm  v3.3.12
npm ERR! code ELIFECYCLE
npm ERR! @poweredbysearch/react-flexlayout@0.0.7 test:dev: `npm run -s test | tap-spec`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @poweredbysearch/react-flexlayout@0.0.7 test:dev script 'npm run -s test | tap-spec'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the @poweredbysearch/react-flexlayout package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     npm run -s test | tap-spec
npm ERR! You can get their info via:
npm ERR!     npm owner ls @poweredbysearch/react-flexlayout
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/hal9000/Development/repos/nathanmarks/react-flexlayout/npm-debug.log
@jesstelford

This comment has been minimized.

Copy link

jesstelford commented Mar 9, 2016

Another possible solution:

quite mode

Reduce the volume of output, rather than removing it completely as in silent mode.

For example, @nathanmarks example;

      ✖ should set the flex prop correctly


  total:     44
  passing:   41
  failing:   3
  duration:  3.1s



npm ERR! Darwin 15.2.0
npm ERR! argv "/usr/local/Cellar/node/5.4.1/bin/node" "/usr/local/bin/npm" "run" "test:dev"
npm ERR! node v5.4.1
npm ERR! npm  v3.3.12
npm ERR! code ELIFECYCLE
npm ERR! @poweredbysearch/react-flexlayout@0.0.7 test:dev: `npm run -s test | tap-spec`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @poweredbysearch/react-flexlayout@0.0.7 test:dev script 'npm run -s test | tap-spec'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the @poweredbysearch/react-flexlayout package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     npm run -s test | tap-spec
npm ERR! You can get their info via:
npm ERR!     npm owner ls @poweredbysearch/react-flexlayout
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/hal9000/Development/repos/nathanmarks/react-flexlayout/npm-debug.log

becomes:

      ✖ should set the flex prop correctly


  total:     44
  passing:   41
  failing:   3
  duration:  3.1s



npm ERR! Exit status 1
npm ERR! Failed at the @poweredbysearch/react-flexlayout@0.0.7 test:dev script 'npm run -s test | tap-spec'.
@kevinkorngut

This comment has been minimized.

Copy link

kevinkorngut commented May 6, 2016

I just discovered the .npmrc file which will let you do this:

loglevel=silent

and if they added in support for specifying values based on NODE_ENV then I think that would be a valid route.

@trygveaa

This comment has been minimized.

Copy link

trygveaa commented May 8, 2016

@kevinkorngut: Doing that makes errors from all npm commands suppressed, e.g. errors from npm install:

trygve@george:~/npm$ echo loglevel=silent > .npmrc
trygve@george:~/npm$ npm install nonexisting
trygve@george:~/npm$ 

So that is not really a practical solution. Only errors from the run-scripts should be suppressed.

Since I'm adding a comment, I might as well state my preference. I vote for sindresorhus' suggestion; simply remove the error output and don't create a npm-debug file for the run-script command.

@styfle

This comment has been minimized.

Copy link
Contributor

styfle commented Jul 7, 2016

I think the original proposal from @ngryman is a great solution: create a devScripts for development scripts, the same way we have a devDependencies for development dependencies. These scripts are only invoked by the developer.

Therefore, devScripts have:

  • no lifecycle hooks
  • no debug log
  • no ERR output (silent by default)
  • optional --verbose flag if you need those things for some reason (chaining?)
@ljharb

This comment has been minimized.

Copy link
Contributor

ljharb commented Jul 19, 2016

@styfle wouldn't devScripts still need prepublish and postpublish?

@styfle

This comment has been minimized.

Copy link
Contributor

styfle commented Jul 20, 2016

@ljharb I can see where this is a bit of a gray area.

I think the reason why this issue exists is because someone explicitly wrote npm run build which has valuable output that NPM ERR hides. The developer knows that the build script failed, and wants to see the output, not npm errors explaining that the script failed.

The reason why NPM ERR exists (correct me if I'm wrong) is to give you valuable information about which script failed and how. The failure could be caused by a lifecycle hook that got called when you ran npm install. You would want to know that the build script failed and not the install.

The proposal for devDependencies makes more sense for apps that are not being published as npm modules to a registry and should therefore avoid prepublish and postpublish because the silent error might not give you enough information.

The main value in devDependencies for me is npm run build and npm run test--scripts where the output is important and there is no chaining.

@ljharb

This comment has been minimized.

Copy link
Contributor

ljharb commented Jul 20, 2016

I use pretest and posttest scripts all the time in developing my modules.

@ngryman

This comment has been minimized.

Copy link
Author

ngryman commented Jul 20, 2016

Just to sum up, clarify.

Currently npm provides run-scripts to "run arbitrary package scripts". Some of these scripts can be invoked using builtin commands (i.e. test, build, ...). Otherwize they are invoked with npm run <script>.

These scripts are mostly meant to be executed during or after the release of package in user space, hence npm err messages. They have been designed for packages being distributed, not for projects being developed. After all npm is a package manager, not a build tool.

But, usage has evolved and needs too. Nowadays npm-run is mostly used by developers on their machine or by services (i.e. CI) during development. Because npm is the only command line tool that we know any node development environment will have, npm-run scripts have become a de facto standard to run (automated)tasks.

When you think about it, linting, testing, building, ... is also part of a package lifecycle, but developer/maintainer side, not user side.
During development, errors are meant to exist and even being processed by automated tools, npm err does not make sense anymore in that context.

So we need to, at least conceptually, split development lifecycles from release/install lifecycles, pretty much like dependencies and devDependencies, or even public api and internal stub.

That's where dev-scripts could exist. They would allow developers to use npm as a frontend, and even a standard, to call basic development tasks.

@ngryman

This comment has been minimized.

Copy link
Author

ngryman commented Jul 20, 2016

To go further, instead of thinking about dev-scripts right of the bat, we could identify development vs production tasks. npm could provide additional commands for development tasks that would not use npm err.

Production tasks

  • install
  • build
  • start
  • stop

Development tasks

  • lint (optional)
  • build (already exists, could be transpile or compile)
  • test (already exists, should be considered as a development task)
  • watch
  • version (already exists, should be considered as a development task)
  • publish (already exists, should be considered as a development task)
@pushred

This comment has been minimized.

Copy link

pushred commented Jul 30, 2016

alias npm-run='npm run --silent $*'

scratched this itch for me =)

@pygy

This comment has been minimized.

Copy link

pygy commented Aug 15, 2016

The silent mode is not appropriate as is IMO because these headers are genuinely useful:

> project-name@x.y.z commandName /project/root
> full command goes here

Especially for meta-commands that run several sub-commands. If one of them hangs, in silent mode, you can't know which one did without re-running in noisy mode or making individual commands noisy manually (scripts: {"foobar": "echo 'foobarizing...' && foobar the-baz the-qux", ...}).

@alexose

This comment has been minimized.

Copy link

alexose commented Aug 26, 2016

I think this is really the important thing:

Personally, I've never found the 22+ lines of error helpful for debugging. Seems like it could be shortened to 2-3 lines unless --verbose is passed.

It's a whole lot of text that provides no value to developers, while also pushing all the useful debug information off the screen.

@adamreisnz

This comment has been minimized.

Copy link

adamreisnz commented Aug 26, 2016

I think this is really the important thing. It's a whole lot of text that provides no value to developers, while also pushing all the useful debug information off the screen.

Don't want to add +1 noise, but yes, this is really the core of the issue in my opinion.

@nixpulvis

This comment has been minimized.

Copy link

nixpulvis commented Sep 28, 2016

From #5452

For now, we can enforce a 0 exit code by appending || true to all of our commands. This feels clunky...

I'm curious why we would want to enforce 0 exit codes? If a test suite fails I would expect the command to give an erroneous code at the end, for example.

@ryansobol

This comment has been minimized.

Copy link

ryansobol commented Oct 2, 2016

@nixpulvis Intuitively, this is how I would expect it to work. I'm sure there are more scenarios that need consideration.

If a test suite "failed" and returned a 0 exit code, I would expect to see the test suite to have completed a run, but some of the tests cases to have failed.

If a test suited failed and returned a non-zero exit code, I would expect to see the test suite to have not completed a run due to a bug in the test suite's code or configuration.

@ljharb

This comment has been minimized.

Copy link
Contributor

ljharb commented Oct 2, 2016

@ryansobol that's not how test suites or linux programs conventionally work - a zero exit code means everything worked perfectly - you'd use the specific value of the nonzero exit code to differentiate the kind of failure.

@RayBenefield

This comment has been minimized.

Copy link

RayBenefield commented Oct 2, 2016

Just ran into this issue recently. I wanted to have an npm run lint with eslint, but turns out that it exits with a lot of error output. My preference would be to have an error message, but not have it fill the whole screen. Similar to how npm test works out with one npm error line. I could just type -s but as others mentioned it would be a problem as an alias and I actually don't mind the single error that comes with npm test. And I still want it to exit with a status of 1 for CI builds to truly fail so || true doesn't solve my problems. For now I'll stick with -s manually but ideally something along the lines of dev scripts would be wonderful.

@pygy

This comment has been minimized.

Copy link

pygy commented Oct 11, 2016

https://yarnpkg.com/ handles this nicely

error Command failed with exit code 1.
info Visit http://yarnpkg.com/en/docs/cli/run for documentation about this command.
@paralin

This comment has been minimized.

Copy link

paralin commented Nov 25, 2016

Yay, another place where Yarn is better... :)

@adamreisnz

This comment has been minimized.

Copy link

adamreisnz commented Nov 25, 2016

I don't want to derail this issue thread or turn it into an "omg Yarn" fanfest, but I am genuinely interested in how the npm team plans to respond to Yarn.

Npm has been around for quite a while now, but seems to have become somewhat bloated and there are a bunch of issues like this one, which plague many developers and have been outstanding for months, if not years. Along comes Yarn, and boom, most if not all of the major concerns and issues now seem to be addressed.

I am usually quite skeptical of new things and prefer to stick with the known and well supported, but after trying it out for myself, Yarn's speed gains and quiet output alone were enough to win me over.

So what are the plans going forward for npm? Quietly ignore it and keep going the same direction? Join forces with Yarn?

Should we wait until this issue and others like this one are fixed or all jump on the Yarn bandwagon?

@gihrig

This comment has been minimized.

Copy link

gihrig commented Dec 15, 2016

FWIW, While yarn is great and I've (mostly) switched, as far as this issue is concerned, yarn runs npm 'under the hood' when executing npm-scripts. So until that changes this issue is still relevant.

For now, -s works for me 😄

image

@Jank1310

This comment has been minimized.

Copy link

Jank1310 commented Jan 21, 2017

@gihrig With yarn v0.18.1 you can omit the -s

@sinedied sinedied referenced this issue Mar 8, 2017

Closed

Add yarn option instead of npm #49

12 of 12 tasks complete
@dmitriid

This comment has been minimized.

Copy link

dmitriid commented Mar 14, 2017

One and a half years later...

Also, two years since this article: https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/ (which for many was a starting point to use npm run)

Also, npm docs:

scripts: If you have a special compilation or installation script, then you should put it in the scripts object.

Oh yes, we do.

@ngryman

This comment has been minimized.

Copy link
Author

ngryman commented Mar 14, 2017

@dmitriid Now that yarn is gaining momentum and addressing those kind of issues, hopefully npm will follow 🎉

@tobia

This comment has been minimized.

Copy link

tobia commented Apr 19, 2017

I would like to point out that using an alias in .bashrc is the correct solution, unless/until more options are available. In fact I have a very simple alias to address this issue:

alias npm='npm -s'

An alias is a user's personal configuration item. Its purpose is to set preferred flags only when using that command interactively in the terminal. It does not affect scripts in any way. If it does, there is something very wrong with the script or with your setup. Moreover, you can easily ignore the alias whenever you need to, by prefixing the command with a backslash:

$ \npm run ...

If you use -s (or any other flag) more often than not, then setting an alias is the correct way to go about it. Many distributions come with several alias already set, such as alias ls='ls --color=auto' or alias ls='ls -F'. No script has ever failed because you have an alias that changes the output of ls, because scripts ignore aliases. There is nothing wrong or dangerous about them.

@ljharb

This comment has been minimized.

Copy link
Contributor

ljharb commented Apr 19, 2017

Scripts may ignore aliases, but tools that run in your own shell context, including aliases you may have copied from others' dot files, do not. Aliasing over other commands definitely can cause problems - it's irrelevant which tool's fault that is.

@tobia

This comment has been minimized.

Copy link

tobia commented Apr 20, 2017

Which tool is at fault is anything but irrelevant. You cannot (and IMHO should not) play nice with other projects' bugs. In this case, if a tool parses the output of npm, but for some reason is not immune to the user's shell aliases, then that tool is written badly. Go ask the Bash developers if you don't believe me. Otherwise, what would be the purpose of aliases in the first place? Why would distributions ship with pre-made aliases for common commands such as ls and grep?

@paralin

This comment has been minimized.

Copy link

paralin commented Apr 20, 2017

Bash aliases shouldn't apply to calls Npm makes internally. Also, I'm pretty sure nobody is screen scraping the npm output...

@dander401

This comment has been minimized.

Copy link

dander401 commented Apr 20, 2017

i think the aliasing is off topic of the bug report. The issue presented is that when a script fails, npm prints a whole paragraph after the actual error that says that the other script failed and that it wasn't npm. The problem with the paragraph is that it pushes the message detailing the error out of sight.

@iarna iarna closed this in 65b9943 Apr 22, 2017

@adamreisnz

This comment has been minimized.

Copy link

adamreisnz commented Apr 22, 2017

🎉

@k-funk

This comment has been minimized.

Copy link

k-funk commented Apr 22, 2017

🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉

@ngryman

This comment has been minimized.

Copy link
Author

ngryman commented Apr 22, 2017

at-last

@stevenvachon

This comment has been minimized.

Copy link

stevenvachon commented Jul 15, 2017

While shorter, I'd still like to not see the lifecycle stuff at all.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.