使用browserify进行JavaScript模块管理
April 12 2015

前言

前一段日子在使用了RequireJS之后觉得模块化开始实在太爽,它使用AMD语句,将整个模块包再一个define中然后以return value的形式提供接口。像这样:

define(['jquery'], function($) {
	var Sth = function(elem) {
		this.elem = $(elem);
		...
	};
	Sth.prototype = {
		init: function() {
		},
		setHeight: function() {
		},
		...
	};
	return Sth;
});

但是使用过程中也遇到了几点不爽:

define([
	'jquery',
	'underscore',
	'backbone',
	'main/nav',
	'main/gallery',
	'main/spotlight',
	'main/somethingelse'
], function(
	$,
	_,
	Backbone,
	Gallery,
	Spotlight,
	Somethingelse
) {
	var App = function(){};
	return App;
});

Browserify

几天前我花了一段时间把company page的模块全部更换成了Browserify的模式,可以让我以node.js的风格在浏览器写代码了。一个直接的好处就是,代码更短了,而且更容易维护。这篇文章介绍了很多其他好处。Browserify的官方网站也提供一系列文章教程。上面的代码使用Browserify会变成如下:

var Sth = function(elem) {
	this.elem = $(elem);
	...
};
Sth.prototype = {
	init: function() {
	},
	setHeight: function() {
	},
	...
};
module.exports = Sth;

使用Gulp构建

我一直使用Gulp来构建项目中的LESS和JavaScript文件。名叫gulp-browserify的插件由于“直接使用来自browserify模块”被加入了Gulp的黑名单这篇文章提供了直接用browserify在Gulp中构建的解决办法,需要安装browserifyvinyl-source-stream。代码如下:

var gulp = require('gulp'),
	browserify = require('browserify'),
	source = require('vinyl-source-stream');
 
gulp.task('browserify', function() {
    return browserify('./src/js/main.js',{ debug: true })
        .bundle()
        .pipe(source('main-built.js'))
        .pipe(gulp.dest('./temp/js'));
});

...

我会先用browserify构建一个暂未压缩的js文件放到/temp中,以便排错,然后再用uglify压缩生成到/public文件中。

全局依赖

对于全局依赖的模块,比如jQuery,Browserify没有提供RequireJS中类似”shim”的东西。一个最直接的做法是在main.js中定义

window.$ = require('./path-to-jquery/jquery.js');

这个项目有一个模块使用jQuery-ui插件,这个插件依赖于jQuery,这时再定义

window.$.mobile = require('./path-to-jquery-ui/jquery-ui.js');

是完全没用的,只能使用browserify-shim这个插件做一些配置,这让我非常不爽。我对于这些第三方插件的质量表示怀疑,因此对于使用比较抗拒。好在我用jquery-ui的唯一目的是使用swipe事件,后来直接使用Hammer.js,它提供CommonJS的接口可以直接使用。对于全局依赖的问题,这篇文章也给出了一种解决方案。 ```

总体来说,从RequireJS转换到Browserify的过程很成功,效果也很好,暂时会作为前端开发的主力方案使用。

资料

  1. Almond.js
  2. A Journey from requirejs to browerify
  3. Browserify articles
  4. browserify-shim
  5. gulp-blacklist
  6. gulp browserify starter faq
  7. gulp-uglify
  8. Hammer.js
  9. Journey From RequireJS to Browserify

Currently

Software Engineer at Yahoo!

Previously

Full Stack Engineer at Prosper Marketplace

Previously

Front End Engineer at BillGuard (Acquired by Prosper)