browserify
Advanced tools
Comparing version 0.0.5 to 0.1.0
269
index.js
var fs = require('fs'); | ||
var path = require('path'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var find = require('findit'); | ||
var npm = require('npm'); | ||
var coffee = require('coffee-script'); | ||
var source = require('source'); | ||
exports = module.exports = function (opts) { | ||
if (typeof opts === 'string') { | ||
opts = { base : opts }; | ||
var opts_ = arguments[1]; | ||
if (typeof opts_ === 'object') { | ||
Object.keys(opts_).forEach(function (key) { | ||
opts[key] = opts_[key]; | ||
}); | ||
} | ||
} | ||
var modified = new Date(); | ||
var src = exports.bundle(opts); | ||
if (!opts.mount) opts.mount = '/browserify.js'; | ||
var src | ||
= Object.keys(builtins).map(function (key) { | ||
return wrapScript(null, key, builtins[key]) | ||
}).join('\n') | ||
+ (opts.base ? find.sync(opts.base) : []) | ||
.filter(function (file) { | ||
return file.match(/\.js$/) || file.match(/\.coffee$/) | ||
}) | ||
.map(function (file) { | ||
var body = fs.readFileSync(file, 'utf8'); | ||
if (file.match(/\.coffee$/)) { | ||
return wrapScript( | ||
opts.base, file.replace(/\.coffee$/,''), | ||
coffee.compile(body) | ||
); | ||
} | ||
else { | ||
return wrapScript(opts.base, file, body); | ||
} | ||
}) | ||
.join('\n') | ||
; | ||
if (opts.filter) { | ||
src = opts.filter(src); | ||
} | ||
npm.load(function () { | ||
// async middleware is hard >_< | ||
var included = {}; | ||
(opts.require || []).concat('es5-shim') | ||
.forEach(function npmWrap (name) { | ||
included[name] = true; | ||
// this part mostly lifted from npm/lib/explore.js | ||
var nv = name.split('@'); | ||
var n = nv[0], v = nv[1] || 'active'; | ||
var dir = path.join(npm.dir, n, v, 'package') | ||
fs.stat(dir, function (err, stat) { | ||
if (err || !stat.isDirectory()) { | ||
console.error("It doesn't look like " | ||
+ name + ' is installed.' | ||
); | ||
} | ||
else { | ||
var pkg = wrapPackage(name, dir); | ||
pkg.on('package.json', function (json) { | ||
if (typeof json.dependencies === 'object') { | ||
Object.keys(json.dependencies) | ||
.forEach(function (n) { | ||
if (!included[n]) npmWrap(n); | ||
}) | ||
; | ||
} | ||
}); | ||
pkg.on('module', function (modSrc) { | ||
var minSrc = opts.filter ? opts.filter(modSrc) : modSrc; | ||
if (name === 'es5-shim') { | ||
preSrc += minSrc + '\nrequire("es5-shim");\n'; | ||
} | ||
else { | ||
src += minSrc; | ||
} | ||
}); | ||
} | ||
}); | ||
}); | ||
}); | ||
var modified = new Date(); | ||
var preSrc = (opts.filter || String)( | ||
wrappers.prelude + wrappers.node_compat | ||
); | ||
return function (req, res, next) { | ||
@@ -104,3 +19,2 @@ if (req.url.split('?')[0] === opts.mount) { | ||
}); | ||
res.write(preSrc); | ||
res.end(src); | ||
@@ -110,89 +24,116 @@ } | ||
}; | ||
} | ||
}; | ||
var wrappers = [ 'prelude', 'body', 'node_compat' ] | ||
.reduce(function (acc, name) { | ||
acc[name] = fs.readFileSync( | ||
__dirname + '/wrappers/' + name + '.js', 'utf8' | ||
); | ||
return acc; | ||
}, {}) | ||
; | ||
var builtins = fs.readdirSync(__dirname + '/builtins/') | ||
.reduce(function (acc, file) { | ||
if (file.match(/\.js/)) { | ||
acc[file.replace(/\.js$/,'')] = | ||
fs.readFileSync(__dirname + '/builtins/' + file, 'utf8'); | ||
exports.bundle = function (opts) { | ||
if (typeof opts === 'string') { | ||
opts = { base : opts }; | ||
var opts_ = arguments[1]; | ||
if (typeof opts_ === 'object') { | ||
Object.keys(opts_).forEach(function (key) { | ||
opts[key] = opts_[key]; | ||
}); | ||
} | ||
return acc; | ||
}, {}) | ||
; | ||
exports.wrapScript = wrapScript; | ||
function wrapScript (base, filename, src) { | ||
var rel = filename; | ||
if (base) { | ||
var bs = base.split('/'); | ||
var rs = filename.split('/'); | ||
for (var i = 0; i < bs.length && i < rs.length && bs[i] === rs[i]; i++); | ||
rel = './' + rs.slice(i).join('/').replace(/^\.(?:\/|$)/,''); | ||
} | ||
return wrappers.body | ||
.replace('$body', src) | ||
.replace(/\$filename/g, JSON.stringify(rel)) | ||
var shim = 'shim' in opts ? opts.shim : true; | ||
var req = opts.require || []; | ||
if (!Array.isArray(req)) req = [req]; | ||
return fs.readFileSync(__dirname + '/wrappers/prelude.js', 'utf8') | ||
+ fs.readFileSync(__dirname + '/wrappers/node_compat.js', 'utf8') | ||
+ (shim ? source.modules('es5-shim')['es5-shim'] : '') | ||
+ wrapperBody | ||
.replace('$body', | ||
fs.readFileSync(__dirname + '/builtins/events.js', 'utf8') | ||
) | ||
.replace(/\$filename/g, '"events"') | ||
+ (req.length ? exports.wrap(req).source : '') | ||
+ (opts.base ? exports.wrapDir(opts.base) : '') | ||
; | ||
} | ||
}; | ||
exports.wrapPackage = wrapPackage; | ||
function wrapPackage (name, dir) { | ||
var em = new EventEmitter; | ||
var wrapperBody = fs.readFileSync(__dirname + '/wrappers/body.js', 'utf8'); | ||
exports.wrap = function (libname, opts) { | ||
if (!opts) opts = {}; | ||
fs.readFile(dir + '/package.json', 'utf8', function (err, body) { | ||
if (err) { em.emit('error', err); return } | ||
if (Array.isArray(libname)) { | ||
var reqs = opts.required || []; | ||
function wrap (p, n) { | ||
var file = require.resolve(dir + '/' + p); | ||
em.emit('module', wrapScript( | ||
null, n, fs.readFileSync(file, 'utf8')) | ||
); | ||
} | ||
try { | ||
var pkg = JSON.parse(body); | ||
} | ||
catch (err) { | ||
if (err instanceof SyntaxError) { | ||
console.error( | ||
'Syntax error in the package.json for ' | ||
+ JSON.stringify(name) | ||
); | ||
var src = libname.map(function (name) { | ||
var lib = exports.wrap(name, { required : reqs }); | ||
reqs.push(name); | ||
var pkg = lib['package.json']; | ||
if (pkg && pkg.dependencies) { | ||
var deps = Object.keys(pkg.dependencies); | ||
var s = exports.wrap(deps, { required : reqs }).source; | ||
reqs.push.apply(reqs, deps); | ||
return lib.source + '\n' + s; | ||
} | ||
throw err; | ||
} | ||
else { | ||
return lib.source; | ||
} | ||
}).join('\n'); | ||
em.emit('package.json', pkg); | ||
if (pkg.main) wrap(pkg.main, name) | ||
return { source : src }; | ||
} | ||
else if (opts.required && opts.required.indexOf(libname) >= 0) { | ||
return { source : '' }; | ||
} | ||
else if (libname.match(/^[.\/]/)) { | ||
var src = fs.readFileSync(opts.filename || libname, 'utf8'); | ||
var body = (opts.filename || libname).match(/\.coffee$/) | ||
? coffee.compile(src) : src | ||
; | ||
if (pkg.modules) { | ||
Object.keys(pkg.modules).forEach(function (n) { | ||
wrap( | ||
pkg.modules[n], | ||
n === 'index' ? name : name + '/' + n | ||
) | ||
}) | ||
} | ||
return { | ||
source : wrapperBody | ||
.replace('$body', body) | ||
.replace(/\$filename/g, JSON.stringify(libname)) | ||
, | ||
}; | ||
} | ||
else { | ||
var mods = source.modules(libname); | ||
var pkg = mods[libname + '/package.json']; | ||
if (pkg.directory && pkg.directory.lib) { | ||
fs.readdir(pkg.directory.lib, function (err, files) { | ||
if (err) em.emit('error', err) | ||
else files.forEach(function (file) { | ||
wrap(file, name + '/' + file) | ||
return { | ||
'package.json' : pkg, | ||
source : Object.keys(mods) | ||
.filter(function (name) { | ||
return !name.match(/\/package\.json$/) | ||
}) | ||
.map(function (name) { | ||
return wrapperBody | ||
.replace('$body', mods[name]) | ||
.replace(/\$filename/g, JSON.stringify(name)) | ||
; | ||
}) | ||
.join('\n') | ||
, | ||
}; | ||
} | ||
}; | ||
var find = require('findit'); | ||
exports.wrapDir = function (base) { | ||
if (Array.isArray(base)) { | ||
return base.map(exports.wrapDir).join('\n'); | ||
} | ||
else { | ||
return find.sync(base) | ||
.filter(function (file) { | ||
return file.match(/\.(?:js|coffee)$/) | ||
}) | ||
} | ||
}); | ||
return em; | ||
} | ||
.map(function (file) { | ||
return exports.wrap( | ||
'.' + file.slice(base.length) | ||
.replace(/\.(?:js|coffee)$/,'') | ||
, { filename : file } | ||
).source; | ||
}) | ||
.join('\n') | ||
; | ||
} | ||
}; |
{ | ||
"name" : "browserify", | ||
"version" : "0.0.5", | ||
"version" : "0.1.0", | ||
"description" : "Browser-side require() for js directories and npm modules", | ||
"main" : "./index.js", | ||
"directories" : { | ||
"example" : "./examples" | ||
}, | ||
"repository" : { | ||
@@ -18,6 +21,10 @@ "type" : "git", | ||
"findit" : ">=0.0.1", | ||
"npm" : ">=0.2.16", | ||
"source" : ">=0.0.1", | ||
"es5-shim" : ">=1.0.0", | ||
"coffee-script" : ">=1.0.0" | ||
}, | ||
"devDependencies" : { | ||
"expresso" : ">=0.6.0", | ||
"seq" : ">=0.1.8" | ||
}, | ||
"author" : { | ||
@@ -28,4 +35,7 @@ "name" : "James Halliday", | ||
}, | ||
"scripts" : { | ||
"test" : "expresso" | ||
}, | ||
"license" : "MIT/X11", | ||
"engine" : ["node >=0.3.0"] | ||
"engine" : ["node >=0.4.0"] | ||
} |
@@ -101,16 +101,13 @@ Browserify | ||
<head> | ||
<script type="text/javascript" src="/browserify.js"></script> | ||
<script type="text/javascript" src="/browserify.js?traverse"></script> | ||
<script type="text/javascript"> | ||
var Traverse = require('traverse'); | ||
var obj = [ 5, 6, -3, [ 7, 8, -2, 1 ], { f : 10, g : -13 } ]; | ||
var fixed = Traverse(obj) | ||
.modify(function (x) { | ||
if (x < 0) this.update(x + 128); | ||
}) | ||
.get() | ||
; | ||
Traverse(obj).forEach(function (x) { | ||
if (x < 0) this.update(x + 128); | ||
}); | ||
window.onload = function () { | ||
document.getElementById('result').innerHTML | ||
= JSON.stringify(fixed); | ||
= JSON.stringify(obj); | ||
}; | ||
@@ -124,1 +121,26 @@ </script> | ||
</html> | ||
methods | ||
======= | ||
var browserify = require('browserify'); | ||
browserify(opts) | ||
---------------- | ||
Return a middleware that will host up a browserified script at `opts.mount` or | ||
`"/browserify.js"` if unspecified. All other options are passed to | ||
`browserify.bundle(opts)` to generate the source. | ||
browserify.bundle(opts) | ||
----------------------- | ||
Return a string with the bundled source code given the options in `opts`: | ||
* base : recursively bundle all `.js` and `.coffee` files in this directory or | ||
Array of directories | ||
* shim : whether to include [es5-shim](https://github.com/kriskowal/es5-shim) | ||
for legacy javascript engines; true if unspecified | ||
* require : bundle all of these module names and their dependencies |
function require (path) { | ||
// not EXACTLY like how node does it but more appropriate for the browser | ||
var mod = [ | ||
require.modules[path], | ||
require.modules[path + '.js'], | ||
require.modules[path + '/index.js'], | ||
].filter(Boolean)[0]; | ||
var mod | ||
= require.modules[path] | ||
|| require.modules[path + '.js'] | ||
|| require.modules[path + '/index.js'] | ||
; | ||
@@ -9,0 +9,0 @@ if (!mod) throw new Error("Cannot find module '" + path + "'"); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
23990
28
502
145
2
2
2
+ Addedsource@>=0.0.1
+ Addedsource@0.0.3(transitive)
- Removednpm@>=0.2.16
- Removednpm@10.9.0(transitive)