經過npm包來製做命令行工具的原理

前言

用過構建工具的親們知道,一般經過全局安裝一個 xxx-cli 的 npm 包,就能在命令行用命令進行構建。那麼這個 npm 包如何變成一個可執行的命令呢?javascript

npm cli 開發步驟

  1. 使用 npm init 初始化一個項目目錄 my-cli。
  2. 在 package.json 中添加或者編輯 bin 字段:css

    {
      "name": "my-cli",
      ...,
      "bin": {
        "command-name": "jsfile" // path of jsfile relative to package.json
      },
      ...
    }

    commandName 就是命令的名字,jsfile 就是當用戶鍵入命令時的處理程序。html

  3. 代碼開發。必須在 jsfile 文件的第一行寫這行命令 #!/usr/bin/env node,譬如:java

    #!/usr/bin/env node
    const program = require('commander');
    const packageJson = require('../package');
    
    let defaultJsProcessors = [ 'react' ];
    let defaultStyleProcessors = [ 'sasslike' ];
    let defaultWebpackVersion = '4';
    
    function parseListArgv( val ) {
      if ( val ) {
        return val.split( ',' );
      } else {
        return [];
      }
    }
    
    program
      .version( packageJson.version, '-v, --version' )
      .option( '-u, --use-version <version-number>', 'Webpack version' )
      .option( '-j, --js-processors <processors>', 'Specify javascript processors', parseListArgv )
      .option( '-s, --style-processors <processors>', 'Specify style(css,image,fonts) processors', parseListArgv )
      .option( '--no-install', 'Do not install devDependncies package' )
      .parse( process.argv );
    
    
    let jsProcessors = program.jsProcessors || defaultJsProcessors;
    let styleProcessors = program.styleProcessors || defaultStyleProcessors;
    let webpackVersion = program.useVersion || defaultWebpackVersion;
    
    if ( webpackVersion=='4' ) {
      // code
    } else {
      // code
    }
  4. 註冊一個 npm 帳號。
  5. 發佈到 npm 倉庫,在項目根目錄執行:node

    $ npm login
    
    $ npm publish
  6. 當發佈成功以後,全局安裝剛剛發佈的包 npm install -g my-cli,安裝完之後就能夠在命令行使用步驟2中的命令了 $ command-name

npm cli 運行原理

Unix-like 平臺

  1. 當全局安裝 npm 包的時候,npm 會把 package.json 中 bin 配置的 command-name 添加到系統 $PATH 中去。拿 macOS 舉例,npm 會在 /usr/local/bin 下建立一個以 command-name 爲名字的軟連接,指向全局安裝下來的 my-cli 包下面的 js:jsfile。(/usr/local/bin 是在 $PATH 中的)
  2. 在命令行鍵入 command-name 至關於執行了文本文件 jsfile
  3. 在執行的時候碰到第一行 #!/usr/bin/env node,這是一個 shebang 行。這行告訴系統使用 node 去執行當前文件。(shebang 只有在Unix-like平臺纔有)
  4. 執行 js 文件。這裏有一個問題:#! 並非一個符合 js 語法的語句,理論上直接執行是會有 syntax error 的。可是 node 對 shebang 行作了例外處理,因此用 node 執行帶 shebang 行的 js 文件是沒有問題的。

Windows 平臺

  1. 全局安裝會把包安裝到 C:\Users\username\AppData\Roaming\npm\node_modules下面,而後在 C:\Users\username\AppData\Roaming\npm 生成一個以 command-name 爲名字的 cmd 文件:command-name.cmd。(C:\Users\username\AppData\Roaming\npm 在安裝 npm 時被加入到 %PATH% 中)
  2. 在 Windows 平臺運行 cmd 文件是不須要後綴名的,因此當在命令行鍵入 command-name 至關於執行 C:\Users\username\AppData\Roaming\npm\command-name.cmd。
  3. 爲何有這個 cmd 文件,由於 windows 平臺沒有 shebang,那麼 command-name.cmd 就模擬了 #!/usr/bin/env node 的功能,調用 C:\Users\username\AppData\Roaming\npm\node_modules\my-cli\ jsfile

用命令行執行本地安裝的 npm cli

之前使用 npm 寫的命令行工具必須全局安裝,如今有一個工具 npx:react

近日發佈的 npm 5.2.0 版本中內置了伴生命令:npx,相似於 npm 簡化了項目開發中的依賴安裝與管理,該工具致力於提高開發者使用包提供的命令行的體驗。npx 容許咱們使用本地安裝的命令行工具而不須要再定義 npm run-script,而且容許咱們僅執行一次腳本而不須要再將其實際安裝到本地;同時 npx 還容許咱們以不一樣的 node 版原本運行指定命令、容許咱們交互式地開發 node 命令行工具以及便捷地安裝來自於 gist 的腳本。

npx 的使用

譬如我要用上文提到的命令行工具 command-name --option,那麼我無需再全局安裝了,只須要運行 $ npx command-name --option。npx 的執行過程請參考:https://www.npmjs.com/package...webpack

Executes <command> either from a local node_modules/.bin, or from a central cache, installing any packages needed in order for <command> to run.

By default, npx will check whether <command> exists in $PATH, or in the local project binaries, and execute that. If <command> is not found, it will be installed prior to execution.web

參考

  1. https://www.cnblogs.com/buzhi...
  2. https://stackoverflow.com/que...
  3. https://stackoverflow.com/que...
  4. https://www.npmjs.com/package...
相關文章
相關標籤/搜索