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/
修改某个文件,浏览器中自动有变化。