.1-淺析webpack源碼之webpack.cmd


  此系列隨時可能斷更,畢竟我是解釋型源碼分析……

  tips:本系列源碼版本為3.10.0

 

  嘗試看過Spring的源碼,有點燒腦,所以還是重回JS吧!

  在配置完環境變量后,可以通過webpack指令進行打包,需要知道的是,如果當前路徑存在webpack.config.js文件,會被默認指定為配置JS文件

  官網原文如下:If a webpack.config.js is present, the webpack command picks it up by default

  也就是說直接執行webpack指令會默認執行webpack webpack.config.js

  也可以通過--config自定義,假設配置文件為config.js,這時就需要執行webpack --config config.js

 

  第一章來點輕松的,比如說webpack.cmd,首先來一張總的流程圖:

  

  批處理文件源碼如下:

REM @代表該行指令不會被顯示在界面中
REM IF EXIST/ELSE類似於普通編程語言的if/else
REM %開頭的相當於一個占位符
@IF EXIST "%~dp0\node.exe" (
    REM 執行node.exe 並繼續執行webpack ...(參數)
  "%~dp0\node.exe"  "%~dp0\..\webpack\bin\webpack.js" %*
) ELSE (
REM 延遲執行
  @SETLOCAL
REM 變量賦值 返回所有系統認為可執行文件類型 排除.JS   
  @SET PATHEXT=%PATHEXT:;.JS;=;%
REM 嘗試直接執行node webpack ...
  node  "%~dp0\..\webpack\bin\webpack.js" %*
)

  語言是bat命令,花了1個小時入了個門,大概能懂指令的內容。

  這里比較復雜的一個是占位符%,%0在這里相當於當前絕對路徑,%~dp0是對內容的格式化,測試代碼如下:

REM E:\1-homework\a.cmd
@echo off
echo %0
echo "%~d0"
echo "%~p0"
echo "%~dp0"
pause

  輸出為:

  所以第一段IF EXIST指令判斷的是在當前路徑是否存在node.exe文件,如果有就執行並調用后面的webpack指令。

 

  指令行最后的%*代表所有接收的參數,參數來自於指令后面自定義的字符了,測試代碼如下:

@echo off
echo the params is: %*
pause

  然后在當前路徑打開cmd在執行文件名后面加上1 2 3,輸出如下:

  也就是在webpack input1.js input2.js指令中,input1.js與input2.js會當成參數替換掉%*。

  

  下面的兩個命令可以自己去查,這里暫時看不到作用。

  如果當前路徑不存在node.exe,會嘗試直接調用node webpack進行打包操作。

 

  需要注意的是,這里的node並不是一個簡單的cmd腳本,而是一個可執行文件,可以在安裝的nodejs文件夾中找到npm.cmd:

:: Created by npm, please don't edit manually.
@ECHO OFF

SETLOCAL

SET "NODE_EXE=%~dp0\node.exe"
IF NOT EXIST "%NODE_EXE%" (
  SET "NODE_EXE=node"
)

SET "NPM_CLI_JS=%~dp0\node_modules\npm\bin\npm-cli.js"
FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO (
  SET "NPM_PREFIX_NPM_CLI_JS=%%F\node_modules\npm\bin\npm-cli.js"
)
IF EXIST "%NPM_PREFIX_NPM_CLI_JS%" (
  SET "NPM_CLI_JS=%NPM_PREFIX_NPM_CLI_JS%"
)

"%NODE_EXE%" "%NPM_CLI_JS%" %*

  這里需要關注的只有第一個SET語句,將node.exe賦值給node_exe,執行node_exe命令也就相當於執行node.exe文件。

 

  回到webpack指令中,"%~dp0\..\webpack\bin\webpack.js"的webpack並不是主函數,只是預處理,引入了一個叫yargs的命令行框架,並在里面再次引入真正的webpack,並將配置文件的options傳入進行打包,源碼簡化后如下:

var path = require("path");

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

// 引入yargs框架
var yargs = require("yargs").usage("...");

// ...

yargs.options({
    // ...
});

yargs.parse(process.argv.slice(2), (err, argv, output) => {
    // ...
    function processOptions(options) {
        // ...
        // 引入真正的webpack
        var webpack = require("../lib/webpack.js");

        Error.stackTraceLimit = 30;
        var lastHash = null;
        var compiler;
        try {
            // 將配置文件的options傳入進行編譯
            compiler = webpack(options);
        } catch (err) {
            // ...

            throw err;
        }

        // 編譯后處理
        // ...
    }
    processOptions(options);
});

  來自於lib文件夾的webpack才是真正的主入口函數。

 

  這一節內容暫時就到這里,簡單過了一下cmd~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM