GithubHelp home page GithubHelp logo

kgryte / browser-pack-flat Goto Github PK

View Code? Open in Web Editor NEW

This project forked from goto-bus-stop/browser-pack-flat

0.0 3.0 0.0 167 KB

bundle browserify modules into a single scope, a la rollup

License: MIT License

JavaScript 100.00%

browser-pack-flat's Introduction

browser-pack-flat

Bundle browserify modules into a single scope, a la rollup.

Caveats:

  • This rewrites require() calls to simple variable assignments. If a module wraps require() somehow it probably will not work. In practice this is quite rare.
  • Using factor-bundle to split output code into separate files will not work with this plugin.

Install

npm install --save-dev browser-pack-flat

Usage

browserify /path/to/app.js | browser-unpack | browser-pack-flat

Or as a plugin:

browserify /path/to/app.js -p browser-pack-flat/plugin

The plugin replaces the browser-pack module used by default by browserify.

With the Node API:

var browserify = require('browserify')
var packFlat = require('browser-pack-flat/plugin')

browserify({ entries: './src/app.js' })
  .plugin(packFlat, { /* options */ })
  .bundle()
  .pipe(fs.createWriteStream('bundle.js'))

What exactly?

browserify uses browser-pack to output a bundle. browser-pack uses a small require-like runtime and wraps modules in functions to get a module loading behaviour that's almost identical to Node.js. However this resolution can take a few milliseconds across an entire bundle.

Input:

var unique = require('uniq');

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

console.log(unique(data));

With browser-pack, this bundle would output:

(function 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){
var unique = require('uniq');

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

console.log(unique(data));
},{"uniq":2}],2:[function(require,module,exports){
"use strict"

/* -- snip -- */

function unique(list, compare, sorted) {
  if(list.length === 0) {
    return list
  }
  if(compare) {
    if(!sorted) {
      list.sort(compare)
    }
    return unique_pred(list, compare)
  }
  if(!sorted) {
    list.sort()
  }
  return unique_eq(list)
}

module.exports = unique

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

browser-pack-flat instead rewrites require() calls and module.exports assignments to simple variables, and sorts the modules so that the module that would be executed first, is at the top of the bundle. It doesn't need a runtime in most cases, and no function calls to execute modules.

(function(){
"use strict"

/* -- snip -- */

function unique(list, compare, sorted) {
  if(list.length === 0) {
    return list
  }
  if(compare) {
    if(!sorted) {
      list.sort(compare)
    }
    return unique_pred(list, compare)
  }
  if(!sorted) {
    list.sort()
  }
  return unique_eq(list)
}

var _$unique_2 = unique

var _$main_1 = {};
/* removed: var _$unique_2 = require('uniq'); */;

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

console.log(_$unique_2(data));
}());

Instead of require('uniq'), the main module simply refers to _$unique_2, which is the exports value of the uniq module. The only function wrapper is the outermost one, which prevents variables from leaking into the window (global scope).

Sometimes it's not possible to sort modules in their execution order, because in the Node.js module system, a module can require another module that requires the first module: a circular dependency. browser-pack-flat addresses this with a small runtime, to lazily execute modules that are part of a circular dependency chain. This works similarly to how the Node.js module system works, and to how the standard browser-pack works too. Instead of rewriting require()s to variables and module.exports to a variable assignment, in "circular modules" browser-pack-flat adds a function wrapper. When a circular module is require()d, browser-pack-flat will call the function wrapper, which executes the module and caches the exports.

Below, a.js depends on b.js, and b.js depends on a.js:

// app.js
console.log(
  require('./a')()
)
// a.js
var b = require('./b')
module.exports = function () {
  return b()
}
// b.js
module.exports = function () {
  return require('./a').toString()
}

With browser-pack-flat, this becomes:

(function(){
var _$cycle = function r(r){var t;return function(){return t||r(t={exports:{}},t.exports),t.exports}};
var _$a_1 = _$cycle(function (module, exports) {
var b = _$b_3()
module.exports = function () {
  return b()
}

});
var _$b_3 = _$cycle(function (module, exports) {
module.exports = function () {
  return _$a_1().toString()
}

});
var _$app_2 = {};
console.log(
  _$a_1()()
)

}());

The _$cycle helper returns the exports of the module it wraps, evaluating the module on the first call. Instead of replacing require('./a') with _$a_1 like browser-pack-flat normally would, it replaced it with _$a_1().

browser-pack-flat does some more things like rewriting top-level variables in modules in case there is another variable with the same name in another module, but that's most of the magic!

Related

License

MIT

browser-pack-flat's People

Contributors

goto-bus-stop avatar kgryte avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.