一。browserify 简介

browserify is a tool for compiling node-flavored commonjs modules for the browser

You can use browserify to organize your code and use third-party libraries even if you don't use node itself in any other capacity except for bundling and installing packages with npm.

The module system that browserify uses is the same as node, so packages published to npm that were originally intended for use in node but not browsers will work just fine in the browser too.

官网链接

简介就直接从官网上copy过来,重点信息都加粗了。

二。学习总结

browserify 可以使开发前端组件就像开发node后端一样----使用require引入依赖(无缝使用了node模块系统的优点),甚至可以使用node里面才有的东西(比如Buffer对象,events,crypto等)。然后最终将编写的模块编译成一个js文件。

我的观点

对于模块化

browserify在他的handbook里面论述了前端模块系统(window globals,concatenate,AMD)的优缺点. 其中对挂载在window对象上这种方式的批判理由是:

Instead of a module system, each file defines properties on the window global object or develops an internal namespacing scheme.

This approach does not scale well without extreme diligence since each new file needs an additional tag in all of the html pages where the application will be rendered. Further, the files tend to be very order-sensitive because some files need to be included before other files the expect globals to already be present in the environment.

It can be difficult to refactor or maintain applications built this way.This approach tends to be very slow since each tag initiates a new round-trip http request.

browserify相对于挂载到window对象的优势在于:他将js文件都编译成了一个,只有一个http请求,并且消除了因为加载顺序导致的依赖失败。

只有一个http请求是很容易办到的。只需将一个模块的所有js文件放到一个js文件里即可。开发的时候是多个文件,开发完之后使用gulp,uglify,minify之后按依赖顺序合并到一个文件里即可。这个方法就是browserify在他的handbook里说的concatenate,对于这个他的解释是难以维护,很难发现错误发生在哪里。对于这个的话,在开发阶段是多个文件分开独立开发的,只是最后使用gulp合并在一起,发现问题出现在哪里没有多难吧!!!

让我们来看一下他编译后的js代码结构:

(function e(t, n, r) { //浏览器端的模块加载函数
function s(o, u) {
if (!n[o]) {
if (!t[o]) {
var a = typeof require == "function" && require;
if (!u && a)
return a(o, !0);
if (i)
return i(o, !0);
var f = new Error("Cannot find module '" + o + "'");
throw f.code = "MODULE_NOT_FOUND",
f
}
var l = n[o] = {
exports : {} };
t[o][0].call(l.exports, function (e) {
var n = t[o][1][e];
return s(n ? n : e)
}, l, l.exports, e, t, n, r)
}
return n[o].exports
}
var i = typeof require == "function" && require;
for (var o = 0; o < r.length; o++)
s(r[o]);
return s
})({
1 : [function (require, module, exports) {//传入的自定义模块 exports.say = function () {
console.log("Hello word");
}
}, {} ]
}, {}, [1]);

编译后的代码和直接使用闭包编写模块组件并没有太大不同,只不过这个引入了版本控制。模块自己有自己的依赖,如果模块的依赖中引入的俩个同名的模块的版本不同,那么就会俩个版本都引入,不会造成版本冲突(封装在各自的作用域下),只是文件会稍大,如果你能容忍,那没关系。

另外就是维护和重构,合并到一个文件里面确实难以维护。但是browserify最终也是将文件合并成了一个,开发的时候是多个。对于这个,按照上面我提到的方法,我们开发的时候也是各个小模块独立开发,最终聚合在一起。 这个方法的好处还有我们在开发的时候不需要编译即可进行各个模块间的联调,而browserify还需要编译一下。我们的编译只发生在最终的产品发布阶段。这个方法另外的优点browserify自己也提到:

On the plus side, all browsers natively support this approach and no server-side tooling is required.

对于使用node的模块

browserify可以使在浏览器端用node自带的或者本来是为node设计的第三方模块,比如events,Buffer,url等。对于这个特性我迫不及待地尝试了一下:

  • w1.js

var events=require("events").EventEmitter; var e=new events();
e.on("data",function(d){
document.getElementById("t1").innerHTML=d;
}); module.exports=e;
  • w2.js
 var crypto=require("crypto");

var md5update=function(str){
return crypto.createHash("md5").update(str).digest("hex");
}; exports.md5Update=md5update;
  • tools.js
exports.eventer=require("./w1.js");
exports.md5=require("./w2.js").md5Update;
window.tools=exports;
  • build.js

var browserify=require("browserify");
var fs=require("fs");
var ws=fs.createWriteStream("./final.js");
var b=browserify();
b.add("./tools.js");
b.bundle().pipe(ws);
  • test.html
  <!DOCTYPE html>
<html>
<head>
<style>
#t1{
width:200px;
height:100px;
background-color:skyblue;
margin-left:300px;
}
</style>
</head>
<body>
<div id="t1"></div>
<script type="text/javascript" src="./final.js"></script>
<script>
setInterval(function(){
var k='t'+Math.random();
tools.eventer.emit('data',tools.md5(k));
},5000)
</script>
</body>
</html>

然后:cmd>node build.js 编译出final.js 。使用浏览器打开test.html ,结果如预期:

可以看到md5加密后的字符串。

但是有一点令人无法接受,这个final.js 大小是549kb ,js.format之后是2w多行。 若非必要,还是不要用,d3的文件大小才300多kb,这才只用了crypto和events.....

final

