如何使用npm脚本获取shell脚本?

时间:2019-04-16 06:34:21

标签: node.js shell npm yarnpkg nvm

我的package.json中有一个脚本:

{
  "scripts": {
    "start": "source run-nvm.sh && ..."
  }
}

但是运行source run-nvm.sh && ...yarn start(或npm run start)不同。

为什么?它创建一个子外壳。因此,我无法更改原始外壳的环境,无法为其export常量或操纵nvm的状态(我无法更改父外壳的节点版本)

所以真正的问题

我可以通过不创建子外壳来执行yarn / nvm脚本吗? (并使用当前的shell)

OR

如何使用npm脚本获取shell脚本?

最终,您可以尝试通过询问以下内容来更改论述:“您为什么不source run-nvm.sh && yarn start”,但我不想只是添加一些自定义脚本和复杂性,我希望它能够自动执行在yarn start / npm start上(以自动更改节点版本)

还有真正的问题

它当前可以工作(脚本会更改节点的版本并运行应用程序),但是由于它是子外壳程序,因此不会保存nvm的状态。因此,在每个yarn start上,它最初都使用默认版本,然后更改版本,然后启动应用程序,因此yarn start命令为版本更改增加了大约3-4秒的时间。虽然它不应该每次都设置版本,但是应该第一次只设置一次。

3 个答案:

答案 0 :(得分:3)

总猜想,但尝试

{
 "scripts": {
    "start": "bash -c 'source run-nvm.sh && ...'"
  }
}

答案 1 :(得分:1)

我今天遇到了这个问题,我找到了一个对我有用的简单解决方案。

  1. 使用 vars 创建一个 env 文件

    # cat > .env << EOF
    PORT=8080
    DB_HOST=my-db.host
    DB_PORT=3306
    DB_USER=mysql
    DB_PASS=123456
    EOF
    
  2. package.json 文件上创建一个新条目

    {
      [...]
      "start": "export $(cat .env | egrep -v '#|^$' | xargs) && node production-server/server.js",
      [...]
    }
    
  3. 照常启动应用

    # npm run start
    
    > myapp@1.0.2 start /usr/local/myapp
    > export $(cat .env | egrep -v '#|^$' | xargs) && 
    node production-server/server.js
    
    > Ready on http://localhost:8080
    

仅此而已。

如果您想知道 export $(cat .env | egrep -v '#|^$' | xargs) 的作用,请继续阅读。

export $(cat .env | egrep -v '#|^$' | xargs)
   |      |           |                 |
   |      |           |                 transform the output in "PORT=8080 DB_HOST=my-db.host DB_PORT=3306 DB_USER=mysql DB_PASS=123456"
   |      |           |
   |      |           filter lines starting with comment or blank line
   |      |
   |      cat the .env file
   |
   save the env on subshell before start the node

答案 2 :(得分:0)

发现您对使用vscode插件的评论 如果您想要的只是在其中一个项目上更改所有终端的nvm版本时,请查看我的过大答案。

我可能会将所有逻辑放在bash脚本中,只是共享链接。 ?

通常,node版本存储在package.json中,并导致不正确的node版本或npm导致失败。

// package.json

 "engines": {
    "node": ">=10.0.0"
  },
  "scripts": {

通常,版本逻辑在$ HOME / .bashrc文件中的shell所提供的bashrc中。 创建新窗口时,它们会重新触发nvm的使用。

两种可能性:
都使用脚本: script-to-replace-nvm-version.sh
# Which replaces in bashrc the "nvm use " line with "nvm use $correctProjectVersion"

  1. 使用json包中的开始脚本运行script-to-replace-nvm-version

  2. 使用PROMPT_COMMAND运行脚本以替换nvm版本:

在此处使用支票以确保我们处于npm项目中。

请注意PROMPT_COMMAND,因为它会在ps1渲染之前每次运行。

 PROMPT_COMMAND="[ -f ./package.json ] && $HOME/.scriptsourcedbybashrc.sh"

脚本摘要:Nvm通常来自$ HOME / .bashrc中的特定版本。因此,我们可以使用npm包重写包含nvm use ...的行并更新版本。我们甚至可以提示您是否要更新?

从package.json检查节点版本

projectVersion=$(cat ./package.json | grep 'node":' | tr -dc '0-9.')
echo $projectVersion

从$ HOME / .bashrc检查节点版本

nodeVersion=$(cat $HOME/.bashrc | grep 'nvm use' | tr -dc '0-9.')
echo $nodeVersion

检查node和package.json版本是否不同

# bash script, to be sourced by npm run start;

# WIP, needs a few more error checks
# such as, nvm used in more than one place in your bashrc.
if
  versions_differ_tell_and_prompt
fi
versions_differ_tell_and_prompt() {
  echo "nvm versions differ: ";
  found in project: $projectVersion;
  found in '$HOME/.bashrc': $nodeVersion;
  echo ;
  echo "ignore with any keypress or [uU] to update";
  old_stty_cfg=$(stty -g);
  stty raw -echo ; answer=$(head -c 1) ; stty $old_stty_cfg;
}
if echo "$answer" | grep -iq "^u" ;then
    update_file 'nvm use' "nvm use $projectVersion" && source $HOME.bashrc;
else
    echo "No changes made";
fi
update_file() {
  searchLine=$1
  replacementLine=$2
  lineNumber=$(cat $HOME/.bashrc | grep -n $searchLine | cut -f1 -d:)
  cp "$HOME/.bashrc" "$HOME/.bashrc.backup"
  sed -i "$lineNumbers/.*/$replacementLine/" "$HOME/.bashrc"
  source "$HOME/.bashrc"
}
unset searchLine
unset replacementLine
unset answer
unset old_stty_cfg
unset nodeVersion
unset projectVersion

其他一些有用的链接: https://github.com/md-command-line/ERRORSCREAM/issues/2

此处采用了大多数逻辑:https://github.com/MichaelDimmitt/git_check_computer/blob/master/git_check_computer.sh

更正纱线启动命令以根据找到的锁定文件运行正确的纱线或npm。 https://github.com/MichaelDimmitt/know-your-package-manager