将 npm 模块注册成 bower 模块

npm是node的包管理系统,通过package.json声明模块间的依赖关系。然而node采用CommonJS规范组织的模块在浏览器中无法直接使用。bower是前端资源的包管理系统,通过bower.json来组织js、css和图标资源。bower管理的js包,一般采用全局变量模式,或者requirejs推崇的AMD规范,亦或UMD。

UMD(通用模块定义)

由于现行的javascript版本中,没有原生的依赖管理实现,而随着前端和Nodejs的越来越流行,javascript的代码量越来越大,于是对依赖管理和包管理的需求越来越高,于是社区就出现了CommonJS和AMD两大依赖管理的阵营。目前CommonJS规范是Nodejs的内置支持,主要用于后端js。AMD被requirejs支持,是一种前端依赖管理的选择。

全局变量

// MyDependency is in your global scope
var MyModule = function() {};

CommonJS,Nodejs支持的规范

var MyDependency = require('my-dependency');
module.exports = function() {};

AMDrequirejs 支持的规范

define(['my-dependency'], function(MyDependency) {
  return function() {};
});

UMD,兼容所有规范

(function (root, factory) {
  if (typeof exports === 'object') {
    // CommonJS
    module.exports = factory(require('b'));
  } else if (typeof define === 'function' && define.amd) {
    // AMD
    define(['b'], function (b) {
      return (root.returnExportsGlobal = factory(b));
    });
  } else {
    // Global Variables
    root.returnExportsGlobal = factory(root.b);
  }
}(this, function (b) {
  // Your actual module
  return {};
}));

Browserify

一个npm package项目,如果想同时兼容bower,可以通过 Browserify 生成支持浏览器端的package。

npm install -g browserify

CommonJS

假设有如下main.js

var unique = require('uniq');

var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];

console.log(unique(data));

使用 npm 安装依赖包uniq

npm install uniq

通过browserify命令将其转换成bundle.js

browserify main.js -o bundle.js

browserify会将所有require()依赖的文件都合并进bundle.js文件。然后通过<script/>引入。

<script src="bundle.js"></script>

AMD

安装deamdify模块 Browserify 可以转换AMD规范的JS模块。

npm install deamdify
browserify -t deamdify main.js -o bundle.js

全局变量

安装deglobalify模块 Browserify 可以转换全局变量风格的JS模块。

npm install deglobalify
browserify -t deglobalify main.js -o bundle.js

ES6

安装es6ify模块 Browserify 可以转换ES6规范的JS模块。

npm install es6ify
browserify -t es6ify main.js -o bundle.js

支持所有规范

browserify 支持一次装载多个转换器。

npm install deamdify es6ify deglobalify
browserify -t deamdify -t es6ify -t deglobalify main.js -o bundle.js

与grunt集成

借助grunt可以把转换集成到构建过程中,方便使用。

npm install grunt-browserify

Gruntfile.js

module.exports = function (grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    browserify : {
      app : {
        files : { 'dist/index.js' : ['index.js'] }
      }
    }
  })
}

注册成bower模块

$ bower init

交互模式下生成如下bower.json文件,注意main属性设置成browserify生成的文件dist/index.js

{
  "name": "module_name",
  "main": "dist/index.js",
  "version": "0.1.1",
  ...
}

将项目上传到Github,如后执行

$ bower register module_name git://github.com/user/module_name.git

bower register只需要执行一次,今后发布新版本只需要向Github仓库推送符合semver 规范的Git tags 即可。

参考阅读

  1. Building Javascript with Grunt, Bower, Browserify
  2. Creating packages
  3. Bower vs Browserify
  4. Browserify and the Universal Module Definition