[关闭]
@bornkiller 2015-04-16T13:42:20.000000Z 字数 2833 阅读 2638

Browerify简易入门指南

nodejs


简介

browerify: http://browserify.org/index.html

browserify可以看做浏览器端的又一个模块化工具,在ES6模块规范在前端大规模落地之前更优雅的选择。

简要说明

browserfify长处在于使用node-flavor模块规范,而不是requirejs使用的AMD模块规范,以及seajs使用的CMD模块规范。打包处理后一般单页面仅为一个js文件(当然,文件size相当可观)。相对于其他规范,最直接的好处是可以直接使用Node生态中前后端功用模块,例如uniq, underscore等不依赖Node环境的包,以及superagent这种做过浏览器适配的包。

简单使用

关于命令行工具使用,请参照官方文档。在使用中,因为使用webstorm,使用watch的话,每次自动保存都会自动触发,加重系统无谓的负担,所以在开发中,可以选择直接调用API的方式,如下使用koa作为简单的server,部分代码如下:

  1. "use strict";
  2. var util = require('util');
  3. var through = require('through-gulp');
  4. function streamToPromise(stream) {
  5. if (util.isUndefined(stream.pipe)) return Promise.reject('argument is not stream');
  6. return new Promise(function(resolve, reject) {
  7. var destiny = new Buffer('');
  8. stream.pipe(through(function(data, encoding, callback) {
  9. destiny = Buffer.concat([destiny, data]);
  10. callback();
  11. }, function(callback) {
  12. resolve(destiny);
  13. callback();
  14. }))
  15. });
  16. }
  17. module.exports = streamToPromise;

此处代码将stream转换为promise

  1. var transform = require('./promise-stream');
  2. app.use(function *(next) {
  3. if (this.path.startsWith('/browserify')) {
  4. var bundle = browserify(path.join(__dirname, 'static', this.path)).bundle();
  5. bundle = yield transform(bundle);
  6. this.type = "application/javascript";
  7. this.body = bundle.toString();
  8. return null;
  9. }
  10. yield next;
  11. });

此处代码,将browserify文件夹内部的js文件,都是用browserify处理,返回处理后的数据。如果依赖文件较大的话,时间会比较长,视具体环境而定。

相同模块重复依赖

模块重复依赖很容易理解,模块实现时可能分割为多个子文件实现,每个子文件内部可能会引用同一个模块,如util。在node环境下很好理解,在browserify处理后的浏览器环境下,该模块可以看做是个单例,不同文件内部引用的同名模块,可以看做引用的同一个变量,简单示例所有文件均放置于browserify文件夹下,代码如下:

  1. // core.js
  2. var utils = { "age" : 12 };
  3. utils.increase = function() {
  4. this.age += 1;
  5. };
  6. module.exports = utils;
  1. // repeat.js
  2. var repeat = require('./core');
  3. module.exports = repeat;
  1. // pristine.js
  2. var pristine = require('./core');
  3. module.exports = pristine;
  1. // index.js
  2. var first = require('./pristine');
  3. var second = require('./repeat');
  4. first.increase();
  5. second.increase();
  6. console.log(first);
  7. console.log(second);

浏览器执行,输出结果result.age均为14,和预想结果匹配。

Karma集成测试

需要用到文件预处理器,karma-browserify: https://www.npmjs.com/package/karma-browserify

karmaAMD模块测试文件组织结构与引入不同,AMD将测试文件以模块方式定义,配置中将待测试文件,测试文件设置为served,然后由单一入口文件加载测试文件。使用browserify作为模块化工具时,需要显式引入测试文件,配合karma-browerify使用,示例如下:

  1. // ./browserify/utils.js
  2. var uniq = require('uniq');
  3. var utils = {};
  4. utils.uniq = uniq;
  5. utils.sum = function(value) {
  6. return value.reduce(function(prev, next) {
  7. return prev + next;
  8. }, 0);
  9. };
  10. module.exports = utils;
  1. // ./browserify_test/utils.spec.js
  2. var utils = require('../browserify/utils');
  3. describe('browserify style module', function () {
  4. it('should uniq array with repeat value', function () {
  5. var source = [1, 2, 3, 2, 3, 4];
  6. expect(utils.uniq(source)).toEqual([1, 2, 3, 4]);
  7. });
  8. it('should sum array with number value', function () {
  9. var source = [1, 2, 3, 4];
  10. expect(utils.sum(source)).toEqual(10);
  11. });
  12. });

详情移步https://github.com/bornkiller/ModuleBoilerplate
注意如果使用webstorm,会出现https://github.com/nikku/karma-browserify/issues/23 BUG,修改测试文件,如果不重启karma server的话,测试文件内容不会改变。

后记

学习使用React的过程中,因为React ES-forward的代码风格,略显不适应,所以选择先学习使用browserify工具,然后延续React学习过程。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注