webpack源碼閱讀——npm腳本運行webpack與命令行輸入webpack的區別

原文地址: webpack源碼閱讀——npm腳本執行webpack與命令行輸入webpack執行的區別
若有錯誤,歡迎指正!

webpack是目前被你們廣爲使用的模塊打包器。從命令行輸入webpack或者在package.json的npm scripts中配置webpack腳本均可以使用webpack。雖然效果是同樣的,可是二者有區別嗎?最近在閱讀源碼的過程當中發現了這個事情,原來二者是有區別的。html

webpack安裝

webpack的安裝分爲全局安裝和本地安裝。node

全局安裝webpack

npm install webpack -g

本地安裝web

npm install webpack --save-dev

全局安裝與本地安裝的區別npm

  1. 安裝時參數不一樣,全局安裝須要添加 -g 參數
  2. 安裝後生成的目錄不一樣json

    • 全局安裝會在系統npm的根路徑下生成node_modules目錄,並在根路徑下生成對應的.cmd 腳本文件用於啓動webpack
    • 本地安裝會在運行npm install 命令的目錄下生成node_modules目錄,並在node_modules 目錄下生成.bin文件夾,裏面存放了對應的.cmd腳本文件用於啓動webpack
  3. 使用方式不一樣windows

    • 全局安裝後能夠直接在命令行輸入webpack命令,使用webpack。不然在命令行輸入webpack的狀況下,會提示 command not found

命令行直接輸入webpack的方式

這種方式使用webpack,必須全局安裝webpack,在全局安裝了webpack的狀況下,命令行輸入webpack並敲下回車時,系統會去npm全局根路徑下尋找webpack.cmd命令(windows系統下),如何查看當前npm的全局安裝目錄? 輸入如下命令:ui

npm root -g

以windows爲例,筆者的路徑是:命令行

C:\Users\(登陸用戶名)\AppData\Roaming\npm\node_modules

其中node_modules下存放了全局安裝的一些npm包,npm文件夾下還存在了對應的webpack.cmd文件用於啓動webpackcode

webpack.cmd

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

這段腳本的意思就是使用當前目錄下的node去運行node_modules/webpack/bin/webpack.js,若是當前目錄不存在node.exe則使用全局的node去運行。

npm scripts配置npm腳本運行webpack的方式

以下所示

package.json

...
scripts: {
    "build": "webpack"
}
...

在package.json中定義了啓動webpack的npm腳本,使用npm run build命令便可使用webpack進行構建。

關於執行npm run ***的原理能夠參考阮老的教程npm scripts使用指南中的原理部分。

執行npm run build時, 會執行webpack命令,此時系統去當前目錄而非全局npm目錄尋找webpack.cmd文件並執行。其中webpack.cmd文件中定義了須要執行的webpack的目錄,也就是在當前目錄下尋找webpack/bin/webpack.js。以下:

webpack.cmd

@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" %*
)

全局版本和本地版本都安裝的狀況下,使用的到底是全局的webpack仍是本地的webpack

如題,咱們仍是從兩種方式使用webpack的狀況下進行分析。

前提:全局以及本地都安裝了webpack

命令行直接輸入webpack的方式

這種方式運行的是全局的node_modules/webpack/bin/webpack.js,其中在webpack.js的開始有如下代碼

// Local version replace global one
try {
    var localWebpack = require.resolve(path.join(process.cwd(), "node_modules", "webpack", "bin", "webpack.js"));
    if(__filename !== localWebpack) {
        return require(localWebpack);
    }
} catch(e) {}

這段代碼判斷了當前的文件路徑與node進程運行時所在的路徑下的node_modules/webpack/bin/webpack.js 是否相等,若是相等表明目前使用的就是本地的版本,若是不相等表明了當前使用的是全局版本,則直接請求本地版本。

結論:在全局安裝以及本地都安裝的狀況下命令行中輸入webpack,在webpack的源碼邏輯中控制了直接使用本地安裝的webpack。

npm 腳本中配置webpack命令

這種方式直接去本地node_modules/.bin去找webpack.cmd命令,而後運行本地node_modules下的webpack。

結論:在全局安裝以及本地都安裝的狀況下,使用npm腳本的方式運行webpack,則直接運行的是本地版本。

總結:在全局以及本地都安裝了webpack的狀況下,運行時本地安裝的webpack。

相關文章
相關標籤/搜索