我们可以选择性地使用browserify的功能,如果喜欢require()的方式的话,只要不嫌编译麻烦还是可以的。对于使用node本地的模块这一点,我们可以单独提出来,使用browserify做成对应项目的一个工具库。

browserify总结的更多相关文章

  1. Vue.js——60分钟browserify项目模板快速入门

    概述 在之前的一系列vue.js文章,我们都是用传统模式引用vue.js以及其他的js文件的,这在开发时会产生一些问题. 首先,这限定了我们的开发模式是基于页面的,而不是基于组件的,组件的所有代码都直 ...

  2. 前端构建工具的用法—grunt、gulp、browserify、webpack

    随着前端项目的飞速发展,项目越来越大.文件越来越多,前端工程化的工具也越来越多.下面介绍目前最流行的四种构建工具——grunt.gulp.browserify.webpack 所有的构建工具都是基于N ...

  3. gulp启动一个小型web服务器配置&browserify(require)

    var gulp = require('gulp'), connect = require('gulp-connect'), // 运行live reload服务器 browserify = requ ...

  4. browserify压缩合并源码反编译

    最近在学习钉钉(一个协作应用)桌面应用的前端源码时候,发现其js源码是用browserify做模块开发.于是想还原其源码的原本的目录结构,学习它的目录分类以及业务划分. 前言 用过browserify ...

  5. browserify学习总结

    前言 在未接触browserify,虽然我知道它是一个前端构建工具,但还是有几个疑问: 1. browserify出现的日期? 2. 能构建哪些文件? 3. 附加的browserify代码体积是多大? ...

  6. gulp/grunt和browserify/webpack的区别

    Gulp应该和Grunt比较,他们的区别我就不说了,说说用处吧.Gulp / Grunt 是一种工具,能够优化前端工作流程.比如自动刷新页面.combo.压缩css.js.编译less等等.简单来说, ...

  7. angular项目总结——angular + browserify + gulp + bower + less 架构分享

    一眨眼,快三个月没有写博客了.一直在为自己没有写博客而懊恼,忙过这段时间,好好总结一下. 新项目主要是自己一个人在写,先搭建了一个初步的架构,用了我并不熟悉的angular,这个过程中,慢慢也熟悉了a ...

  8. browserify使用手册

    简介 这篇文档用以说明如何使用browserify来构建模块化应用 browserify是一个编译工具,通过它可以在浏览器环境下像nodejs一样使用遵循commonjs规范的模块化编程. 你可以使用 ...

  9. 使用Gulp和Browserify来搭建React应用程序

    对React有一定了解之后,我们知道,需要把JSX文件转换成JS文件,组件需要导入导出.本篇就体验使用Gulp把JSX文件转换成JS文件,使用Browserify来把组件捆绑到一个文件并理顺组件之间的 ...

  10. 使用Gulp和Browserify创建多个绑定文件

    Browserify是一个Javascript的绑定工具,帮助我们理顺module之间的依赖关系.Gulp用来优化workflow.两者的共同点都是使用流,但在使用流方面也有不同之处: Browser ...

随机推荐

  1. Windows 7系统安装MySQL5.5.21图解

    Win7系统安装MySQL5.5.21图解 大家都知道MySQL是一款中.小型关系型数据库管理系统,非常具有有用性,对于我们学习非常多技术都有帮助,前几天我分别装了SQL Server 2008和Or ...

  2. android146 360 病毒查杀

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  3. Percona-Galera-Monitoring-Template监控模板说明

    http://blog.chinaunix.net/uid-16844903-id-4054635.html 官网链接:http://www.percona.com/doc/percona-monit ...

  4. C 高级编程 1

    内存管理层次: 硬件层次: 内存结构管理 内核算层次: 内存映射 堆扩展 数据结构层次: 智能指针: stl :在多线程,共享内存有问题 SGI公司实现了STL ,开发了OPENGL库 语言层次:C: ...

  5. 网络IPC:套接字之带外数据

    带外数据(Out-of-band data)是一些通信协议所支持的可选特征,允许更高优先级的数据比普通数据优先传输.即使传输队列已经有数据,带外数据先行传输.TCP支持带外数据,但是UDP不支持.套接 ...

  6. NopCommerce 数据库初始化

    NopCommerce数据库初始化比较复杂,我简化了,只初始化创建一张表,不多说,直接上代码: //数据实体 /// <summary> /// Represents an affilia ...

  7. html/css 两个div在同一行

    在界面设计的时候,经常需要将两个div在同一行显示. 但是每次都会忘记怎么做,特此随笔,备忘. 如以下要将“第一个div”和“第二个div”显示在同一行: <div id="id1&q ...

  8. [辛酸历程]在Mac中使用Python获取屏幕截图

    一.起因 最近想做个小外挂玩玩,技术倒是不难,就是通过图片匹配加上一些判断方法来刷分.但是在最不起眼(却最容易出问题)的准备阶段卡住了. 为什么卡住了呢,简单说,因为我需要获取截屏的数据,所以就要找一 ...

  9. [设计模式]<<设计模式之禅>>关于单例模式

     1 我是皇帝我独苗 自从秦始皇确立了皇帝这个位置以后,同一时期基本上就只有一个人孤零零地坐在这个位置.这种情况下臣民们也好处理,大家叩拜.谈论的时候只要提及皇帝,每个人都知道指的是谁,而不用在皇帝前 ...

  10. [需再总结]SSH整合代码生成器

    package cn.itcast.invoice.util.generator; import java.io.BufferedWriter; import java.io.File; import ...