Vscode: Configure npm script shell for running npm tasks in VS Code.

Created on 14 Nov 2018  路  25Comments  路  Source: microsoft/vscode


  • VSCode Version: 1.29.0
  • OS Version: Windows Server 2008R

Steps to Reproduce:

  1. set up default shell for terminal to bash with "Terminal select default shell" command
  2. run any commmand from npm scripts - it opens in default windows cmd but not in bash


Does this issue occur when all extensions are disabled?: Yes

*out-of-scope feature-request tasks

Most helpful comment

Our team work with the project crossplatform.
Linux & OSX use bash by default, but windows - does not.
We dont want to every our member to know and set up npm by hands to open bash - we use VSCode so it must work crossplatform with bash terminal and bash commands

All 25 comments

(Experimental duplicate detection)
Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:

run any commmand from npm scripts

As a task or with some extension?

as a task

I can't reproduce this. I opened a project with npm scripts, ran the "Terminal select default shell" command and set the shell to git bash. The task correctly ran the in git bash.
Can you check if the terminal default shell setting change saved? If your settings file is dirty that command pops up an error notification.

User settings:

{
    "workbench.colorTheme": "Plastic",
    "workbench.iconTheme": "vs-nomo-dark",
    "javascript.updateImportsOnFileMove.enabled": "always",
    "terminal.integrated.rendererType": "dom",
    "workbench.activityBar.visible": true,
    "editor.minimap.enabled": false,
    "terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe",
    "git.confirmSync": false,
    "typescript.updateImportsOnFileMove.enabled": "always",
    "npm.enableScriptExplorer": true,
    "files.autoSave": "onFocusChange",
    "files.autoSaveDelay": 1000,
    "window.zoomLevel": 0,
    "git.enableSmartCommit": true,
}

Workspace settings

{
    // prettier
    "editor.formatOnSave": true,
    "json.format.enable": true,
    "[json]": {
        "editor.formatOnSave": true
    },
    "[css]": {
        "editor.formatOnSave": true
    },

    // stylelint
    "css.validate": false,
    "less.validate": false,
    "scss.validate": false,
    "prettier.stylelintIntegration": false,

    // npm sripts
    "npm.enableScriptExplorer": true,

    // git
    "git.autofetch": true,

    "files.autoSave": "onFocusChange",
    "workbench.iconTheme": "vs-nomo-dark",
    "editor.minimap.enabled": false,
    "workbench.colorTheme": "Plastic",
    "workbench.statusBar.feedback.visible": false,
    "workbench.sideBar.location": "left",
    "git.confirmSync": false,
    "eslint.enable": false
}

Hmm. Any options set in your tasks.json file? You can optionally choose the shell that all tasks run in there.

I dont know anything about task.json
What is it and where?
Where to get info about it?

It will be in the .vscode folder at the root of your project. Info about tasks: https://code.visualstudio.com/Docs/editor/tasks

Sorry, there is no tsaks.json

Removed my comment - misunderstood the issue

If you open a terminal in VS Code does it correctly use bash? Can you try the insiders build and see if it reproduces there? https://code.visualstudio.com/insiders/

VS correctly uses bash
I've tryed it in insiders build - the result is the same - error:

default

I run command "try": "source app_env" with packackage.json npm script in npm scripts panel

Before your un your npm task, can you check and see if you have a terminal for tasks already open? If you already had a terminal that was used for tasks open and it used cmd, then you change the terminal.integrated.shell.windows value to bash.exe, then run the npm task then it will re-use the existing cmd.exe terminal for tasks. You can check if you have a terminal for tasks already open by looking in the drop down in the terminal pane for a terminal with the work Task in the name.

before runing npm scripts command - terminal with bash is opened
terminal.integrated.shell.windows is set to C:\Program Files\Git\bin\bash.exe but terminal for nmp scripts tasks opens with cmd

Here is default terminal
default

here is task terminal runing printenv command
default

and here are vscode settings:
default

I'm able to see the same output from the printenv command, both when I run in a bash terminal in VS Code and when I run it in a task. I've confirmed that even thou the npm_config_shell value says cmd.exe it is definitely running in bash. If you look at task manager, you should see that only a bash.exe process spins up, and no cmd.exe process. For whatever reason, npm_config_shell is misleading here.

I'm sorry, but it's not true
In bash terminal calling bash command source .env doesn't produce the error
default

but when this command is calling in terminal with cmd - it raises the error

I still have the error when run a command from npm script panel

