Browserify让你的Javascript游走于前后端
Browserify通过预编译,可以让前端以Nodejs的require方式来组织Javascript模块,从而前端代码可以走进后端,后端通过Browserify同样可以在浏览器里跑NPM模块;
在Nodejs中使用的是Commonjs中定义的模块机制,每个Javascript文件就是一个模块,模块与文件之间是一一对应的关系;模块通过exports来对外提供接口,包括属性和方法,调用者使用require来加载模块并使用模块提供的接口;Browserify作为Nodejs与浏览器之间的桥梁,把Javascript扩展到Nodejs端,并改写NPM模块使浏览器也能使用数量众多的NPM模块,同时Browserify也很好的解决了模块之间的依赖,可以很好的将应用模块及依赖模块打包成一个Javascript文件;
Nodejs对require参数(模块名称)解析规则:如果参数以'/'开头,则模块名表示绝对路径;如果是以'./'开头,则模块名表示调用require方法的文件所在目录的相对路径;如果模块名称不以'/','./','../'开头并且不是Nodejs自带模块,则表示你所安装的模块,即node_modules目录下;所以你的应用所写的模块只要符合Nodejs模块的规范,即可与NPM众多模块一起通过require的方式调用,然后由Browserify编译打包生成你在浏览器里要调用的那个JS文件;
既然走到了Nodejs这里,前端自动化的工具自然少不了,这里推荐的是Gulp(基础介绍: 前端自动化之神器 — Gulp ),后面介绍Browserify在Gulp里的基本做法;
1、Nodejs的模块定义:
1 var Hello=function(){ console.log('Hello,Nodejs!'); } module.exports=Hello;
2、Nodejs的模块调用:
1 var Hello=require('./hello'); 2 Hello();
3、Browserify编译模块:
首先安装Browserify,npm install browserify -g
现在一个小栗子:把Nodejs模块main.js编译为浏览器可加载的Javascript文件index.js
1 browserify ./main.js > ./index.js 2 //或者 3 browserify ./main.js -o ./index.js
那么main.js里也一并打包了其所依赖的模块,保证index.js在浏览器端的顺利运行;
4、模块的package.json:
在模块所在根目录添加package.json或npm init生成,可更方便的定义深层模块的名:
1 { 2 'name':'mode', 3 'main':'./lib/mode/mode.min.js' 4 }
main属性指定了模块的入口文件,这样,通过require('./mode')来加载模块时,会定位到目录下的./lib/mode/mode.min.js;
5、package.json的browser属性:
package.json里定义了模块的相关配置信息,browserify扩展了package.json的配置项,通过browser属性,可以指定浏览器环境中的模块入口文件;这样,模块就可以在Nodejs和浏览器端自动切换入口文件了;Javascript可以自由游走于前后端了;
1 { 'name':'mode', 2 'main':'main.js', 3 'browser':'browser_main.js' 4 }
在浏览器端指定要被替换的模块:
1 { 2 'name':'mode', 3 'main':'main.js', 4 'browser':{ 5 'main.js':'browser_main.js' 6 } 7 }
在浏览器端指定要被忽略的模块:
1 { 2 'name':'mode', 3 'main':'main.js', 4 'browser':{ 5 'main.js':false 6 } 7 }
6、通过变换模块brfs读取静态资源:
1 var fs = require('fs'); 2 var html = fs.readFileSync(__dirname + '/example.html', 'utf8');
处理后的文件如下:
1 var fs = require('fs'); 2 var html = "<p>hello,Nodejs!</p>";
还可以读取css、base64图片资源,在此就不弄了,可自行github;
7、独立打包公共模块:
比如:A模块依赖a模块和公共模块c,B模块依赖b模块和公共模块c,可将c模块单独打包;
1 browserify A.js B.js -p [ factor-bundle -o A.js -o B.js ] \ -o c.js
如此,依赖模块会出现在打包后的文件内,而公共模块不会出现在打包后的文件内;
8、在Gulpfile里使用browserify:
Gulp的安装与基础使用: 前端自动化之神器 — Gulp
还是先安装要用到的插件:
1 var gulp=require('gulp'); 2 var watch=require('gulp-watch'); 3 var source = require("vinyl-source-stream"); 4 var streamify=require('gulp-streamify'); 5 var buffer=require('vinyl-buffer');
来个task:
1 gulp.task('browserify',function() { 2 return browserify('./dist/react/testBroswerify.js') 3 .bundle() .pipe(source('test.js')) 4 .pipe(buffer())//.pipe(streamify(uglify())) //压缩耗时间 上线处理 5 .pipe(gulp.dest('./dist/demos')) 6 });
顺便监听下文件变动,实时编译:
1 gulp.task('watch',function() { 3 gulp.watch('./dist/react/testBroswerify.js',['browserify']); 4 });
天色已晚,在此不做详解了,根据项目情况,更多详细任务配置还得由大家自己探索了;
9、前端加油
由于国情和实际项目的差异,可能基于PC端的前端开发还需要BSIE,但是Nodejs带给前端的优秀模块如云,以及前端的自动化进程、像Browserify这样强大的工具,无疑对前端是历史性的变革,用好工具,提高开发效率,大家加油!