本文是依據 Browserify 官網及網路參考資料逐步學習記錄的內容
Browserify 讓我們可以在瀏覽器中使用Node.js 風格的模組,不管是 AMD / CMD / ES6 …..風格的模塊化,它都能認識,並且編譯成瀏覽器認識的JS。
Browserify 運作的方式,會先在代碼中以靜態分析(static analysis)搜尋有調用 require()的內容,彙整出調用依賴關係圖(dependency graph),並且將關鍵字解析成路徑,然後根據路徑找到檔案, 接著,檔案會被打包(bundle)成單一獨立的 javascript 檔案,讓你可以直接在網頁中直接使用。 並且,打包的檔案預設都會使用嚴格模式 ```use
接下來,開始介紹 Browserify 安裝方式及用法說明:
安裝 browserify
首先,安裝 browserify
CVT2HUGO: strict```
npm install -g browserify
安裝完畢後,接下來將陸續介紹如何透過 Browserify 來編譯 Node 風格的模組:
- require(‘modules’)
- exports
一、 require(‘modules’)
在 Node 的 require() 函式是用來載入外部的程式碼,且調用的方式有兩種
1.當你填寫的是 require(路徑),例如 require(’./foo.js’) ,將會直接從 ./ 或者 ../ 前往位置(例如 /beep/boop/bar.js),呼叫內容 2.如果直接填寫名稱的方式,例如 require(‘xyz’),Node 就會依照下邏輯方式進行搜索
/beep/boop/node_modules/xyz
/beep/node_modules/xyz
/node_modules/xyz
如果每個目錄都有 xyz,Node會返回檢查package.json 裡的 main ,是否有指定xyz
{
"name": "xyz",
"version": "1.2.3",
"main": "lib/abc.js"
}
如果沒有指定main,Node就會預設採用下列位置的檔案
/beep/node_modules/xyz/index.js
這裡將以 uniq 來進行 require() 演練,及如何透過 browserify 編譯出結果
範例
接下來,會透過一個 uniq modules 來示範
uniq 可以從陣列中刪除所有重複的值 安裝 uniq
npm install uniq
建立 Node require
接著,新增 main.js 並寫入底下內容
//main.js
var unique = require('uniq');
var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];
//檢查是否去除掉重複的值
console.log(unique(data));
執行 Node 檢視結果
我們先用 node 來檢視會出現甚麼結果
node main.js
輸出結果
[ 1, 2, 3, 4, 5, 6 ]
Browserify 轉譯檔案
接下來,用browserify 來轉譯main.js的結果,並且儲存為 bundle.js 語法如下:
browserify main.js -o bundle.js
或者,可以透過 > 操作子
browserify main.js > bundle.js
執行轉譯結果
建立一個 test.html,並且使用剛剛轉譯成功的 bundle.js, 可直接開啟瀏覽器,從開發者工具中察看 console
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
輸出結果
Array(6)
0:1
1:2
2:3
3:4
4:5
5:6
length:6
#二、 export 當我們透過 require 載入模組, 當模組載入時,會返回module.exports的內容 當然,也可以直接使用 module.exports 的輔助方法 exports,照樣能夠正常返回結果 (建議統一使用module.exports) 首先,使用 module.exports 測試 foo.js
module.exports = function (n) { return n * 111 }
main.js
var foo = require('./foo.js');
console.log(foo(5));
然後執行```node
接下來用 exports 試試看
foo.js
CVT2HUGO: main.js```,就能看到輸出結果為555
exports.name = function() {
console.log('My name is Adam');
};
main.js
var foo = require('./foo.js');
foo.name();
輸出結果為 My name is Adam
接下來,一樣將上面的結果進行 browserify 轉譯
browserify main.js > bundle.js
再檢查是否正常在瀏覽器上面執行
三、搭配第三方套件
這裡僅以jQuery來示範,其他第三方套件則依照同樣原則來使用即可。
jQuery
通常,我們會先前往jQuery官網,下載最新的檔案, 但現在,只要透過 npm 就能直接下載最新的檔案,再透過browserify 即可在瀏覽器中使用
首先,先安裝 jQuery,並且透過 –save 將jquery 自動加入 package.json 行列
npm install jquery --save
在main.js載入jquery並且使用 main.js
var $ = require('jquery');
$(function(){
$("h1").hide();
console.log('h1 hided');
});
用browserify將main.js打包成bundle.js
browserify main.js > bundle.js
編輯 test.html 內容
<body>
<h1>Hello world</h1>
<!--js-->
<script type="text/javascript" src="bundle.js"></script>
</body>
其他
Gulp + Browserify
如果想在Gulp使用Browserify,不推薦使用 gulp-browserify,
而是直接 require(‘browserify’) 即可,
先安裝 browserify 並儲存在本地gulp
npm install browserify --save
如果遇到下方錯誤
Refusing to install browserify as a dependency of itself
請檢查你的package.json name是否命名為 browserify,如果是就會引發衝突,請更名
另外,Gulp 使用的是 Vinyl File Object Stream,而不是普通的Node Stream,無法支援取得 Node stream 庫,
所以,需透過 vinyl-source-stream 把 Node Stream 轉換為Gulp支援的 Vinyl File Object Stream,讓一般的 Node Stream 可以連結到 Gulp體系。(詳細可參考 這裡)
npm install vinyl-source-stream --save
順帶一提,vinyl-source-stream 和gulp.src()一樣,會依照來源名進行新增,因此可搭配gulp.dest()將檔案複製到指定位置,因此不必再寫使用 gulp-rename 重新命名
另外,一定要確認有在 package.json 加入 babelify package.json
{
"browserify": {
"transform": [["babelify", { "presets": ["latest"] }]]
},
"name": "browserifys",
"version": "1.0.0",
"babel": {
"plugins": [
[
"transform-runtime",
{
"helpers": false,
"polyfill": false,
"regenerator": true,
"moduleName": "babel-runtime"
}
]
]
},
...
}
範例如下:
gulpfile.js
var browserify = require('browserify'),
gulp = require('gulp'),
source = require('vinyl-source-stream');//returns a streaming vinyl object where as uglify expects buffered vinyl file objects.
gulp.task('browserify', function() {
return browserify('./main.js')
.bundle()
// pass desired output filename to vinyl-source-stream
.pipe(source('boundle.js'))
.pipe(gulp.dest('./'));
});
gulp.task('default',['browserify']);
進階一點的使用方式: gulpfile.js
var browserify = require('browserify'),
gulp = require('gulp'),
uglify = require('gulp-uglify'),//will compress source code
source = require('vinyl-source-stream'),//returns a streaming vinyl object where as uglify expects buffered vinyl file objects.
buffer = require('vinyl-buffer');// will convert streaming vinyl files to use buffer.
gulp.task('browserify', function() {
return browserify('./main.js')
.bundle()
// pass desired output filename to vinyl-source-stream
.pipe(source('boundle.js'))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest('./'));
});
gulp.task('default',['browserify']);
watchify 即時監聽
將上面 browserify修改成監聽模式,先安裝 watchify
npm install watchify --save
要等到檔案變更之後,才會觸發 gulpfile.js
var browserify = require('browserify'),
gulp = require('gulp'),
watchify = require('watchify'),//watchify
source = require('vinyl-source-stream');//returns a streaming vinyl object where as uglify expects buffered vinyl file objects.
var b = browserify({
entries: ['./main.js'],
cache: {},// required for watchify
packageCache: {},// required for watchify
plugin: [watchify]
});
function bundle() {
return b.bundle()
// pass desired output filename to vinyl-source-stream
.pipe(source('boundle.js'))
.pipe(gulp.dest('./'));
}
bundle();
b.on('update', bundle);
gulp.task('default');