如何在webpack中獲取git版本和當前指令碼的工作目錄

weixin_33912445發表於2017-10-28

前言

前一陣子因為vue部署不上去錯誤沒有解決,一直找不到原因,後來一看部署的git版本有問題,於是決定在頁面中顯示git版本。
要顯示git版本,首先要知道它存在什麼地方?這就導致我們需要知道git的目錄中的資訊,知道了資訊我們怎麼把它拿出來這也是個問題?。

準備工作

.git目錄與git瞭解

當你建立一個倉庫的時候,使用 git init 指令, git 將會建立一個神奇的目錄:.git。這個目錄下包含了所有 git 正常工作所需要的資訊。

這裡就是第一次提交之前 .git 目錄的檔案結構:

<pre>
<code>
├── HEAD:這個檔案包含了一個檔期分支(branch)的引用,通過這個檔案Git可以得到下一次commit的parent
├── branches
├── config:這個是GIt倉庫的配置檔案
├── description:倉庫的描述資訊,主要給gitweb等git託管系統使用
├── hooks:這個目錄存放一些shell指令碼,可以設定特定的git命令後觸發相應的指令碼;在搭建gitweb系統或其他git託管系統會經常用到hook script
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ └── ...
├── info:包含倉庫的一些資訊
│ └── exclude
├── objects:所有的Git物件都會存放在這個目錄中,物件的SHA1雜湊值的前兩位是資料夾名稱,後38位作為物件檔名
│ ├── info
│ └── pack
└── refs:這個目錄一般包括三個子資料夾,heads、remotes和tags,heads中的檔案標識了專案中的各個分支指向的當前commit
├── heads
└── tags
</code>
</pre>

這個檔案包含你倉庫的設定資訊。例如這裡會放你遠端倉庫的 URL,你的 email 地址,你的使用者名稱等…。 每次你在控制檯使用“git config…”指令時,修改的就是這裡。

這裡不對.git的檔案進行詳細說明了,直接說明是那個檔案,這裡給大家推薦幾個.git目錄詳解的教程:

git指南:GitBook
探索 .git 目錄,讓你真正了理解git
Git HEAD 意思詳解 和版本回退
GitBook, Git + Markdown 快速釋出你的書籍

首先,Git必須知道當前版本是哪個版本,在Git中,用HEAD表示當前分支版本的路徑指向,也就是最新的提交。這裡我們需要用到git根目錄下的HEAD,我們開啟它,他裡面有這樣一句話:

ref: refs/heads/這裡是你的分支名字

如果你只有master分支或者你通過git checkout 分支切換到master上,就是ref: refs/heads/master。

比如題主目前有兩個分支

4645892-93a71634149bcefc.png
我的分支檢視

在develop分支時,HEAD的內容是ref: refs/heads/develop,在master分支時HEAD的內容是ref: refs/heads/master

我們根據HEAD指向的目錄資訊可以看到如下內容

4645892-d4ef841511853aa5.png
HEAD指向的目錄資訊

這裡說明題主是develop分支(如果你們沒有develop分支,請開啟你們自己的當前分支版本的路徑指向),所以我們開啟develop,它的內容就是當前git版本b1b8d7b1f29d40b68c16b2f524d8655ae99faeae(注意我的提交ID和你的肯定不一樣)

node讀取檔案

因為我們是基於webpack的git版本獲取,而webpack是基於node的,因為是基於vue的前端,我們沒有辦法在src底下的前端專案中獲取src檔案之外的東西(如果你這樣做了,不過不是static,那是不對的),所以我們只能在src之外的可以使用node的地方,供我們選擇的地方不多,只有下面這些:

4645892-83519e3734f49228.png
使用node的地方

我們這裡仔細敲定選通過config的底下的專案構建檔案dev.env.jsprod.env.js來得到我們需要的資訊,即在專案構建時我們獲取git版本。

我們需要使用node的fs模組

這裡附上node的api:

Node.js 中文文件

webpack構建時使用node獲取git版本

預設的dev.env.js是這樣的:

var merge = require('webpack-merge')
var prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"'
})

預設的prod.env.js是這樣的:

module.exports = {
  NODE_ENV: '"production"'
}

我們dev.env.js的獲取程式碼如下:(記住題主是develop分支,你們不一定,但是程式碼是相同的,只是註釋換成你們自己的)

var merge = require('webpack-merge')
var prodEnv = require('./prod.env')

// 當前指令碼的工作目錄的路徑
var cwd = '"' + process.cwd() + '"' // process-node全域性模組用來與當前程式互動,可以通過全域性變數process訪問,不必使用require命令載入。它是一個EventEmitter物件的例項。process.cwd()表示返回執行當前指令碼的工作目錄的路徑

// 獲取git版本
var fs = require("fs")
var gitHEAD = fs.readFileSync('.git/HEAD', 'utf-8').trim() // ref: refs/heads/develop
var ref = gitHEAD.split(': ')[1] // refs/heads/develop
var develop = gitHEAD.split('/')[2] // 環境:develop
var gitVersion = fs.readFileSync('.git/' + ref, 'utf-8').trim() // git版本號,例如:6ceb0ab5059d01fd444cf4e78467cc2dd1184a66
var gitCommitVersion = '"' + develop + ': ' + gitVersion + '"' // 例如dev環境: "develop: 6ceb0ab5059d01fd444cf4e78467cc2dd1184a66"
module.exports = merge(prodEnv, {
  CURRENT_WORK_DIR: cwd, // 當前指令碼的工作目錄的路徑
  GIT_COMMIT_VERSION: gitCommitVersion, // 獲取git版本
  NODE_ENV: '"development"'
}

注意:上面程式碼的'"'東西不能換成',具體原因自行百度。

可是我們dev.env.js只是開發環境,我們需要在正式環境上也顯示,很簡單,複製一份放到prod.env.js中:

// 當前指令碼的工作目錄的路徑
var cwd = '"' + process.cwd() + '"' // process-node全域性模組用來與當前程式互動,可以通過全域性變數process訪問,不必使用require命令載入。它是一個EventEmitter物件的例項。process.cwd()表示返回執行當前指令碼的工作目錄的路徑

// 獲取git版本
var fs = require("fs")
var gitHEAD = fs.readFileSync('.git/HEAD', 'utf-8').trim() // ref: refs/heads/develop
var ref = gitHEAD.split(': ')[1] // refs/heads/develop
var develop = gitHEAD.split('/')[2] // 環境:develop
var gitVersion = fs.readFileSync('.git/' + ref, 'utf-8').trim() // git版本號,例如:6ceb0ab5059d01fd444cf4e78467cc2dd1184a66
var gitCommitVersion = '"' + develop + ': ' + gitVersion + '"' // 例如dev環境: "develop: 6ceb0ab5059d01fd444cf4e78467cc2dd1184a66"
module.exports = merge(prodEnv, {
  CURRENT_WORK_DIR: cwd, // 當前指令碼的工作目錄的路徑
  GIT_COMMIT_VERSION: gitCommitVersion, // 獲取git版本
  NODE_ENV: '"production"'
}

結語

到此我們可以得到git版本還有當前指令碼的工作目錄的路徑。

提示:後面還有精彩敬請期待,請大家關注我的專題:web前端。如有意見可以進行評論,每一條評論我都會認真對待。

相關文章