eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNxdWFyZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLEVBQUU7QUFDNUIsU0FBTyxDQUFDLEdBQUMsQ0FBQyxDQUFDO0NBQ1osQ0FBQSIsImZpbGUiOiJzcXVhcmUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXh

发布时间:2019-08-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNxdWFyZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLEVBQUU7QUFDNUIsU0FBTyxDQUFDLEdBQUMsQ0FBQyxDQUFDO0NBQ1osQ0FBQSIsImZpbGUiOiJzcXVhcmUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXh脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

欢迎到个人博客去看看: 戳着里

0. browserify是什么

  • browserify是目前比较流行的模块打包工具之一(另外一个webpack)

  • 基于流式(stream)思想设计

  • 可以通过command line,也可以通过API来使用

  • 仅处理javascript

  • 模块化的逆过程,但是推动着模块化的更好发展

  • 内置了一些node core module

  • node模块可以在浏览器端使用,是同构应用的有力武器

1. 从demo说起

存在两个js: square.js、foo.js

// square.js
module.exports = function (a) {
  return a*a;
}
@H_126_62@
// foo.js
VAR sq = require('./square');
console.LOG(sq(2));

接着通过API进行打包:

var browserify = require('../node-browserify');
var fs = require('fs');

var b = browserify(['./foo.js']);

b.require('./square.js', {
 expose: 'square'
})

b.bundle().piPE(fs.createWritestream('./bundle.js'));

得到一个可以在浏览器端使用的bundle.js:

(function @H_360_136@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){
'use strict';

var sq = require('./square');
console.log(sq(2));

},{"./square":2}],2:[function(require,module,exports){
"use strict";

module.exports = function (a) {
  return a * a;
};

},{}]},{},[1]);

接下来分析browserify是如何做到的。

2. 总体设计

eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNxdWFyZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLEVBQUU7QUFDNUIsU0FBTyxDQUFDLEdBQUMsQ0FBQyxDQUFDO0NBQ1osQ0FBQSIsImZpbGUiOiJzcXVhcmUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXh

3. 具体分析

3.1 输入(input)

browserfiy的输入内容整体上分为两类:file、transform function。file就是需要打包的文件,transform function用于对输入的file内容进行处理。例如:我们需要对coffeeScript文件进行打包,那么打包之前就需要将coffeeScript文件转换成javascript,然后才能进行打包。

那么输入的接口都有哪些呢:

  • b = new Browserify(file, opts): 在实例化的时候,将相关内容输入进去

  • b.require(file, opts): 指定可以在浏览器端require的文件

  • b.add(file, opts):实例化时未指定参数的情况下,可以使用该接口

  • b.external/exclude/ignore: 一些file的特殊配置

  • b.transform(tr, opts): 指定transform function,用于对module进行转换

3.2 处理

b.pipeline是browserify里面的核心对象。通过这个对象,可以对module进行一系列的处理,这个对象具有如下特点:

  • labeled-stream-splicer生成

  • 整合了很多transform stream后,生成一个整体transform stream

  • 带有label,通过label访问内部具体的transform stream

  • wrITe进去的chunk分两种情况:带有file的对象,带有transform function的对象

伪代码:

// 创建pipeline
Browserify.PRototype._createPipeline = function (opts) {
  ...
  var pipeline = splicer.obj([
    'record', [ this._recorder() ],
    'deps', [ this._mdeps ],
    'json', [ this._json() ],
    'unbom', [ this._unbom() ],
    'unshebang', [ this._unshebang() ],
    'syntax', [ this._syntax() ],
    'sort', [ depsSort(dopts) ],
    'dedupe', [ this._dedupe() ],
    'label', [ this._label(opts) ],
    'emit-deps', [ this._emitDeps() ],
    'debug', [ this._debug(opts) ],
    'pack', [ this._bpack ],
    'wrap', []
  ]);
  ...
  return pipeline;
}

// pipeline write进去的chunk
Browserify.prototype.transform = function (tr, opts) {
  ...
  var rec = {
    transform: tr,
    options: opts,
    global: opts.global
  };
  // 带有transform function的对象
  this.pipeline.write(transform);
  ...
}

Browserify.prototype.require = function (file, opts) {
  ...
  var rec = {
    source: buf.toString('utf8'),
    entry: defined(opts.entry, false),
    file: filename,
    id: id
  };
  // 带有file的对象
  this.pipeline.write(rec);
}

接下来针对其中关键的deps、pack进行分析。

3.3 模块依赖的解析

面对的问题:

  • 在模块合并前,首先要做的工作就是找出入口文件(entry file)的依赖以及依赖的依赖,例如在charpter1的demo中,入口文件foo.js仅依赖square.js

  • 考虑要对代码进行转换

browserify通过module-deps来解决上述问题,通过下面的代码可以看到解析的结果:

var browserify = require('../node-browserify');
var fs = require('fs');

var b = browserify(['./foo.js'], {
  debug: true,
  basedir: './'
});
b.require('./square.js', {
  expose: 'square'
})
b.on('dep', function (row) {
  console.log(row);
})

b.bundle().pipe(fs.createWriteStream('./bundle.js'));

输出的JSON结果为:

{
  "entry":true,
  "expose":false,
  "basedir":"./",
  "file":"/Users/lizhenhua/Documents/france/z-react/foo.js",
  "id":1,
  "order":0,
  "source":"'use strict';nnvar sq = require('./square');nconsole.log(sq(2));n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3Vyy2VzIjpbImZvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUM3QixPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDIiwiZMLsZSI6ImZvby5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBzcSA9IHJlcXVpcmUoJy4vc3F1YXJlJyk7XG5jb25zb2xlLmxvZyhzcSgyKSk7XG4iXX0=",
  "deps":{
    "./square":2
  },
  "index":1,
  "indexDeps":{
    "./square":2
  }
}

{
  "id":2,
  "source":""use strict"";nnmodule.exports = function (a) {n  return a * a;n};n//# sourceMappingURL=data:application/json;base64

脚本宝典总结

以上是脚本宝典为你收集整理的eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNxdWFyZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLEVBQUU7QUFDNUIsU0FBTyxDQUFDLEdBQUMsQ0FBQyxDQUFDO0NBQ1osQ0FBQSIsImZpbGUiOiJzcXVhcmUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXh全部内容,希望文章能够帮你解决eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNxdWFyZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU0sQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLEVBQUU7QUFDNUIsU0FBTyxDQUFDLEdBQUMsQ0FBQyxDQUFDO0NBQ1osQ0FBQSIsImZpbGUiOiJzcXVhcmUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXh所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。