不懂就问,node_modules文件夹下的.bin文件夹下面都是什么文件?

如题:在项目中的node_modules文件夹下有个.bin目录。目前知道的是是一些指令。
拿 eslint 为例。有三个文件:分别是

  • eslint

    #!/bin/sh
    basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
    
    case `uname` in
      *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
    esac
    
    if [ -x "$basedir/node" ]; then
    "$basedir/node"  "$basedir/../eslint/bin/eslint.js" "$@"
    ret=$?
    else 
    node  "$basedir/../eslint/bin/eslint.js" "$@"
    ret=$?
    fi
    exit $ret
  • eslint.cmd

    @ECHO off
    SETLOCAL
    CALL :find_dp0
    
    IF EXIST "%dp0%\node.exe" (
    SET "_prog=%dp0%\node.exe"
    ) ELSE (
    SET "_prog=node"
    SET PATHEXT=%PATHEXT:;.JS;=;%
    )
    
    "%_prog%"  "%dp0%\..\eslint\bin\eslint.js" %*
    ENDLOCAL
    EXIT /b %errorlevel%
    :find_dp0
    SET dp0=%~dp0
    EXIT /b
  • eslint.ps1

    #!/usr/bin/env pwsh
    $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
    
    $exe=""
    if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
    # Fix case when both the Windows and Linux builds of Node
    # are installed in the same directory
    $exe=".exe"
    }
    $ret=0
    if (Test-Path "$basedir/node$exe") {
    & "$basedir/node$exe"  "$basedir/../eslint/bin/eslint.js" $args
    $ret=$LASTEXITCODE
    } else {
    & "node$exe"  "$basedir/../eslint/bin/eslint.js" $args
    $ret=$LASTEXITCODE
    }
    exit $ret

    所以,为什么会有这三个文件?这三个文件都是啥语言?具体意义是?package.json的scripts执行时是怎么样的机制?
    有介绍文章推荐看看吗?
    谢谢。

阅读 4.5k
2 个回答

二进制可执行文件。

你贴的三个分别是 Shell 脚本、CMD 脚本、PowerShell 脚本。

从代码上不难看出,脚本最后运行了 node $DIR$/node_modules/eslint/bin/eslint.js($DIR$ 是你项目的实际路径)。核心就是拼接实际的路径,以及判断是不是 Windows 环境、来决定运行 node 还是 node.exe

https://www.zhihu.com/questio...

node_modues/.bin文件夹下,对于一个npm包,有两个可执行文件,没有后缀名的是是对应unix系的shell脚本,.cmd文件对应的是windows bat脚本,内容都是用node执行一个js文件

@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0..\webpack\bin\webpack.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0..\webpack\bin\webpack.js" %*
)

这里是windows的cmd中的语法 ~dp0指执行脚本的当前目录 这句话的意思是如果当前目录下有node.exe,就用node.exe执行... ...webpack.js文件 %*是指执行bat时命令中输入的后续参数 否则 @SETLOCAL设置本次批处理命令中的环境变量 PATHEXT是windows下的文件扩展名环境变量 后面的语法是从PATHEXT中删除.JS 然后执行 node ... ... webpack.js 命令, 去除掉扩展名的作用是为了防止执行到node.js文件 比如当前文件夹下有一个node.js文件, 如果直接执行node命令可能会默认用vscode打开这个.js文件

https://docs.microsoft.com/en...

https://stackoverflow.com/que...

另一个不带.cmd结尾的是为unix系统准备的:

!/bin/sh

$() https://www.cnblogs.com/cheng... 做命令替换的

sed https://www.runoob.com/linux/... https://stackoverflow.com/que...

$0 https://unix.stackexchange.co...

获取当前执行bash的dirname( strip last component from file name ),命名为basedir这个变量

basedir=$(dirname "$(echo "$0" | sed -e 's,\,/,g')")

如果uname 以 开头 中间有CYGWIN后面有结束 basedir是 cygpath -w "$basedir"

cygpath -w 是以windows风格路径分割符处理$basedir

case...in...esac语法 http://c.biancheng.net/view/2...

case uname in

*CYGWIN*) basedir=`cygpath -w "$basedir"`;;

esac

if[]...then...else...fi语法 https://blog.csdn.net/puqutog...

$@ 代表所有参数 https://superuser.com/questio...

$?代表最近执行的返回值 https://unix.stackexchange.co...

-x 如果后面文件存在是true http://man7.org/linux/man-pag... (-x file)

if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../webpack/bin/webpack.js" "$@"
ret=$?
else
node "$basedir/../webpack/bin/webpack.js" "$@"
ret=$?
fi

exit $ret

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题