前端入門->makefile

2551129937 8年前發布 | 16K 次閱讀 Makefile 前端技術

來自: https://segmentfault.com/a/1190000004437816

我第一次見到makefile的時候,是在看js測試的那一塊。簡直,一開始跟風,覺得makefile這么牛逼,我也想看看。 首先,看了陳老師的 跟我一起學習Makefile . 打開了第一章之后,后面就沒有勇氣再打開下去了。 后來了解了一下makefile原來是C語言作為工程化處理的一個必殺技。然后就遷移到其他平臺上了,但是對于我們這種,對于C的認知度為(0)的人,這不是難為我們嗎?后來,就在網上游蕩,慢慢找,還是有點入門的感覺,這里,我想把,一些感悟分享給大家,如果有用,您就拿去,沒用的話,ctrl+w就over了。

知識 = 學習 + 分享

makefile的基本淺析

前端學習makefile的成本還是蠻大的誒~ 因為好多教程都是用c寫的,這也沒辦法,誰讓這是C的工具,我們也只是偷師學學。makefile的基本格式為:

target: prerequisities
[TAB]command

target就是你要執行的命令套件,prerequisties就是依賴,而command就是實際執行的命令。(說人話)上栗子:

create: 
    touch newMake.js

makefile的解析的過程:

首先makefile會讀取你的makefile文件.
讀取指定的target.
解析后面的依賴是否更新
如果更新則執行command
沒有則do nothing

由于我們這里后面沒有什么參數,所以,make會直接執行對應的命令。 然后執行:

make create

接著你會發現,在當前目錄下(makefile文件夾下)。會生成一個 newMake.js的文件。這時候就說明你已經成功的入門了makefile了.

基本命令

注釋

在makefile中,通常可以用"#"標識來作為注釋.

run:
        touch a.js #create js file
del:
        rm a.js #delete js file

回聲

在php中有個輸出API echo, 和這個類似,在make中,它會自動打印命令,然后才執行。

//makefile
run:
        touch a.js #create js file
//執行make
make run
//結果:
touch a.js #create js file
//這時候,他便會創建a.js文件

當然如果你不想讓make打印出來,可以在首行加上"@"表示取消回聲.

run:
        @touch a.js #create js file

之后,你再使用make run。他便不會打印出什么東西了。

自動變量

$@指代當前構建的目標。 怎么說呢?

show me the code

a.js b.js:
    touch $@
//等價于:
a.js b.js:
    touch a.js b.js;
//也等價于:
a.js:
    touch a.js;
b.js: 
    touch b.js

這里相當于你定義了兩個命令(雖然,看起來像一個)

$<指代第一個依賴的條件。(這些都是什么flag呀~ 寶寶看不懂)

我們來看一下例子吧:

</div>

create:a.js b.js
    touch $<
//等價于
create:a.js b.js
    touch a.js

還有 $^ 指代所有的依賴條件。makefile里面有很多automatic variable 這里只列一些比較常用的。

變量的使用:

在寫nodeJS測試的時候,變量的作用 super well.

通常我們需要從node_modules中,引出指定的.bin包。 一般而言就是mocha和istanbul.

使用命令:

npm install mocha istanbul --save-dev

還記得,我們在運行測試的時候的命令嗎?

istanbul cover _mocha

由于系統已經把環境變量給配置好了,你執行上面的命令的時候,其實,shell已經從全局中把對應的bin文件提取出來,并且執行了。

而在makefile中,就需要你手動執行進行路徑的配置了.

舉個例子吧,現在我們處在和 node_modules 同目錄下。

然后引入mocha和istanbul的路徑,并存入變量中:

</div>

MOCHA=./node_modules/.bin/mocha
ISTANBUL=./node_modules/.bin/istanbul

OK,這樣就夠了。 有的同學,可能會發現node_modules下并沒有.bin文件夾呀~ 親莫急。你可以使用 ls -a 來查看所有的。相信你一定能找到的。

現在我們已經定義了變量,接下來要做的就是引用定義的變量了。

在makefile中,使用$(...)進行相關的定義。

像這樣:

</div>

MOCHA=./node_modules/.bin/mocha
ISTANBUL=./node_modules/.bin/istanbul
_MOCHA=./node_modules/.bin/_mocha
runTest:
        $(ISTANBUL) cover $(_MOCHA)

