Browserify是一個Javascript的庫,能夠用來把多個Module打包到一個文件中,而且能很好地應對Modules之間的依賴關係。而Module是封裝了屬性和功能的單元,是一個Javascript對象,Modules之間能夠相互依賴。某種程度上來講,Browserify模仿了Node.js加載Module的方式。一個js文件包含一個Module。因此,Browserify經過讀取文件來加載該文件內的Module。css
【module的寫法】html
'use strict'; exports.save = function(tasks){}; exports.load = function(){}; exports.clear = function(){};
還能夠這麼寫:jquery
'use strict'; module.exports = { save: function(tasks){}, load: function(){}, clear: function(){} };
【module的緩存】web
一、單例模式緩存npm
module ajson
exports.value = "original";
module bgulp
var a = require('./a'); a.value = "changed"; console.log(a.value);//changed
module c數組
var a = require('./a'); console.log(a.value);//original
module c中的a.value值之因此是original,是由於module c對module a有依賴,並且依賴的是緩存。因此,在默認狀況下,module是有緩存的,也能夠理解成單例模式。瀏覽器
二、實例模式緩存緩存
還能夠經過構造函數來建立一個module。
module a
module.exports = function(){ this.value = "original value"; };
module b
var A = require('./a'); var a = new A(); a.value = "changed"; console.log(a.value);//changed
module c
var A = require('./a'); var a = new A(); console.log(a.value);//original
【準備工做】
【明確目標】
【文件結構】
.....css/
..........tasks.css
.....js/
..........data/
...............taskData.js
..........renderers/
...............taskRenderer.js
..........tasks.js
..........app.js
.....index.html
【代碼實現】
文件結構有了,module的寫法也搞清楚了,接下來就實現一遍。
① taskData.js 是用來處理數據的一個module
'use strict'; var STORE_NAME = "tasks"; exports.save = function(tasks){ localStorage.setItem(STORE_NAME, JSON.stringify(tasks)); }; exports.load = function(){ var storedTasks = localStorage.getItem(STORE_NAME); if(storedTasks){ return JSON.parse(storedTasks); } return []; }; exports.clear = function(){ localStorage.removeItem(STORE_NAME); };
② taskRenderer.js 是用來處理頁面相關的一個module
'use strict'; var $ = require('jquery'); var taskTemplate = '<li class="task"><input class="complete" type="checkbox" /><input class="description" type="text" /></li>'; //返回一段帶值的html //task是傳入的一個object對象 function _renderTask(task){ var $task = $(taskTemplate); if(task.complete){ $task.find(".complete").attr("checked", "checked"); } $task.find(".description").val(task.description); return $task; } exports.renderTasks = function(tasks){ //遍歷任務得到帶值html的數組 var elementArray = $.map(tasks, _renderTask); $("#task-list") .empty() .append(elementArray); }; exports.renderNew = function(){ var $taskList = $("#task-list"); $taskList.prepend(_renderTask({})); }
③ tasks.js 用到了以上2個module
'use strict'; var $ = require('jquery'); var taskData = require('./data/taskData'); var taskRenderer = require('./renderers/taskRenderer'); exports.add = function () { taskRenderer.renderNew(); }; exports.remove = function (clickEvent) { var taskElement = clickEvent.target; $(taskElement).closest(".task").remove(); }; exports.clear = function(){ taskData.clear(); exports.render(); }; exports.save = function(){ var tasks=[]; $("#task-list .task").each(function(index, task){ var $task = $(task); tasks.push({ complete: $task.find(".complete").prop('checked'), description: $task.find(".description").val() }); }); taskData.save(tasks); }; exports.cancel = function(){ exports.render(); }; exports.render = function(){ taskRenderer.renderTasks(taskData.load()); };
④ app.js 只須要和tasks.js打交道就能夠
'use strict'; var $ = require('jquery'); var tasks =require('./tasks'); function _addTask(){ tasks.add(); } function _deleteAllTasks(){ tasks.clear(); } function _saveChanges(){ tasks.save(); } function _cancelChanges(){ tasks.cancel(); } function _deleteTask(clientEvent){ tasks.remove(clientEvent); } function _registerEventHandlers(){ $('#new-task-button').on("click", _addTask); $('#delete-all-button').on("click", _deleteAllTasks); $('#save-button').on("click",_saveChanges); $('#cancel-button').on("click", _cancelChanges); $('#task-list').on("click", ".delete-button", _deleteTask); } _registerEventHandlers(); tasks.render();
⑤ 使用browserify把全部module捆綁到一個js文件中去:
browserify src\js\app.js -o src\js\app.bundle.js
⑥ index.html 只須要引用src\js\app.bundle.js就能夠
<!DOCTYPE html> <html> <head> <title>Task List</title> <link rel="stylesheet" href="css/tasks.css"> </head> <body> <header> <h1>TaskList</h1> </header> <div class="toolbar"> <button id="new-task-button">New Task</button> <button id="delete-all-button">Delete All</button> </div> <div id="content"> <ul id="task-list"> </ul> <ul id="log-list"> </ul> </div> <div class="toolbar"> <button id="save-button">Save</button> <button id="cancel-button">Cancel</button> </div> <script src="js/app.bundle.js"></script> </body> </html>
【若是有不少文件,調試時出錯】
當有不少文件的時候,調試出錯,使用Source Map能夠方便找到出錯的文件和出錯的地方。
如今,有了app.bundle.js文件,以及有了app.js, tasks.js, taskRenderer.js, taskData.js文件們,咱們能夠在app.bundle.js和其它js文件中建立一個Souce Map.
browserify src\js\app.js -o src\js\app.bundle.js --debug
這樣,會在app.bundle.js文件最後面追加上相似//# sourceMappingURL=data:application/json;
,這樣在調試的時候會很容易找到出錯的文件和出錯的位置。
【修改文件】
若是此時修改某個js文件呢?咱們還須要使用browserify把全部的module依賴關係捆綁到一個文件中,執行以下的命令:
browserify src\js\app.js -o src\js\app.bundle.js
解決思路:Watchify爲此而生,當發現有文件變化,自動運行Browserify。
全局安裝Watchify:npm install -g watchify
在命令行窗口運行Watchify命令:watchify src\js\app.js -o src\js\app.bundle.js --debug -v
此時保持命令窗口打開着。
修改某個文件,並保存,發現命令窗口會自動運行:watchify src\js\app.js -o src\js\app.bundle.js --debug -v
【Grunt Browserify】
Grunt是Javascript Task Runner,也是運行在Node.js之上。
如何安裝Grunt?
檢測版本?
grunt --version
在哪一個文件中配置?
通常在根目錄下的Gruntfile.js
Grunt與Browserify的結合?
npm install grunt-browserify --save-dev
在根目錄下的Gruntfile.js文件:
module.exports=function(grunt){ //配置 grunt.initConfig({ browserify: { app: { src: 'templates/src/js/app.js', dest: 'templates/src/js/app.bundle.js', options: { browserifyOptions:{ debug: true } } } } }); //加載其它module/plugins grunt.loadNpmTasks('grunt-browserify'); //定義task grunt.registerTask('default',['browserify']); }
【Grunt Watch】
使用了Grunt以及用Gruntfile.js進行配置以後,每次有文件變化,咱們須要在命令行窗口輸入gulp命令。能不能自動爲咱們運行gulp命令呢?
Grunt Watch出場。
如何安裝Grunt Watch?
npm install grunt-contrib-watch --save-dev
修改Gruntfile.js文件
module.exports=function(grunt){ //配置 grunt.initConfig({ browserify: { app: { src: 'templates/src/js/app.js', dest: 'templates/src/js/app.bundle.js', options: { browserifyOptions:{ debug: true } } } }, watch: { app: { files: ['templates/src/js/*/*.js'], tasks: ['browserify'] } } }); //加載其它module/plugins grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-contrib-watch'); //定義task grunt.registerTask('default',['browserify']); }
在命令行窗口輸入:grunt watch
如今,修改templates/src/js中的任何js文件,會自動運行browserify命令。
【Grunt Connect】
Grunt Connect可讓咱們搭建一個web server。
如何安裝?
npm install grunt-contrib-connect --save-dev
修改Gruntfile.js文件
module.exports=function(grunt){ //配置 grunt.initConfig({ browserify: { app: { src: 'templates/src/js/app.js', dest: 'templates/src/js/app.bundle.js', options: { browserifyOptions:{ debug: true } } } }, watch: { app: { files: ['templates/src/js/*/*.js'], tasks: ['browserify'] } }, connect: { app: { options: { port: 9001, base: 'templates/src' } } } }); //加載其它module/plugins grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-connect'); //定義task grunt.registerTask('default',['browserify']); grunt.registerTask('serve',['browserify:app', 'connect:app', 'watch:app']); }
在命令行窗口輸入:grunt serve
在瀏覽器窗口輸入:localhost:9001
【Connect Live Reload】
如今,能夠在瀏覽器中輸入localhost:9001瀏覽到網頁內容,此時,若是某個文件有變化,咱們須要從新刷新瀏覽器。web server能夠有自動刷新的功能嗎?
Connect Live Reload就是解決這個問題的。
如何安裝?
npm install connect-livereload --save-dev
修改Gruntfile.js文件
module.exports=function(grunt){
//配置 grunt.initConfig({ browserify: { app: { src: 'templates/src/js/app.js', dest: 'templates/src/js/app.bundle.js', options: { browserifyOptions:{ debug: true } } } }, watch: { app: { files: ['templates/src/js/*/*.js'], tasks: ['browserify'], options: { //爲保持web server 的自動刷新而設置 livereload: true } } }, connect: { app: { options: { port: 9001, base: 'templates/src', middleware: function(connect, options, middlewares){//爲保持web server 的自動刷新而設置 middlewares.unshift(require('connect-livereload')()); return middlewares; } } } } }); //加載其它module/plugins grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-connect'); //定義task grunt.registerTask('default',['browserify']); grunt.registerTask('serve',['browserify:app', 'connect:app', 'watch:app']); }
在命令行窗口輸入:grunt serve
在瀏覽器中打開:http://localhost:9001/
修改某個文件,瀏覽器中自動有變化。