使用Make構(gòu)建Node.js網(wǎng)站項(xiàng)目
一、Make的優(yōu)點(diǎn)
首先解釋一下,為什么要用Make。
目前,網(wǎng)站項(xiàng)目(尤其是Node.js項(xiàng)目)有三種構(gòu)建方案。
我覺得,make是大型項(xiàng)目的首選方案。npm run可以認(rèn)為是make的簡化形式,只適用于簡單項(xiàng)目,而Grunt、Gulp那樣的工具,有很多問題。
(1)插件問題
Grunt和Gulp的操作,都由插件完成。即使是文件改名這樣簡單的任務(wù),都要寫插件,相當(dāng)麻煩。而Make是直接調(diào)用命令行,根本不用擔(dān)心找不到插件。
(2)兼容性問題
插件的版本,必須與Grunt和Gulp的版本匹配,還必須與對應(yīng)的命令行程序匹配。比如,grunt-contrib-jshint插件現(xiàn)在是0.11.0版,對應(yīng)Grunt 0.4.5版和JSHint 2.6.0版。萬一Grunt和JSHint升級,而插件沒有升級,就有可能出現(xiàn)兼容性問題。Make是直接調(diào)用JSHint,不存在這個(gè)問題。
(3)語法問題
Grunt和Gulp都有自己的語法,并不容易學(xué),尤其是Grunt,語法很羅嗦,很難一眼看出來代碼的意圖。當(dāng)然,make也不容易學(xué),但它有復(fù)用性,學(xué)會(huì)了還可以用在其他場合。
(4)功能問題
make已經(jīng)使用了幾十年,全世界無數(shù)的大項(xiàng)目都用它構(gòu)建,早就證明非??煽?,各種情況都有辦法解決,前人累積的經(jīng)驗(yàn)和資料也非常豐富。相比之下,Grunt和Gulp的歷史都不長,使用范圍有限,目前還沒有出現(xiàn)它們能做、而make做不到的任務(wù)。
基于以上理由,我看好make。
二、常見的構(gòu)建任務(wù)
下面是一些常見的網(wǎng)站構(gòu)建任務(wù)。
- 檢查語法
- 編譯模板
- 轉(zhuǎn)碼
- 合并
- 壓縮
- 測試
- 刪除
這些任務(wù)用到 JSHint、handlebars、CoffeeScript、uglifyjs、mocha 等工具。對應(yīng)的package.json文件如下。
"devDependencies": { "coffee-script": "~1.9.1", "handlebars": "~3.0.0", "jshint": "^2.6.3", "mocha": "~2.2.1", "uglify-js": "~2.4.17" }
我們來看看,Make 命令怎么完成這些構(gòu)建任務(wù)。
三、Makefile的通用配置
開始構(gòu)建之前,要編寫Makefile文件。它是make命令的配置文件。所有任務(wù)的構(gòu)建規(guī)則,都寫在這個(gè)文件(參見《Make 命令教程》)。
首先,寫入兩行通用配置。
PATH := node_modules/.bin:$(PATH) SHELL := /bin/bash
上面代碼的PATH和SHELL都是BASH變量。它們被重新賦值。
PATH變量重新賦值為,優(yōu)先在 nodemodules/.bin 目錄尋找命令。這是因?yàn)椋ó?dāng)前項(xiàng)目的)node模塊,會(huì)在 nodemodules/.bin 目錄設(shè)置一個(gè)符號鏈接。PATH變量指向這個(gè)目錄以后,調(diào)用各種命令就不用寫路徑了。比如,調(diào)用JSHint,就不用寫 ~/node_modules/.bin/jshint ,只寫 jshint 就行了。
SHELL變量指定構(gòu)建環(huán)境使用BASH。
四、檢查語法錯(cuò)誤
第一個(gè)任務(wù)是,檢查源碼有沒有語法錯(cuò)誤。
js_files = $(shell find ./lib -name '*.js') lint: $(js_files) jshint $?
上面代碼中,shell函數(shù)調(diào)用find命令,找出lib目錄下所有js文件,保存在變量js_files。然后,就可以用jshint檢查這些文件。
使用時(shí)調(diào)用下面的命令。
$ make lint
五、模板編譯
第二個(gè)任務(wù)是編譯模板。假定模板都在templates目錄,需要編譯為build目錄下的templates.js文件。
build/templates.js: templates/*.handlebars mkdir -p $(dir $@) handlebars templates/*.handlebars > $@ template: build/templates.js
上面代碼查看build目錄是否存在,如果不存在就新建一個(gè)。dir函數(shù)用于取出構(gòu)建目標(biāo)的路徑名(build),內(nèi)置變量$@代表構(gòu)建目標(biāo)(build/templates.js)。
使用時(shí)調(diào)用下面的命令。
$ make template
六、Coffee腳本轉(zhuǎn)碼
第三個(gè)任務(wù)是,將CofferScript腳本轉(zhuǎn)為JavaScript腳本。
source_files := $(wildcard lib/*.coffee) build_files := $(source_files:lib/%.coffee=build/%.js) build/%.js: lib/%.coffee coffee -co $(dir $@) $< coffee: $(build_files)
上面代碼中,首先獲取所有的Coffee腳本文件,存放在變量sourcefiles,函數(shù)wildcard用來擴(kuò)展通配符。然后,將變量sourcefiles中的coffee文件名,替換成js文件名,即 lib/x.coffee 替換成 build/x.js 。
使用時(shí)調(diào)用下面的命令。
$ make coffee
七、合并文件
使用cat命令,合并多個(gè)文件。
JS_FILES := $(wildcard build/*.js) OUTPUT := build/bundle.js concat: $(JS_FILES) cat $^ > $(OUTPUT)
使用時(shí)調(diào)用下面的命令。
$ make concat
八、壓縮JavaScript腳本
將所有JavaScript腳本,壓縮為build目錄下的app.js。
app_bundle := build/app.js $(app_bundle): $(build_files) $(template_js) uglifyjs -cmo $@ $^ min: $(app_bundle)
使用時(shí)調(diào)用下面的命令。
$ make min
還有另一種寫法,可以另行指定壓縮工具。
UGLIFY ?= uglify $(app_bundle): $(build_files) $(template_js) $(UGLIFY) -cmo $@ $^
上面代碼將壓縮工具uglify放在變量UGLIFY。注意,變量的賦值符是 ?= ,表示這個(gè)變量可以被命令行參數(shù)覆蓋。
調(diào)用時(shí)這樣寫。
$ make UGLIFY=node_modules/.bin/jsmin min
上面代碼,將jsmin命令給變量UGLIFY,壓縮時(shí)就會(huì)使用jsmin命令。
九、刪除臨時(shí)文件
構(gòu)建結(jié)束前,刪除所有臨時(shí)文件。
clean: rm -rf build
使用時(shí)調(diào)用下面的命令。
$ make clean
十、測試
假定測試工具是mocha,所有測試用例放在test目錄下。
test: $(app_bundle) $(test_js) mocha
當(dāng)腳本和測試用例都存在,上面代碼就會(huì)執(zhí)行mocha。
使用時(shí)調(diào)用下面的命令。
$ make test
十一、多任務(wù)執(zhí)行
構(gòu)建過程需要一次性執(zhí)行多個(gè)任務(wù),可以指定一個(gè)多任務(wù)目標(biāo)。
build: template concat min clean
上面代碼將build指定為執(zhí)行模板編譯、文件合并、腳本壓縮、刪除臨時(shí)文件四個(gè)任務(wù)。
使用時(shí)調(diào)用下面的命令。
$ make build
如果這行規(guī)則在Makefile的最前面,執(zhí)行時(shí)可以省略目標(biāo)名。
$ make
通常情況下,make一次執(zhí)行一個(gè)任務(wù)。如果任務(wù)都是獨(dú)立的,互相沒有依賴關(guān)系,可以用參數(shù) -j 指定同時(shí)執(zhí)行多個(gè)任務(wù)。
$ make -j build
十二、聲明偽文件
最后,為了防止目標(biāo)名與現(xiàn)有文件沖突,顯式聲明哪些目標(biāo)是偽文件。
.PHONY: lint template coffee concat min test clean build
十三、Makefile文件示例
下面是兩個(gè)簡單的Makefile文件,用來補(bǔ)充make命令的其他構(gòu)建任務(wù)。
實(shí)例一。
PROJECT = "My Fancy Node.js project" all: install test server test: ;@echo "Testing ${PROJECT}....."; \ export NODE_PATH=.; \ ./node_modules/mocha/bin/mocha; install: ;@echo "Installing ${PROJECT}....."; \ npm install update: ;@echo "Updating ${PROJECT}....."; \ git pull --rebase; \ npm install clean : ; rm -rf node_modules .PHONY: test server install clean update
實(shí)例二。
all: build-js build-css build-js: browserify -t brfs src/app.js > site/app.js build-css: stylus src/style.styl > site/style.css .PHONY build-js build-css
十四、參考鏈接
- Jess Telford, Example using Makefile for cloverfield
- Oskar Schöldström, How to use Makefiles in your web projects
- James Coglan, Building JavaScript projects with Make
- Rob Ashton, The joy of make
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于Node.js的WebSocket通信實(shí)現(xiàn)
這篇文章主要介紹了基于Node.js的WebSocket通信實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03Node發(fā)出HTTP POST請求的方法實(shí)例小結(jié)
這篇文章主要介紹了Node發(fā)出HTTP POST請求的方法,結(jié)合實(shí)例形式總結(jié)分析了三種常用的post請求操作方法,以及相關(guān)庫操作注意事項(xiàng),需要的朋友可以參考下2023-05-05npm install --save 、--save-dev 、-D、-S&nb
這篇文章主要介紹了npm install --save 、--save-dev 、-D、-S 的區(qū)別與NODE_ENV的配置方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08node.js讀取Excel數(shù)據(jù)(下載圖片)的方法示例
這篇文章主要給大家介紹了關(guān)于node.js讀取Excel數(shù)據(jù)(下載圖片)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用node.js具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08node.js中的fs.truncateSync方法使用說明
這篇文章主要介紹了node.js中的fs.truncateSync方法使用說明,本文介紹了fs.truncateSync的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12