然后在另外一個zsh中執行:

make runTest;

就可以達到和 istanbul cover _mocha 一樣的效果了.

在makefile里面,變量分為兩種:

</div>

引用式變量

如果es6和commonJS的同學應該知道,在模塊的書寫上,兩者都有自己的一套實現原理。 而es6的實現原理就和引用變量一樣的,即,相互引用的模塊,會持續影響到對方。舉個栗子唄:

    A=$(B);
    B=$(C);
    C=quote

當在編輯器解析時,會有以下的結果:

A=quote;
B=quote;
C=quote;

這樣,其實并沒有什么不好,但是如果你不小心寫成了一個死循環,呵呵,你電腦也就崩了。像這樣的:

A=$(B)
B=$(A)

這樣解析器會一直這樣,不斷的解析,只到你的資源被eat up. 然后你就可以關機重啟了。

直接展開式變量

這個就是用來解決上述問題的。使用的賦值符號不在是 = 而變成了 := . 看個例子吧:

A=good
B:=$(A) job
A=stupid

最終的解析結果為:

B=good job

A=stupid

為什么呢? 因為使用":="的使用,他會立即尋找上文引用到的最近的變量,然后放入B中,這時候B的值就已經固定了。如果你后面再去修改A的值是沒有意義的。

如果使用引用變量的話,會有這樣的結果:

</div>

A=good
B=$(A) job
A=bad

最后輸出:

B=bad job

A=bad

就是醬汁,大家了解就over了。

其實,大部分時候我還是會選擇引用變量的,因為簡單,靈活性更大。 而直接展開式變量通常寫給leader看的,大家注意一下就沒什么問題了。

另外變量的定義一共有 四種方法

</div>

VARIABLE = value

在執行時擴展,允許遞歸擴展。

VARIABLE := value

在定義時擴展。

VARIABLE ?= value

只有在該變量為空時才設置值。

VARIABLE += value

將值追加到變量的尾端。</pre>

由于剩下兩種使用的頻率不是很高,這里也就不贅述了。

偽目標

一門深邃的語言,首先必須要有一個裝逼的名字。偽目標這個名字好,能一眼讓你不知道他根本是干什么的。

意淫完畢~

其實,偽目標就是為了解決命令和文件名沖突的。

比如,我的makefile是這樣書寫的

clean:
        rm *.jpg
create:
        touch clean

首先,我執行make clean,他會完全的刪除當前目錄下的jpg文件。然后我運行make create 生成一個clean文件。但是當我再次使用make clean的時候。 執行的效果并不是我預期的那樣,提示jpg文件不存在。而是提示:

make: `clean' is up to date.

那么問題來了: 是你傻逼,還是電腦傻逼?

你: 肯定是電腦傻逼.

電腦: xxx&&*%^^^^%. 好吧.為了給你點信心學下去,是我傻逼

</div>

這里,涉及到了GUN make的一條tip: 隱含規則

由于這個隱含規則主要是針對于C語言的童鞋的。這里,作為前端的寶寶,我們了解一下就可以了。

隱含規則就是指一些約定俗成語句可以不需要寫出來,make可以自己去推測,并且執行。(由于隱含規則大部分是針對C的,我這里就不列了)。

這樣,像上文一樣,make clean 會首先查找隱含文件,檢查clean的文件,由于已經存在clean文件,這里會被認為是最新的,就不會去執行定義的規則了。(大家如果有興趣可以去翻閱一下詳細資料). 另外,我覺得這樣我們前端去理解這個,這是要上天呀~~~ 說白了,就是,如果你的文件下,有和命令同名的文件的話,你的命令是不會被執行的。

所以,我們需要偽命令,來解決這一沖突.

使用 .PHONY: 來進行定義:

在makefile中,我們加上一句:

.PHONY: clean
然后繼續執行 make clean

這樣,他就能正常的執行你所定義的command了。

通常情況下,我們需要把自己寫的命令都在.PHONY里面過一遍,有備無患吧~

</div>

最后說兩句

前端懂makefile沒壞處寫好makefile更沒壞處

</div>

 本文由用戶 2551129937 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!