了解Browserify
2016-05-14 10:17
363 查看
Browserify是一个Javascript的库,可以用来把多个Module打包到一个文件中,并且能很好地应对Modules之间的依赖关系。而Module是封装了属性和功能的单元,是一个Javascript对象,Modules之间可以相互依赖。某种程度上来说,Browserify模仿了Node.js加载Module的方式。一个js文件包含一个Module。所以,Browserify通过读取文件来加载该文件内的Module。
【module的写法】
还可以这么写:
【module的缓存】
1、单例模式缓存
module a
module b
module c
module c中的a.value值之所以是original,是因为module c对module a有依赖,而且依赖的是缓存。所以,在默认情况下,module是有缓存的,也可以理解成单例模式。
2、实例模式缓存
还可以通过构造函数来创建一个module。
module a
module b
module c
【准备工作】
安装Node.js
安装Browserify:npm install -g browserify
【明确目标】
app这个module包含了和视图交互的逻辑,是整个程序的entry point
app这个module依赖tasks这个module,tasks这个module用来管理task list
taskRender这个module用来渲染页面,taskData这个module用来保存加载有关task list的数据
【文件结构】
.....css/
..........tasks.css
.....js/
..........data/
...............taskData.js
..........renderers/
...............taskRenderer.js
..........tasks.js
..........app.js
.....index.html
【代码实现】
文件结构有了,module的写法也搞清楚了,接下来就实现一遍。
① taskData.js 是用来处理数据的一个module
② taskRenderer.js 是用来处理页面相关的一个module
③ tasks.js 用到了以上2个module
④ app.js 只需要和tasks.js打交道就可以
⑤ 使用browserify把所有module捆绑到一个js文件中去:
browserify src\js\app.js -o src\js\app.bundle.js
⑥ index.html 只需要引用src\js\app.bundle.js就可以
【如果有很多文件,调试时出错】
当有很多文件的时候,调试出错,使用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文件最后面追加上类似
【修改文件】
如果此时修改某个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?
npm install -g grunt-cli
npm install grunt --save-dev
检测版本?
grunt --version
在哪个文件中配置?
一般在根目录下的Gruntfile.js
Grunt与Browserify的结合?
npm install grunt-browserify --save-dev
在根目录下的Gruntfile.js文件:
【Grunt Watch】
使用了Grunt以及用Gruntfile.js进行配置之后,每次有文件变化,我们需要在命令行窗口输入gulp命令。能不能自动为我们运行gulp命令呢?
Grunt Watch出场。
如何安装Grunt Watch?
npm install grunt-contrib-watch --save-dev
修改Gruntfile.js文件
在命令行窗口输入:grunt watch
现在,修改templates/src/js中的任何js文件,会自动运行browserify命令。
【Grunt Connect】
Grunt Connect可以让我们搭建一个web server。
如何安装?
npm install grunt-contrib-connect --save-dev
修改Gruntfile.js文件
在命令行窗口输入: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 serve
在浏览器中打开:http://localhost:9001/
修改某个文件,浏览器中自动有变化。
【module的写法】
'use strict'; exports.save = function(tasks){}; exports.load = function(){}; exports.clear = function(){};
还可以这么写:
'use strict'; module.exports = { save: function(tasks){}, load: function(){}, clear: function(){} };
【module的缓存】
1、单例模式缓存
module a
exports.value = "original";
module b
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是有缓存的,也可以理解成单例模式。
2、实例模式缓存
还可以通过构造函数来创建一个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
【准备工作】
安装Node.js
安装Browserify:npm install -g browserify
【明确目标】
app这个module包含了和视图交互的逻辑,是整个程序的entry point
app这个module依赖tasks这个module,tasks这个module用来管理task list
taskRender这个module用来渲染页面,taskData这个module用来保存加载有关task list的数据
【文件结构】
.....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?
npm install -g grunt-cli
npm install grunt --save-dev
检测版本?
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/
修改某个文件,浏览器中自动有变化。
相关文章推荐
- 将大于整数m且紧靠m的k个素数存入数组xx传回(160514)
- JAVA-勇者斗恶龙-The Dragon of Loowater,Uva 11292-排序后贪心
- 遍历数组元素,然后返回按2个数一组的字符串,中间加上分隔符
- 去掉标题栏和信息栏的代码实现
- 一起学Netty(十三)之 Netty简单的重连机制
- Release Order的问题记录
- 一起学Netty(十二)之 Netty心跳简单Demo
- 字符串专题:几种奇怪的算法
- Tomcat - 设置 HTTP 摘要认证
- Dylsim-V2X simulation 软件介绍
- python3爬虫得到的数据乱码并进行处理
- 一起学Netty(十一)之 Netty心跳之IdleStateHandler
- 产品需求文档到底该怎么写?
- 类型转换
- 第103课:动手实战联合使用Spark Streaming、Broadcast、Accumulator实现在线黑名单过滤和计数
- 程序员的自我修养 读书笔记02
- YUV采样及存储格式
- 在ASP.NET 2.0中操作数据之四十二:DataList和Repeater数据排序(一)
- [LeetCode] 148. Sort List (Linked List) - Using Quick Sort(小改动)
- JavaScript中的比较