VS Code will execute your script by running npm run <script name> in the shell that you have set using terminal.integrated.shell.windows. It looks like npm has it's own way of specifying the shell that it uses, and doesn't simply inherit the shell that it is run in (https://stackoverflow.com/questions/23243353/how-to-set-shell-for-npm-run-scripts-in-windows). So what's happening is:

  1. VS Code starts terminal with bash
  2. executes npm run <script name> in that terminal
  3. npm has it's own configuration and runs the script in whatever shell it is configured to use. In this case, cmd.

Would simply configuring npm to use bash solve your use case? Or is your desired behavior a VS Code setting that allows you to override the npm configured script shell?

Sorry, I dont know how to set up npm to use bash.
It would be useful if vscode configured npm to use bash terminal

@budarin, I linked you a stack overflow article with how to configure npm to use bash. Do you always want your npm scripts to use bash, or do you only want them to use bash when you're running them from VS Code? I'm trying to understand the use case so I know if this is a feature people might want.

Our team work with the project crossplatform.
Linux & OSX use bash by default, but windows - does not.
We dont want to every our member to know and set up npm by hands to open bash - we use VSCode so it must work crossplatform with bash terminal and bash commands

It definitely seems like there is more involved than just changing the VS Code Integrated terminal setting and potentially the NPM shell setting. I've spent endless hours trying to get NPM Scripts to run from the VS Code panel via WSL for our developers. I'm not sure if that's "different enough" from GIT Bash to warrant its own issue, but here is what I see:

The machines are running Windows 10 with WSL (Ubuntu), latest VS Code, and GIT for Windows. Node is install both in Windows (i.e. Program Files) and in WSL (via nvm) -- as developers need access to both.

If I go and configure VS Code using "Terminal select default shell", and choose GIT Bash, the NPM scripts from the VS Code panel will "run" but it uses Node/npm from Windows and doesn't have access to the WSL filesystem or resources, so it's not really of use for us.

If I go and configure VS Code using "Terminal select default shell", and choose WSL Bash, the NPM scripts from the VS Code panel will fail. Again they appear to be using Node/npm from Windows rather than the installation under WSL.

For example, I made an npm script that simply does ls -l named "fred". If I bring up the integrated terminal (which is now running Bash under WSL fine), and run npm run fred, it runs as expected using the npm command installed under WSL, and gives a directory listing.

If I click to run "fred" from the NPM Scripts panel in VS Code I get errors in the terminal that comes up including:

/mnt/c/Program Files/nodejs/npm: 6: /mnt/c/Program Files/nodejs/npm: Syntax error: word unexpected (expecting "in")
The terminal process terminated with exit code: 2

So it seems to me like it's not simply running "npm" in the configured shell as expected. If it did simply bring up the WSL/bash shell I have configured and run "npm run freddy" I'd see the same results as doing it myself w/ the integrated terminal, no? Or perhaps those tasks are run in a terminal that doesn't get the full PATH used in WSL for some reason.

So it seems to me (at least in this case), that no additional configuration would be necessary if it truly would bring up WSL/bash in the terminal (in the same manner it comes up when manually starting a shell in VS Code) and then issue the npm command and let the shell sort out the location of npm, etc.

I'd love to get this figured out, as our developers need to develop using Node/npm running under WSL. It's close at this point, but we have a lot of scripts which would be much easier to click on vs manually bringing up a shell and issuing npm commands after looking up the right names.

Thanks for listening if you made it this far :)

Well, after looking at this further, here is what I've learned -- at least with WSL Bash.

  • WSL adds translated "Windows" paths to PATH by default, so if you have Node/NPM installed on Windows also, you'll get it added. The only way to stop that behavior is via registry edit (or /etc/wsl.conf if you have a new enough version of WSL)
  • You can't remove those PATH entries via .profile, as VS Code terminals that are brought up for NPM run scripts don't seem to source those. (more on that coming)
  • This gets complicated when Node/NPM on the WSL side is installed via nvm where it's expected the needed PATH entries are added dynamically via .bashrc which VS Code terminals for NPM scripts do not source either.

So in the end, to get a working config where WSL Node/NPM scripts are all used via WSL Bash currently I had to:

  • Disable automatic WSL Windows paths being added
  • Set VS Code to use WSL Bash for integrated terminal
  • Create symbolic links to node and npm in /usr/local/bin which is part of the PATH VS Code does have when running NPM scripts

I guess the only thing that is a mystery is how that PATH that VS Code has when a NPM script is run is formed. I don't see .profile or .bashrc having any effect. I also tried adding to /etc/environment but that didn't seem to change it either. Obviously when it starts up the shell for NPM scripts it's not a full user login shell where those would be sourced. I think if it was it may solve a lot of issues for people.

This issue is being closed to keep the number of issues in our inbox on a manageable level, we are closing issues that are not going to be addressed in the foreseeable future: We look at the number of votes the issue has received and the number of duplicate issues filed. More details here. If you disagree and feel that this issue is crucial: We are happy to listen and to reconsider.

If you wonder what we are up to, please see our roadmap and issue reporting guidelines.

Thanks for your understanding and happy coding!

I faced this problem when I tried to launch npm/Yarn scripts in WSL from a Windows app (.NET).
Nested bash calls were the only thing that worked. I have no explanation. It's just an empirical thing.

C# Process.Start("bash", "-i -c \"bash -i -c '" + command.Replace("'", @"'\''") + "'\"")

Just like @Codelica, I have Node installed both in Windows and WSL and use nvm in WSL.

If I set up the workspace to use bash as a shell, like this:

{
    "terminal.integrated.shell.windows": "bash.exe"
}

And then try to use VSCode's NPM task runner, it's still trying to find the NPM I have Installed in Windows:

> Executing task: npm run build <

/bin/bash: /mnt/c/Copies/Node/npm: /bin/sh^M: bad interpreter: No such file or directory
The terminal process terminated with exit code: 126

And fails terribly of course, because trying to use NPM from windows inside WSL is not a good idea.

I think the only option is to use VSCode WSL remote extension.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

omidgolparvar picture omidgolparvar  路  3Comments

shanalikhan picture shanalikhan  路  3Comments

borekb picture borekb  路  3Comments

sijad picture sijad  路  3Comments

VitorLuizC picture VitorLuizC  路  3Comments