新增调试信息
This commit is contained in:
+12
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: npm/browserify
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "10"
|
||||
- "9"
|
||||
- "8"
|
||||
- "6"
|
||||
- "4"
|
||||
- "iojs"
|
||||
- "0.12"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
- "0.6"
|
||||
before_install:
|
||||
# Old npm certs are untrusted https://github.com/npm/npm/issues/20191
|
||||
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ] || [ "${TRAVIS_NODE_VERSION}" = "0.8" ]; then export NPM_CONFIG_STRICT_SSL=false; fi'
|
||||
- 'nvm install-latest-npm'
|
||||
install:
|
||||
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ] || [ "${TRAVIS_NODE_VERSION}" = "0.9" ]; then nvm install --latest-npm 0.8 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;'
|
||||
sudo: false
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- node_js: "0.6"
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2010 James Halliday
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
environment:
|
||||
matrix:
|
||||
- nodejs_version: "10"
|
||||
- nodejs_version: "9"
|
||||
- nodejs_version: "8"
|
||||
- nodejs_version: "6"
|
||||
- nodejs_version: "4"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "0.10"
|
||||
|
||||
# Install scripts. (runs after repo cloning)
|
||||
install:
|
||||
# Get the latest stable version of Node.js or io.js
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
# install modules
|
||||
- npm install
|
||||
|
||||
# Post-install test scripts.
|
||||
test_script:
|
||||
# Output useful info for debugging.
|
||||
- node --version
|
||||
- npm --version
|
||||
# run tests
|
||||
- npm test
|
||||
|
||||
# Don't actually build.
|
||||
build: off
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
+117
@@ -0,0 +1,117 @@
|
||||
Advanced Options:
|
||||
|
||||
--insert-globals, --ig, --fast [default: false]
|
||||
|
||||
Skip detection and always insert definitions for process, global,
|
||||
__filename, and __dirname.
|
||||
|
||||
benefit: faster builds
|
||||
cost: extra bytes
|
||||
|
||||
--insert-global-vars, --igv
|
||||
|
||||
Comma-separated list of global variables to detect and define.
|
||||
Default: __filename,__dirname,process,Buffer,global
|
||||
|
||||
--detect-globals, --dg [default: true]
|
||||
|
||||
Detect the presence of process, global, __filename, and __dirname and define
|
||||
these values when present.
|
||||
|
||||
benefit: npm modules more likely to work
|
||||
cost: slower builds
|
||||
|
||||
--ignore-missing, --im [default: false]
|
||||
|
||||
Ignore `require()` statements that don't resolve to anything.
|
||||
|
||||
--noparse=FILE
|
||||
|
||||
Don't parse FILE at all. This will make bundling much, much faster for giant
|
||||
libs like jquery or threejs.
|
||||
|
||||
--no-builtins
|
||||
|
||||
Turn off builtins. This is handy when you want to run a bundle in node which
|
||||
provides the core builtins.
|
||||
|
||||
--no-commondir
|
||||
|
||||
Turn off setting a commondir. This is useful if you want to preserve the
|
||||
original paths that a bundle was generated with.
|
||||
|
||||
--no-bundle-external
|
||||
|
||||
Turn off bundling of all external modules. This is useful if you only want
|
||||
to bundle your local files.
|
||||
|
||||
--bare
|
||||
|
||||
Alias for both --no-builtins, --no-commondir, and sets --insert-global-vars
|
||||
to just "__filename,__dirname". This is handy if you want to run bundles in
|
||||
node.
|
||||
|
||||
--no-browser-field, --no-bf
|
||||
|
||||
Turn off package.json browser field resolution. This is also handy if you
|
||||
need to run a bundle in node.
|
||||
|
||||
--transform-key
|
||||
|
||||
Instead of the default package.json#browserify#transform field to list
|
||||
all transforms to apply when running browserify, a custom field, like, e.g.
|
||||
package.json#browserify#production or package.json#browserify#staging
|
||||
can be used, by for example running:
|
||||
* `browserify index.js --transform-key=production > bundle.js`
|
||||
* `browserify index.js --transform-key=staging > bundle.js`
|
||||
|
||||
--node
|
||||
|
||||
Alias for --bare and --no-browser-field.
|
||||
|
||||
--full-paths
|
||||
|
||||
Turn off converting module ids into numerical indexes. This is useful for
|
||||
preserving the original paths that a bundle was generated with.
|
||||
|
||||
--deps
|
||||
|
||||
Instead of standard bundle output, print the dependency array generated by
|
||||
module-deps.
|
||||
|
||||
--no-dedupe
|
||||
|
||||
Turn off deduping.
|
||||
|
||||
--list
|
||||
|
||||
Print each file in the dependency graph. Useful for makefiles.
|
||||
|
||||
--extension=EXTENSION
|
||||
|
||||
Consider files with specified EXTENSION as modules, this option can used
|
||||
multiple times.
|
||||
|
||||
--global-transform=MODULE, -g MODULE
|
||||
|
||||
Use a transform module on all files after any ordinary transforms have run.
|
||||
|
||||
--plugin=MODULE, -p MODULE
|
||||
|
||||
Register MODULE as a plugin.
|
||||
|
||||
--preserve-symlinks
|
||||
|
||||
Preserves symlinks when resolving modules.
|
||||
|
||||
Passing arguments to transforms and plugins:
|
||||
|
||||
For -t, -g, and -p, you may use subarg syntax to pass options to the
|
||||
transforms or plugin function as the second parameter. For example:
|
||||
|
||||
-t [ foo -x 3 --beep ]
|
||||
|
||||
will call the `foo` transform for each applicable file by calling:
|
||||
|
||||
foo(file, { x: 3, beep: true })
|
||||
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
var browserify = require('../');
|
||||
var path = require('path');
|
||||
var spawn = require('child_process').spawn;
|
||||
var parseShell = require('shell-quote').parse;
|
||||
var insertGlobals = require('insert-module-globals');
|
||||
var duplexer = require('duplexer2');
|
||||
var subarg = require('subarg');
|
||||
var glob = require('glob');
|
||||
var Readable = require('readable-stream').Readable;
|
||||
var xtend = require('xtend');
|
||||
|
||||
module.exports = function (args, opts) {
|
||||
var argv = subarg(args, {
|
||||
'boolean': [
|
||||
'deps', 'pack', 'ig', 'dg', 'im', 'd', 'list', 'builtins',
|
||||
'commondir', 'bare', 'full-paths', 'bundle-external', 'bf',
|
||||
'node', 'preserve-symlinks'
|
||||
],
|
||||
string: [ 's', 'r', 'u', 'x', 't', 'i', 'o', 'e', 'c', 'it' ],
|
||||
alias: {
|
||||
ig: [ 'insert-globals', 'fast' ],
|
||||
dg: [ 'detect-globals', 'detectGlobals', 'dg' ],
|
||||
bf: [ 'browser-field', 'browserField' ],
|
||||
im: 'ignore-missing',
|
||||
it: 'ignore-transform',
|
||||
igv: 'insert-global-vars',
|
||||
d: 'debug',
|
||||
s: 'standalone',
|
||||
noParse: [ 'noparse' ],
|
||||
'full-paths': [ 'fullpaths', 'fullPaths' ],
|
||||
r: 'require',
|
||||
u: 'exclude',
|
||||
x: 'external',
|
||||
t: 'transform',
|
||||
i: 'ignore',
|
||||
o: 'outfile',
|
||||
e: 'entry',
|
||||
c: 'command',
|
||||
bare: 'bear'
|
||||
},
|
||||
'default': {
|
||||
ig: false,
|
||||
im: false,
|
||||
dg: true,
|
||||
d: false,
|
||||
builtins: true,
|
||||
commondir: true,
|
||||
'bundle-external': true,
|
||||
bf: true,
|
||||
dedupe: true,
|
||||
node: false
|
||||
}
|
||||
});
|
||||
|
||||
var entries = argv._.concat(argv.entry)
|
||||
.filter(Boolean).map(function (entry) {
|
||||
if (entry === '-') {
|
||||
var s = process.stdin;
|
||||
if (typeof s.read === 'function') return s;
|
||||
// only needed for 0.8, remove at some point later:
|
||||
var rs = Readable().wrap(s);
|
||||
s.resume();
|
||||
return rs;
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
|
||||
if (argv.igv) {
|
||||
var insertGlobalVars = {};
|
||||
var wantedGlobalVars = argv.igv.split(',');
|
||||
Object.keys(insertGlobals.vars).forEach(function (x) {
|
||||
if (wantedGlobalVars.indexOf(x) === -1) {
|
||||
insertGlobalVars[x] = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var ignoreTransform = argv['ignore-transform'] || argv.it;
|
||||
var b = browserify(xtend({
|
||||
node: argv.node,
|
||||
bare: argv.bare,
|
||||
noParse: Array.isArray(argv.noParse) ? argv.noParse : [argv.noParse],
|
||||
extensions: [].concat(argv.extension).filter(Boolean).map(function (extension) {
|
||||
if (extension.charAt(0) != '.') {
|
||||
return '.' + extension;
|
||||
} else {
|
||||
return extension
|
||||
}
|
||||
}),
|
||||
ignoreTransform: [].concat(ignoreTransform).filter(Boolean),
|
||||
entries: entries,
|
||||
fullPaths: argv['full-paths'],
|
||||
builtins: argv.builtins === false ? false : undefined,
|
||||
commondir: argv.commondir === false ? false : undefined,
|
||||
bundleExternal: argv['bundle-external'],
|
||||
basedir: argv.basedir,
|
||||
browserField: argv.browserField,
|
||||
transformKey: argv['transform-key'] ? ['browserify', argv['transform-key']] : undefined,
|
||||
dedupe: argv['dedupe'],
|
||||
preserveSymlinks: argv['preserve-symlinks'],
|
||||
|
||||
detectGlobals: argv.detectGlobals,
|
||||
insertGlobals: argv['insert-globals'] || argv.ig,
|
||||
insertGlobalVars: insertGlobalVars,
|
||||
ignoreMissing: argv['ignore-missing'] || argv.im,
|
||||
debug: argv['debug'] || argv.d,
|
||||
standalone: argv['standalone'] || argv.s
|
||||
}, opts));
|
||||
function error (msg) {
|
||||
var e = new Error(msg);
|
||||
process.nextTick(function () { b.emit('error', e) });
|
||||
}
|
||||
b.argv = argv;
|
||||
[].concat(argv.p).concat(argv.plugin).filter(Boolean)
|
||||
.forEach(function (p) {
|
||||
var pf = p, pOpts = {};
|
||||
if (typeof p === 'object') {
|
||||
pf = p._.shift(), pOpts = p;
|
||||
}
|
||||
b.plugin(pf, pOpts);
|
||||
})
|
||||
;
|
||||
|
||||
[].concat(argv.ignore).filter(Boolean)
|
||||
.forEach(function (i) {
|
||||
b._pending ++;
|
||||
glob(i, function (err, files) {
|
||||
if (err) return b.emit('error', err);
|
||||
if (files.length === 0) {
|
||||
b.ignore(i);
|
||||
}
|
||||
else {
|
||||
files.forEach(function (file) { b.ignore(file) });
|
||||
}
|
||||
if (--b._pending === 0) b.emit('_ready');
|
||||
});
|
||||
})
|
||||
;
|
||||
|
||||
[].concat(argv.exclude).filter(Boolean)
|
||||
.forEach(function (u) {
|
||||
b.exclude(u);
|
||||
|
||||
b._pending ++;
|
||||
glob(u, function (err, files) {
|
||||
if (err) return b.emit('error', err);
|
||||
files.forEach(function (file) { b.exclude(file) });
|
||||
if (--b._pending === 0) b.emit('_ready');
|
||||
});
|
||||
})
|
||||
;
|
||||
|
||||
[].concat(argv.require).filter(Boolean)
|
||||
.forEach(function (r) {
|
||||
var xs = splitOnColon(r);
|
||||
b.require(xs[0], { expose: xs.length === 1 ? xs[0] : xs[1] })
|
||||
})
|
||||
;
|
||||
|
||||
// resolve any external files and add them to the bundle as externals
|
||||
[].concat(argv.external).filter(Boolean)
|
||||
.forEach(function (x) {
|
||||
var xs = splitOnColon(x);
|
||||
if (xs.length === 2) {
|
||||
add(xs[0], { expose: xs[1] });
|
||||
}
|
||||
else if (/\*/.test(x)) {
|
||||
b.external(x);
|
||||
glob(x, function (err, files) {
|
||||
files.forEach(function (file) {
|
||||
add(file, {});
|
||||
});
|
||||
});
|
||||
}
|
||||
else add(x, {});
|
||||
|
||||
function add (x, opts) {
|
||||
if (/^[\/.]/.test(x)) b.external(path.resolve(x), opts)
|
||||
else b.external(x, opts)
|
||||
}
|
||||
})
|
||||
;
|
||||
|
||||
[].concat(argv.transform)
|
||||
.filter(Boolean)
|
||||
.forEach(function (t) { addTransform(t) })
|
||||
;
|
||||
|
||||
[].concat(argv.g).concat(argv['global-transform'])
|
||||
.filter(Boolean)
|
||||
.forEach(function (t) {
|
||||
addTransform(t, { global: true });
|
||||
})
|
||||
;
|
||||
|
||||
function addTransform (t, opts) {
|
||||
if (typeof t === 'string' || typeof t === 'function') {
|
||||
b.transform(opts, t);
|
||||
}
|
||||
else if (t && typeof t === 'object') {
|
||||
if (!t._[0] || typeof t._[0] !== 'string') {
|
||||
return error(
|
||||
'expected first parameter to be a transform string'
|
||||
);
|
||||
}
|
||||
if (opts) Object.keys(opts).forEach(function (key) {
|
||||
t[key] = opts[key];
|
||||
});
|
||||
b.transform(t, t._.shift());
|
||||
}
|
||||
else error('unexpected transform of type ' + typeof t);
|
||||
}
|
||||
|
||||
[].concat(argv.command).filter(Boolean)
|
||||
.forEach(function (c) {
|
||||
var cmd = parseShell(c);
|
||||
b.transform(function (file) {
|
||||
var env = Object.keys(process.env).reduce(function (acc, key) {
|
||||
acc[key] = process.env[key];
|
||||
return acc;
|
||||
}, {});
|
||||
env.FILENAME = file;
|
||||
var ps = spawn(cmd[0], cmd.slice(1), { env: env });
|
||||
var error = '';
|
||||
ps.stderr.on('data', function (buf) { error += buf });
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
if (code === 0) return;
|
||||
console.error([
|
||||
'error running source transform command: ' + c,
|
||||
error.split('\n').join('\n '),
|
||||
''
|
||||
].join('\n'));
|
||||
process.exit(1);
|
||||
});
|
||||
return duplexer(ps.stdin, ps.stdout);
|
||||
});
|
||||
})
|
||||
;
|
||||
|
||||
if (argv.standalone === '') {
|
||||
error('--standalone requires an export name argument');
|
||||
return b;
|
||||
}
|
||||
|
||||
return b;
|
||||
};
|
||||
|
||||
function splitOnColon (f) {
|
||||
var pos = f.lastIndexOf(':');
|
||||
if (pos == -1) {
|
||||
return [f]; // No colon
|
||||
} else {
|
||||
if ((/[a-zA-Z]:[\\/]/.test(f)) && (pos == 1)){
|
||||
return [f]; // Windows path and colon is part of drive name
|
||||
} else {
|
||||
return [f.substr(0, pos), f.substr(pos + 1)];
|
||||
}
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env node
|
||||
var fs = require('fs');
|
||||
var JSONStream = require('JSONStream');
|
||||
var through = require('through2');
|
||||
var mkdirp = require('mkdirp-classic');
|
||||
var path = require('path');
|
||||
|
||||
var b = require('./args')(process.argv.slice(2));
|
||||
process.stdout.on('error', process.exit);
|
||||
|
||||
if ((b.argv._[0] === 'help' && b.argv._[1]) === 'advanced'
|
||||
|| (b.argv.h || b.argv.help) === 'advanced') {
|
||||
return fs.createReadStream(__dirname + '/advanced.txt')
|
||||
.pipe(process.stdout)
|
||||
.on('close', function () { process.exit(1) })
|
||||
;
|
||||
}
|
||||
if (b.argv._[0] === 'help' || b.argv.h || b.argv.help
|
||||
|| (process.argv.length <= 2 && process.stdin.isTTY)) {
|
||||
return fs.createReadStream(__dirname + '/usage.txt')
|
||||
.pipe(process.stdout)
|
||||
.on('close', function () { process.exit(1) })
|
||||
;
|
||||
}
|
||||
if (b.argv.version) {
|
||||
return console.log(require('../package.json').version);
|
||||
}
|
||||
|
||||
b.on('error', errorExit);
|
||||
|
||||
if (b.argv.pack) {
|
||||
process.stdin.pipe(b.pack()).pipe(process.stdout);
|
||||
process.stdin.resume();
|
||||
return;
|
||||
}
|
||||
|
||||
if (b.argv.deps) {
|
||||
var stringify = JSONStream.stringify();
|
||||
stringify.pipe(process.stdout);
|
||||
b.pipeline.get('deps').push(through.obj(
|
||||
function (row, enc, next) { stringify.write(row); next() },
|
||||
function () { stringify.end() }
|
||||
));
|
||||
return b.bundle();
|
||||
}
|
||||
|
||||
if (b.argv.list) {
|
||||
b.pipeline.get('deps').push(through.obj(
|
||||
function (row, enc, next) {
|
||||
console.log(row.file || row.id);
|
||||
next()
|
||||
}
|
||||
));
|
||||
return b.bundle();
|
||||
}
|
||||
|
||||
var bundle = b.bundle();
|
||||
bundle.on('error', errorExit);
|
||||
bundle.on('end', successExit);
|
||||
|
||||
var tmpfile;
|
||||
var outfile = b.argv.o || b.argv.outfile;
|
||||
if (outfile) {
|
||||
mkdirp.sync(path.dirname(outfile));
|
||||
|
||||
// we'll output to a temp file within same filesystem, then atomically overwrite outfile once successful
|
||||
tmpfile = outfile + ".tmp-browserify-" + Math.random().toFixed(20).slice(2)
|
||||
bundle.pipe(fs.createWriteStream(tmpfile));
|
||||
}
|
||||
else {
|
||||
bundle.pipe(process.stdout);
|
||||
}
|
||||
|
||||
function errorExit(err) {
|
||||
if (tmpfile) fs.unlink(tmpfile, function (err) {
|
||||
if (err) /* no-op, we're already exiting unhappily… */;
|
||||
});
|
||||
if (err.stack) {
|
||||
console.error(err.stack);
|
||||
}
|
||||
else {
|
||||
console.error(String(err));
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function successExit() {
|
||||
if (tmpfile && outfile) fs.rename(tmpfile, outfile, function (err) {
|
||||
if (err) errorExit(err);
|
||||
});
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
Usage: browserify [entry files] {OPTIONS}
|
||||
|
||||
Standard Options:
|
||||
|
||||
--outfile, -o Write the browserify bundle to this file.
|
||||
If unspecified, browserify prints to stdout.
|
||||
|
||||
--require, -r A module name or file to bundle.require()
|
||||
Optionally use a colon separator to set the target.
|
||||
|
||||
--entry, -e An entry point of your app
|
||||
|
||||
--ignore, -i Replace a file with an empty stub. Files can be globs.
|
||||
|
||||
--exclude, -u Omit a file from the output bundle. Files can be globs.
|
||||
|
||||
--external, -x Reference a file from another bundle. Files can be globs.
|
||||
|
||||
--transform, -t Use a transform module on top-level files.
|
||||
|
||||
--command, -c Use a transform command on top-level files.
|
||||
|
||||
--standalone -s Generate a UMD bundle for the supplied export name.
|
||||
This bundle works with other module systems and sets the name
|
||||
given as a window global if no module system is found.
|
||||
|
||||
--debug -d Enable source maps that allow you to debug your files
|
||||
separately.
|
||||
|
||||
--help, -h Show this message
|
||||
|
||||
For advanced options, type `browserify --help advanced`.
|
||||
|
||||
Specify a parameter.
|
||||
+1388
File diff suppressed because it is too large
Load Diff
+78
@@ -0,0 +1,78 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
nationality, personal appearance, race, religion, or sexual identity and
|
||||
orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at (any one or all of these):
|
||||
|
||||
* substack@gmail.com
|
||||
|
||||
All complaints will be reviewed and investigated and will result in a response
|
||||
that is deemed necessary and appropriate to the circumstances. The project team
|
||||
is obligated to maintain confidentiality with regard to the reporter of an
|
||||
incident. Further details of specific enforcement policies may be posted
|
||||
separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = function (n) { return n * 3 };
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
var bar = require('./bar');
|
||||
|
||||
module.exports = function (n) {
|
||||
return n * bar(n);
|
||||
};
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
var foo = require('./foo');
|
||||
console.log(foo(5));
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
var browserify = require('browserify');
|
||||
var b = browserify();
|
||||
b.add('./browser/main.js');
|
||||
b.bundle().pipe(process.stdout);
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
var robot = require('./robot');
|
||||
console.log(robot('beep'));
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
var robot = require('./robot');
|
||||
console.log(robot('boop'));
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
browserify -r ./robot.js > static/common.js
|
||||
browserify -x ./robot.js beep.js > static/beep.js
|
||||
browserify -x ./robot.js boop.js > static/boop.js
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = function (s) { return s.toUpperCase() + '!' };
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<script src="common.js"></script>
|
||||
<script src="beep.js"></script>
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
<script src="common.js"></script>
|
||||
<script src="boop.js"></script>
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
var browserify = require('../..'),
|
||||
path = require('path'),
|
||||
fs = require('fs'),
|
||||
bundlePath = path.join(__dirname, 'js', 'build', 'bundle.js');
|
||||
|
||||
browserify()
|
||||
.require(require.resolve('./js/main.js'), {
|
||||
entry: true,
|
||||
debug: true
|
||||
})
|
||||
.bundle()
|
||||
.on('error', function (err) { console.error(err); })
|
||||
.pipe(fs.createWriteStream(bundlePath));
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
../../bin/cmd.js --debug -e ./js/main.js > js/build/bundle.js
|
||||
|
||||
echo bundle was generated with source maps, you can now open index.html
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=utf-8 />
|
||||
<title></title>
|
||||
<script type="text/javascript" src="./js/build/bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Open your dev tools ;)</p>
|
||||
</body>
|
||||
</html>
|
||||
+1
@@ -0,0 +1 @@
|
||||
!.gitignore
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
;(function(e,t,n,r){function i(r){if(!n[r]){if(!t[r]){if(e)return e(r);throw new Error("Cannot find module '"+r+"'")}var s=n[r]={exports:{}};t[r][0](function(e){var n=t[r][1][e];return i(n?n:e)},s,s.exports)}return n[r].exports}for(var s=0;s<r.length;s++)i(r[s]);return i})(typeof require!=="undefined"&&require,{1:[function(require,module,exports){
|
||||
console.log('main line 1');
|
||||
var foo = require('./foo.js');
|
||||
|
||||
foo();
|
||||
|
||||
},{"./foo.js":2}],2:[function(require,module,exports){
|
||||
console.log('foo line 1');
|
||||
var bar = require('./wunder/bar');
|
||||
|
||||
module.exports = function foo() {
|
||||
console.log('hello from foo line 5');
|
||||
bar();
|
||||
};
|
||||
|
||||
},{"./wunder/bar":3}],3:[function(require,module,exports){
|
||||
console.log('bar line 1');
|
||||
'use strict';
|
||||
|
||||
// this is a meaningless comment to add some lines
|
||||
|
||||
module.exports = function bar() {
|
||||
console.log('hello from bar line 7');
|
||||
};
|
||||
|
||||
},{}]},{},[1])
|
||||
//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlcyI6WyIvVXNlcnMvdGhsb3JlbnovZGV2L2pzL3Byb2plY3RzL2ZvcmtzL25vZGUtYnJvd3NlcmlmeS9leGFtcGxlL3NvdXJjZV9tYXBzL2pzL21haW4uanMiLCIvVXNlcnMvdGhsb3JlbnovZGV2L2pzL3Byb2plY3RzL2ZvcmtzL25vZGUtYnJvd3NlcmlmeS9leGFtcGxlL3NvdXJjZV9tYXBzL2pzL2Zvby5qcyIsIi9Vc2Vycy90aGxvcmVuei9kZXYvanMvcHJvamVjdHMvZm9ya3Mvbm9kZS1icm93c2VyaWZ5L2V4YW1wbGUvc291cmNlX21hcHMvanMvd3VuZGVyL2Jhci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiJmaWxlOi8vbG9jYWxob3N0Iiwic291cmNlQ29udGVudCI6WyJjb25zb2xlLmxvZygnbWFpbiBsaW5lIDEnKTtcbnZhciBmb28gPSByZXF1aXJlKCcuL2Zvby5qcycpO1xuXG5mb28oKTtcbiIsImNvbnNvbGUubG9nKCdmb28gbGluZSAxJyk7XG52YXIgYmFyID0gcmVxdWlyZSgnLi93dW5kZXIvYmFyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZm9vKCkge1xuICBjb25zb2xlLmxvZygnaGVsbG8gZnJvbSBmb28gbGluZSA1Jyk7XG4gIGJhcigpO1xufTtcbiIsImNvbnNvbGUubG9nKCdiYXIgbGluZSAxJyk7XG4ndXNlIHN0cmljdCc7XG5cbi8vIHRoaXMgaXMgYSBtZWFuaW5nbGVzcyBjb21tZW50IHRvIGFkZCBzb21lIGxpbmVzXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYmFyKCkge1xuICBjb25zb2xlLmxvZygnaGVsbG8gZnJvbSBiYXIgbGluZSA3Jyk7XG59O1xuIl19
|
||||
;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
console.log('foo line 1');
|
||||
var bar = require('./wunder/bar');
|
||||
|
||||
module.exports = function foo() {
|
||||
console.log('hello from foo line 5');
|
||||
bar();
|
||||
};
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
console.log('main line 1');
|
||||
var foo = require('./foo.js');
|
||||
|
||||
foo();
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
console.log('bar line 1');
|
||||
'use strict';
|
||||
|
||||
// this is a meaningless comment to add some lines
|
||||
|
||||
module.exports = function bar() {
|
||||
console.log('hello from bar line 7');
|
||||
};
|
||||
+875
@@ -0,0 +1,875 @@
|
||||
var path = require('path');
|
||||
var mdeps = require('module-deps');
|
||||
var depsSort = require('deps-sort');
|
||||
var bpack = require('browser-pack');
|
||||
var insertGlobals = require('insert-module-globals');
|
||||
var syntaxError = require('syntax-error');
|
||||
|
||||
var builtins = require('./lib/builtins.js');
|
||||
|
||||
var splicer = require('labeled-stream-splicer');
|
||||
var through = require('through2');
|
||||
var concat = require('concat-stream');
|
||||
|
||||
var inherits = require('inherits');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var xtend = require('xtend');
|
||||
var isArray = Array.isArray;
|
||||
var defined = require('defined');
|
||||
var has = require('has');
|
||||
var sanitize = require('htmlescape').sanitize;
|
||||
var shasum = require('shasum-object');
|
||||
|
||||
var bresolve = require('browser-resolve');
|
||||
var resolve = require('resolve');
|
||||
|
||||
var readonly = require('read-only-stream');
|
||||
|
||||
module.exports = Browserify;
|
||||
inherits(Browserify, EventEmitter);
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var cachedPathRelative = require('cached-path-relative');
|
||||
|
||||
var paths = {
|
||||
empty: path.join(__dirname, 'lib/_empty.js')
|
||||
};
|
||||
|
||||
function Browserify (files, opts) {
|
||||
var self = this;
|
||||
if (!(this instanceof Browserify)) return new Browserify(files, opts);
|
||||
if (!opts) opts = {};
|
||||
|
||||
if (typeof files === 'string' || isArray(files) || isStream(files)) {
|
||||
opts = xtend(opts, { entries: [].concat(opts.entries || [], files) });
|
||||
}
|
||||
else opts = xtend(files, opts);
|
||||
|
||||
if (opts.node) {
|
||||
opts.bare = true;
|
||||
opts.browserField = false;
|
||||
}
|
||||
if (opts.bare) {
|
||||
opts.builtins = false;
|
||||
opts.commondir = false;
|
||||
if (opts.insertGlobalVars === undefined) {
|
||||
opts.insertGlobalVars = {}
|
||||
Object.keys(insertGlobals.vars).forEach(function (name) {
|
||||
if (name !== '__dirname' && name !== '__filename') {
|
||||
opts.insertGlobalVars[name] = undefined;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
self._options = opts;
|
||||
if (opts.noparse) opts.noParse = opts.noparse;
|
||||
|
||||
if (opts.basedir !== undefined && typeof opts.basedir !== 'string') {
|
||||
throw new Error('opts.basedir must be either undefined or a string.');
|
||||
}
|
||||
|
||||
opts.dedupe = opts.dedupe === false ? false : true;
|
||||
|
||||
self._external = [];
|
||||
self._exclude = [];
|
||||
self._ignore = [];
|
||||
self._expose = {};
|
||||
self._hashes = {};
|
||||
self._pending = 0;
|
||||
self._transformOrder = 0;
|
||||
self._transformPending = 0;
|
||||
self._transforms = [];
|
||||
self._entryOrder = 0;
|
||||
self._ticked = false;
|
||||
|
||||
var browserField = opts.browserField
|
||||
self._bresolve = browserField === false
|
||||
? function (id, opts, cb) {
|
||||
if (!opts.basedir) opts.basedir = path.dirname(opts.filename)
|
||||
resolve(id, opts, cb)
|
||||
}
|
||||
: typeof browserField === 'string'
|
||||
? function (id, opts, cb) {
|
||||
opts.browser = browserField
|
||||
bresolve(id, opts, cb)
|
||||
}
|
||||
: bresolve
|
||||
;
|
||||
self._syntaxCache = {};
|
||||
|
||||
var ignoreTransform = [].concat(opts.ignoreTransform).filter(Boolean);
|
||||
self._filterTransform = function (tr) {
|
||||
if (isArray(tr)) {
|
||||
return ignoreTransform.indexOf(tr[0]) === -1;
|
||||
}
|
||||
return ignoreTransform.indexOf(tr) === -1;
|
||||
};
|
||||
|
||||
self.pipeline = self._createPipeline(opts);
|
||||
|
||||
[].concat(opts.transform).filter(Boolean).filter(self._filterTransform)
|
||||
.forEach(function (tr) {
|
||||
self.transform(tr);
|
||||
});
|
||||
|
||||
[].concat(opts.entries).filter(Boolean).forEach(function (file) {
|
||||
self.add(file, { basedir: opts.basedir });
|
||||
});
|
||||
|
||||
[].concat(opts.require).filter(Boolean).forEach(function (file) {
|
||||
self.require(file, { basedir: opts.basedir });
|
||||
});
|
||||
|
||||
[].concat(opts.plugin).filter(Boolean).forEach(function (p) {
|
||||
self.plugin(p, { basedir: opts.basedir });
|
||||
});
|
||||
}
|
||||
|
||||
Browserify.prototype.require = function (file, opts) {
|
||||
var self = this;
|
||||
if (isArray(file)) {
|
||||
file.forEach(function (x) {
|
||||
if (typeof x === 'object') {
|
||||
self.require(x.file, xtend(opts, x));
|
||||
}
|
||||
else self.require(x, opts);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!opts) opts = {};
|
||||
var basedir = defined(opts.basedir, self._options.basedir, process.cwd());
|
||||
var expose = opts.expose;
|
||||
if (file === expose && /^[\.]/.test(expose)) {
|
||||
expose = '/' + relativePath(basedir, expose);
|
||||
}
|
||||
if (expose === undefined && this._options.exposeAll) {
|
||||
expose = true;
|
||||
}
|
||||
if (expose === true) {
|
||||
expose = '/' + relativePath(basedir, file);
|
||||
}
|
||||
|
||||
if (isStream(file)) {
|
||||
self._pending ++;
|
||||
var order = self._entryOrder ++;
|
||||
file.pipe(concat(function (buf) {
|
||||
var filename = opts.file || file.file || path.join(
|
||||
basedir,
|
||||
'_stream_' + order + '.js'
|
||||
);
|
||||
var id = file.id || expose || filename;
|
||||
if (expose || opts.entry === false) {
|
||||
self._expose[id] = filename;
|
||||
}
|
||||
if (!opts.entry && self._options.exports === undefined) {
|
||||
self._bpack.hasExports = true;
|
||||
}
|
||||
var rec = {
|
||||
source: buf.toString('utf8'),
|
||||
entry: defined(opts.entry, false),
|
||||
file: filename,
|
||||
id: id
|
||||
};
|
||||
if (rec.entry) rec.order = order;
|
||||
if (rec.transform === false) rec.transform = false;
|
||||
self.pipeline.write(rec);
|
||||
|
||||
if (-- self._pending === 0) self.emit('_ready');
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
|
||||
var row;
|
||||
if (typeof file === 'object') {
|
||||
row = xtend(file, opts);
|
||||
}
|
||||
else if (!opts.entry && isExternalModule(file)) {
|
||||
// external module or builtin
|
||||
row = xtend(opts, { id: expose || file, file: file });
|
||||
}
|
||||
else {
|
||||
row = xtend(opts, { file: path.resolve(basedir, file) });
|
||||
}
|
||||
|
||||
if (!row.id) {
|
||||
row.id = expose || row.file;
|
||||
}
|
||||
if (expose || !row.entry) {
|
||||
// Make this available to mdeps so that it can assign the value when it
|
||||
// resolves the pathname.
|
||||
row.expose = row.id;
|
||||
}
|
||||
|
||||
if (opts.external) return self.external(file, opts);
|
||||
if (row.entry === undefined) row.entry = false;
|
||||
|
||||
if (!row.entry && self._options.exports === undefined) {
|
||||
self._bpack.hasExports = true;
|
||||
}
|
||||
|
||||
if (row.entry) row.order = self._entryOrder ++;
|
||||
|
||||
if (opts.transform === false) row.transform = false;
|
||||
self.pipeline.write(row);
|
||||
return self;
|
||||
};
|
||||
|
||||
Browserify.prototype.add = function (file, opts) {
|
||||
var self = this;
|
||||
if (!opts) opts = {};
|
||||
if (isArray(file)) {
|
||||
file.forEach(function (x) { self.add(x, opts) });
|
||||
return this;
|
||||
}
|
||||
return this.require(file, xtend({ entry: true, expose: false }, opts));
|
||||
};
|
||||
|
||||
Browserify.prototype.external = function (file, opts) {
|
||||
var self = this;
|
||||
if (isArray(file)) {
|
||||
file.forEach(function (f) {
|
||||
if (typeof f === 'object') {
|
||||
self.external(f, xtend(opts, f));
|
||||
}
|
||||
else self.external(f, opts)
|
||||
});
|
||||
return this;
|
||||
}
|
||||
if (file && typeof file === 'object' && typeof file.bundle === 'function') {
|
||||
var b = file;
|
||||
self._pending ++;
|
||||
|
||||
var bdeps = {};
|
||||
var blabels = {};
|
||||
|
||||
b.on('label', function (prev, id) {
|
||||
self._external.push(id);
|
||||
|
||||
if (prev !== id) {
|
||||
blabels[prev] = id;
|
||||
self._external.push(prev);
|
||||
}
|
||||
});
|
||||
|
||||
b.pipeline.get('deps').push(through.obj(function (row, enc, next) {
|
||||
bdeps = xtend(bdeps, row.deps);
|
||||
this.push(row);
|
||||
next();
|
||||
}));
|
||||
|
||||
self.on('dep', function (row) {
|
||||
Object.keys(row.deps).forEach(function (key) {
|
||||
var prev = bdeps[key];
|
||||
if (prev) {
|
||||
var id = blabels[prev];
|
||||
if (id) {
|
||||
row.indexDeps[key] = id;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
b.pipeline.get('label').once('end', function () {
|
||||
if (-- self._pending === 0) self.emit('_ready');
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!opts) opts = {};
|
||||
var basedir = defined(opts.basedir, process.cwd());
|
||||
this._external.push(file);
|
||||
this._external.push('/' + relativePath(basedir, file));
|
||||
return this;
|
||||
};
|
||||
|
||||
Browserify.prototype.exclude = function (file, opts) {
|
||||
if (!opts) opts = {};
|
||||
if (isArray(file)) {
|
||||
var self = this;
|
||||
file.forEach(function(file) {
|
||||
self.exclude(file, opts);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
var basedir = defined(opts.basedir, process.cwd());
|
||||
this._exclude.push(file);
|
||||
this._exclude.push('/' + relativePath(basedir, file));
|
||||
return this;
|
||||
};
|
||||
|
||||
Browserify.prototype.ignore = function (file, opts) {
|
||||
if (!opts) opts = {};
|
||||
if (isArray(file)) {
|
||||
var self = this;
|
||||
file.forEach(function(file) {
|
||||
self.ignore(file, opts);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
var basedir = defined(opts.basedir, process.cwd());
|
||||
|
||||
// Handle relative paths
|
||||
if (file[0] === '.') {
|
||||
this._ignore.push(path.resolve(basedir, file));
|
||||
}
|
||||
else {
|
||||
this._ignore.push(file);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Browserify.prototype.transform = function (tr, opts) {
|
||||
var self = this;
|
||||
if (typeof opts === 'function' || typeof opts === 'string') {
|
||||
tr = [ opts, tr ];
|
||||
}
|
||||
if (isArray(tr)) {
|
||||
opts = tr[1];
|
||||
tr = tr[0];
|
||||
}
|
||||
|
||||
//if the bundler is ignoring this transform
|
||||
if (typeof tr === 'string' && !self._filterTransform(tr)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
function resolved () {
|
||||
self._transforms[order] = rec;
|
||||
-- self._pending;
|
||||
if (-- self._transformPending === 0) {
|
||||
self._transforms.forEach(function (transform) {
|
||||
self.pipeline.write(transform);
|
||||
});
|
||||
|
||||
if (self._pending === 0) {
|
||||
self.emit('_ready');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!opts) opts = {};
|
||||
opts._flags = '_flags' in opts ? opts._flags : self._options;
|
||||
|
||||
var basedir = defined(opts.basedir, this._options.basedir, process.cwd());
|
||||
var order = self._transformOrder ++;
|
||||
self._pending ++;
|
||||
self._transformPending ++;
|
||||
|
||||
var rec = {
|
||||
transform: tr,
|
||||
options: opts,
|
||||
global: opts.global
|
||||
};
|
||||
|
||||
if (typeof tr === 'string') {
|
||||
var topts = {
|
||||
basedir: basedir,
|
||||
paths: (self._options.paths || []).map(function (p) {
|
||||
return path.resolve(basedir, p);
|
||||
})
|
||||
};
|
||||
resolve(tr, topts, function (err, res) {
|
||||
if (err) return self.emit('error', err);
|
||||
rec.transform = res;
|
||||
resolved();
|
||||
});
|
||||
}
|
||||
else process.nextTick(resolved);
|
||||
return this;
|
||||
};
|
||||
|
||||
Browserify.prototype.plugin = function (p, opts) {
|
||||
if (isArray(p)) {
|
||||
opts = p[1];
|
||||
p = p[0];
|
||||
}
|
||||
if (!opts) opts = {};
|
||||
var basedir = defined(opts.basedir, this._options.basedir, process.cwd());
|
||||
if (typeof p === 'function') {
|
||||
p(this, opts);
|
||||
}
|
||||
else {
|
||||
var pfile = resolve.sync(String(p), { basedir: basedir })
|
||||
var f = require(pfile);
|
||||
if (typeof f !== 'function') {
|
||||
throw new Error('plugin ' + p + ' should export a function');
|
||||
}
|
||||
f(this, opts);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Browserify.prototype._createPipeline = function (opts) {
|
||||
var self = this;
|
||||
if (!opts) opts = {};
|
||||
this._mdeps = this._createDeps(opts);
|
||||
this._mdeps.on('file', function (file, id) {
|
||||
pipeline.emit('file', file, id);
|
||||
self.emit('file', file, id);
|
||||
});
|
||||
this._mdeps.on('package', function (pkg) {
|
||||
pipeline.emit('package', pkg);
|
||||
self.emit('package', pkg);
|
||||
});
|
||||
this._mdeps.on('transform', function (tr, file) {
|
||||
pipeline.emit('transform', tr, file);
|
||||
self.emit('transform', tr, file);
|
||||
});
|
||||
|
||||
var dopts = {
|
||||
index: !opts.fullPaths && !opts.exposeAll,
|
||||
dedupe: opts.dedupe,
|
||||
expose: this._expose
|
||||
};
|
||||
this._bpack = bpack(xtend(opts, { raw: true }));
|
||||
|
||||
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', []
|
||||
]);
|
||||
if (opts.exposeAll) {
|
||||
var basedir = defined(opts.basedir, process.cwd());
|
||||
pipeline.get('deps').push(through.obj(function (row, enc, next) {
|
||||
if (self._external.indexOf(row.id) >= 0) return next();
|
||||
if (self._external.indexOf(row.file) >= 0) return next();
|
||||
|
||||
if (isAbsolutePath(row.id)) {
|
||||
row.id = '/' + relativePath(basedir, row.file);
|
||||
}
|
||||
Object.keys(row.deps || {}).forEach(function (key) {
|
||||
row.deps[key] = '/' + relativePath(basedir, row.deps[key]);
|
||||
});
|
||||
this.push(row);
|
||||
next();
|
||||
}));
|
||||
}
|
||||
return pipeline;
|
||||
};
|
||||
|
||||
Browserify.prototype._createDeps = function (opts) {
|
||||
var self = this;
|
||||
var mopts = xtend(opts);
|
||||
var basedir = defined(opts.basedir, process.cwd());
|
||||
|
||||
// Let mdeps populate these values since it will be resolving file paths
|
||||
// anyway.
|
||||
mopts.expose = this._expose;
|
||||
mopts.extensions = [ '.js', '.json' ].concat(mopts.extensions || []);
|
||||
self._extensions = mopts.extensions;
|
||||
|
||||
mopts.transform = [];
|
||||
mopts.transformKey = defined(opts.transformKey, [ 'browserify', 'transform' ]);
|
||||
mopts.postFilter = function (id, file, pkg) {
|
||||
if (opts.postFilter && !opts.postFilter(id, file, pkg)) return false;
|
||||
if (self._external.indexOf(file) >= 0) return false;
|
||||
if (self._exclude.indexOf(file) >= 0) return false;
|
||||
|
||||
//filter transforms on module dependencies
|
||||
if (pkg && pkg.browserify && pkg.browserify.transform) {
|
||||
//In edge cases it may be a string
|
||||
pkg.browserify.transform = [].concat(pkg.browserify.transform)
|
||||
.filter(Boolean)
|
||||
.filter(self._filterTransform);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
mopts.filter = function (id) {
|
||||
if (opts.filter && !opts.filter(id)) return false;
|
||||
if (self._external.indexOf(id) >= 0) return false;
|
||||
if (self._exclude.indexOf(id) >= 0) return false;
|
||||
if (opts.bundleExternal === false && isExternalModule(id)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
mopts.resolve = function (id, parent, cb) {
|
||||
if (self._ignore.indexOf(id) >= 0) return cb(null, paths.empty, {});
|
||||
|
||||
self._bresolve(id, parent, function (err, file, pkg) {
|
||||
if (file && self._ignore.indexOf(file) >= 0) {
|
||||
return cb(null, paths.empty, {});
|
||||
}
|
||||
if (file && self._ignore.length) {
|
||||
var nm = file.replace(/\\/g, '/').split('/node_modules/')[1];
|
||||
if (nm) {
|
||||
nm = nm.split('/')[0];
|
||||
if (self._ignore.indexOf(nm) >= 0) {
|
||||
return cb(null, paths.empty, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file) {
|
||||
var ex = '/' + relativePath(basedir, file);
|
||||
if (self._external.indexOf(ex) >= 0) {
|
||||
return cb(null, ex);
|
||||
}
|
||||
if (self._exclude.indexOf(ex) >= 0) {
|
||||
return cb(null, ex);
|
||||
}
|
||||
if (self._ignore.indexOf(ex) >= 0) {
|
||||
return cb(null, paths.empty, {});
|
||||
}
|
||||
}
|
||||
if (err) cb(err, file, pkg)
|
||||
else if (file) {
|
||||
if (opts.preserveSymlinks && parent.id !== self._mdeps.top.id) {
|
||||
return cb(err, path.resolve(file), pkg, file)
|
||||
}
|
||||
|
||||
fs.realpath(file, function (err, res) {
|
||||
cb(err, res, pkg, file);
|
||||
});
|
||||
} else cb(err, null, pkg)
|
||||
});
|
||||
};
|
||||
|
||||
if (opts.builtins === false) {
|
||||
mopts.modules = {};
|
||||
self._exclude.push.apply(self._exclude, Object.keys(builtins));
|
||||
}
|
||||
else if (opts.builtins && isArray(opts.builtins)) {
|
||||
mopts.modules = {};
|
||||
opts.builtins.forEach(function (key) {
|
||||
mopts.modules[key] = builtins[key];
|
||||
});
|
||||
}
|
||||
else if (opts.builtins && typeof opts.builtins === 'object') {
|
||||
mopts.modules = opts.builtins;
|
||||
}
|
||||
else mopts.modules = xtend(builtins);
|
||||
|
||||
Object.keys(builtins).forEach(function (key) {
|
||||
if (!has(mopts.modules, key)) self._exclude.push(key);
|
||||
});
|
||||
|
||||
mopts.globalTransform = [];
|
||||
if (!this._bundled) {
|
||||
this.once('bundle', function () {
|
||||
self.pipeline.write({
|
||||
transform: globalTr,
|
||||
global: true,
|
||||
options: {}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var no = [].concat(opts.noParse).filter(Boolean);
|
||||
var absno = no.filter(function(x) {
|
||||
return typeof x === 'string';
|
||||
}).map(function (x) {
|
||||
return path.resolve(basedir, x);
|
||||
});
|
||||
|
||||
function globalTr (file) {
|
||||
if (opts.detectGlobals === false) return through();
|
||||
|
||||
if (opts.noParse === true) return through();
|
||||
if (no.indexOf(file) >= 0) return through();
|
||||
if (absno.indexOf(file) >= 0) return through();
|
||||
|
||||
var parts = file.replace(/\\/g, '/').split('/node_modules/');
|
||||
for (var i = 0; i < no.length; i++) {
|
||||
if (typeof no[i] === 'function' && no[i](file)) {
|
||||
return through();
|
||||
}
|
||||
else if (no[i] === parts[parts.length-1].split('/')[0]) {
|
||||
return through();
|
||||
}
|
||||
else if (no[i] === parts[parts.length-1]) {
|
||||
return through();
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.commondir === false && opts.builtins === false) {
|
||||
opts.insertGlobalVars = xtend({
|
||||
__dirname: function(file, basedir) {
|
||||
var dir = path.dirname(path.relative(basedir, file));
|
||||
return 'require("path").join(__dirname,' + dir.split(path.sep).map(JSON.stringify).join(',') + ')';
|
||||
},
|
||||
__filename: function(file, basedir) {
|
||||
var filename = path.relative(basedir, file);
|
||||
return 'require("path").join(__dirname,' + filename.split(path.sep).map(JSON.stringify).join(',') + ')';
|
||||
}
|
||||
}, opts.insertGlobalVars);
|
||||
}
|
||||
|
||||
var vars = xtend({
|
||||
process: function () { return "require('_process')" },
|
||||
}, opts.insertGlobalVars);
|
||||
|
||||
if (opts.bundleExternal === false) {
|
||||
vars.process = undefined;
|
||||
vars.buffer = undefined;
|
||||
}
|
||||
|
||||
return insertGlobals(file, xtend(opts, {
|
||||
debug: opts.debug,
|
||||
always: opts.insertGlobals,
|
||||
basedir: opts.commondir === false && isArray(opts.builtins)
|
||||
? '/'
|
||||
: opts.basedir || process.cwd()
|
||||
,
|
||||
vars: vars
|
||||
}));
|
||||
}
|
||||
return mdeps(mopts);
|
||||
};
|
||||
|
||||
Browserify.prototype._recorder = function (opts) {
|
||||
var self = this;
|
||||
var ended = false;
|
||||
this._recorded = [];
|
||||
|
||||
if (!this._ticked) {
|
||||
process.nextTick(function () {
|
||||
self._ticked = true;
|
||||
self._recorded.forEach(function (row) {
|
||||
stream.push(row);
|
||||
});
|
||||
if (ended) stream.push(null);
|
||||
});
|
||||
}
|
||||
|
||||
var stream = through.obj(write, end);
|
||||
return stream;
|
||||
|
||||
function write (row, enc, next) {
|
||||
self._recorded.push(row);
|
||||
if (self._ticked) this.push(row);
|
||||
next();
|
||||
}
|
||||
function end () {
|
||||
ended = true;
|
||||
if (self._ticked) this.push(null);
|
||||
}
|
||||
};
|
||||
|
||||
Browserify.prototype._json = function () {
|
||||
return through.obj(function (row, enc, next) {
|
||||
if (/\.json$/.test(row.file)) {
|
||||
var sanitizedString = sanitize(row.source);
|
||||
try {
|
||||
// check json validity
|
||||
JSON.parse(sanitizedString);
|
||||
row.source = 'module.exports=' + sanitizedString;
|
||||
} catch (err) {
|
||||
err.message = 'While parsing ' + (row.file || row.id) + ': ' + err.message
|
||||
this.emit('error', err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.push(row);
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
Browserify.prototype._unbom = function () {
|
||||
return through.obj(function (row, enc, next) {
|
||||
if (/^\ufeff/.test(row.source)) {
|
||||
row.source = row.source.replace(/^\ufeff/, '');
|
||||
}
|
||||
this.push(row);
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
Browserify.prototype._unshebang = function () {
|
||||
return through.obj(function (row, enc, next) {
|
||||
if (/^#!/.test(row.source)) {
|
||||
row.source = row.source.replace(/^#![^\n]*\n/, '');
|
||||
}
|
||||
this.push(row);
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
Browserify.prototype._syntax = function () {
|
||||
var self = this;
|
||||
return through.obj(function (row, enc, next) {
|
||||
var h = shasum(row.source);
|
||||
if (typeof self._syntaxCache[h] === 'undefined') {
|
||||
var err = syntaxError(row.source, row.file || row.id);
|
||||
if (err) return this.emit('error', err);
|
||||
self._syntaxCache[h] = true;
|
||||
}
|
||||
this.push(row);
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
Browserify.prototype._dedupe = function () {
|
||||
return through.obj(function (row, enc, next) {
|
||||
if (!row.dedupeIndex && row.dedupe) {
|
||||
row.source = 'arguments[4]['
|
||||
+ JSON.stringify(row.dedupe)
|
||||
+ '][0].apply(exports,arguments)'
|
||||
;
|
||||
row.nomap = true;
|
||||
}
|
||||
else if (row.dedupeIndex) {
|
||||
row.source = 'arguments[4]['
|
||||
+ JSON.stringify(row.dedupeIndex)
|
||||
+ '][0].apply(exports,arguments)'
|
||||
;
|
||||
row.nomap = true;
|
||||
}
|
||||
if (row.dedupeIndex && row.indexDeps) {
|
||||
row.indexDeps.dup = row.dedupeIndex;
|
||||
}
|
||||
this.push(row);
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
Browserify.prototype._label = function (opts) {
|
||||
var self = this;
|
||||
var basedir = defined(opts.basedir, process.cwd());
|
||||
|
||||
return through.obj(function (row, enc, next) {
|
||||
var prev = row.id;
|
||||
|
||||
if (self._external.indexOf(row.id) >= 0) return next();
|
||||
if (self._external.indexOf('/' + relativePath(basedir, row.id)) >= 0) {
|
||||
return next();
|
||||
}
|
||||
if (self._external.indexOf(row.file) >= 0) return next();
|
||||
|
||||
if (row.index) row.id = row.index;
|
||||
|
||||
self.emit('label', prev, row.id);
|
||||
if (row.indexDeps) row.deps = row.indexDeps || {};
|
||||
|
||||
Object.keys(row.deps).forEach(function (key) {
|
||||
if (self._expose[key]) {
|
||||
row.deps[key] = key;
|
||||
return;
|
||||
}
|
||||
|
||||
var afile = path.resolve(path.dirname(row.file), key);
|
||||
var rfile = '/' + relativePath(basedir, afile);
|
||||
if (self._external.indexOf(rfile) >= 0) {
|
||||
row.deps[key] = rfile;
|
||||
}
|
||||
if (self._external.indexOf(afile) >= 0) {
|
||||
row.deps[key] = rfile;
|
||||
}
|
||||
if (self._external.indexOf(key) >= 0) {
|
||||
row.deps[key] = key;
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < self._extensions.length; i++) {
|
||||
var ex = self._extensions[i];
|
||||
if (self._external.indexOf(rfile + ex) >= 0) {
|
||||
row.deps[key] = rfile + ex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (row.entry || row.expose) {
|
||||
self._bpack.standaloneModule = row.id;
|
||||
}
|
||||
this.push(row);
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
Browserify.prototype._emitDeps = function () {
|
||||
var self = this;
|
||||
return through.obj(function (row, enc, next) {
|
||||
self.emit('dep', row);
|
||||
this.push(row);
|
||||
next();
|
||||
})
|
||||
};
|
||||
|
||||
Browserify.prototype._debug = function (opts) {
|
||||
var basedir = defined(opts.basedir, process.cwd());
|
||||
return through.obj(function (row, enc, next) {
|
||||
if (opts.debug) {
|
||||
row.sourceRoot = 'file://localhost';
|
||||
row.sourceFile = relativePath(basedir, row.file);
|
||||
}
|
||||
this.push(row);
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
Browserify.prototype.reset = function (opts) {
|
||||
if (!opts) opts = {};
|
||||
var hadExports = this._bpack.hasExports;
|
||||
this.pipeline = this._createPipeline(xtend(opts, this._options));
|
||||
this._bpack.hasExports = hadExports;
|
||||
this._entryOrder = 0;
|
||||
this._bundled = false;
|
||||
this.emit('reset');
|
||||
};
|
||||
|
||||
Browserify.prototype.bundle = function (cb) {
|
||||
var self = this;
|
||||
if (cb && typeof cb === 'object') {
|
||||
throw new Error(
|
||||
'bundle() no longer accepts option arguments.\n'
|
||||
+ 'Move all option arguments to the browserify() constructor.'
|
||||
);
|
||||
}
|
||||
if (this._bundled) {
|
||||
var recorded = this._recorded;
|
||||
this.reset();
|
||||
recorded.forEach(function (x) {
|
||||
self.pipeline.write(x);
|
||||
});
|
||||
}
|
||||
var output = readonly(this.pipeline);
|
||||
if (cb) {
|
||||
output.on('error', cb);
|
||||
output.pipe(concat(function (body) {
|
||||
cb(null, body);
|
||||
}));
|
||||
}
|
||||
|
||||
function ready () {
|
||||
self.emit('bundle', output);
|
||||
self.pipeline.end();
|
||||
}
|
||||
|
||||
if (this._pending === 0) ready();
|
||||
else this.once('_ready', ready);
|
||||
|
||||
this._bundled = true;
|
||||
return output;
|
||||
};
|
||||
|
||||
function isStream (s) { return s && typeof s.pipe === 'function' }
|
||||
function isAbsolutePath (file) {
|
||||
var regexp = process.platform === 'win32' ?
|
||||
/^\w:/ :
|
||||
/^\//;
|
||||
return regexp.test(file);
|
||||
}
|
||||
function isExternalModule (file) {
|
||||
var regexp = process.platform === 'win32' ?
|
||||
/^(\.|\w:)/ :
|
||||
/^[\/.]/;
|
||||
return !regexp.test(file);
|
||||
}
|
||||
function relativePath (from, to) {
|
||||
// Replace \ with / for OS-independent behavior
|
||||
return cachedPathRelative(from, to).replace(/\\/g, '/');
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
exports.assert = require.resolve('assert/');
|
||||
exports.buffer = require.resolve('buffer/');
|
||||
exports.child_process = require.resolve('./_empty.js');
|
||||
exports.cluster = require.resolve('./_empty.js');
|
||||
exports.console = require.resolve('console-browserify');
|
||||
exports.constants = require.resolve('constants-browserify');
|
||||
exports.crypto = require.resolve('crypto-browserify');
|
||||
exports.dgram = require.resolve('./_empty.js');
|
||||
exports.dns = require.resolve('./_empty.js');
|
||||
exports.domain = require.resolve('domain-browser');
|
||||
exports.events = require.resolve('events/');
|
||||
exports.fs = require.resolve('./_empty.js');
|
||||
exports.http = require.resolve('stream-http');
|
||||
exports.https = require.resolve('https-browserify');
|
||||
exports.http2 = require.resolve('./_empty.js');
|
||||
exports.inspector = require.resolve('./_empty.js');
|
||||
exports.module = require.resolve('./_empty.js');
|
||||
exports.net = require.resolve('./_empty.js');
|
||||
exports.os = require.resolve('os-browserify/browser.js');
|
||||
exports.path = require.resolve('path-browserify');
|
||||
exports.perf_hooks = require.resolve('./_empty.js')
|
||||
exports.punycode = require.resolve('punycode/');
|
||||
exports.querystring = require.resolve('querystring-es3/');
|
||||
exports.readline = require.resolve('./_empty.js');
|
||||
exports.repl = require.resolve('./_empty.js');
|
||||
exports.stream = require.resolve('stream-browserify');
|
||||
exports._stream_duplex = require.resolve('readable-stream/duplex.js');
|
||||
exports._stream_passthrough = require.resolve('readable-stream/passthrough.js');
|
||||
exports._stream_readable = require.resolve('readable-stream/readable.js');
|
||||
exports._stream_transform = require.resolve('readable-stream/transform.js');
|
||||
exports._stream_writable = require.resolve('readable-stream/writable.js');
|
||||
exports.string_decoder = require.resolve('string_decoder/');
|
||||
exports.sys = require.resolve('util/util.js');
|
||||
exports.timers = require.resolve('timers-browserify');
|
||||
exports.tls = require.resolve('./_empty.js');
|
||||
exports.tty = require.resolve('tty-browserify');
|
||||
exports.url = require.resolve('url/');
|
||||
exports.util = require.resolve('util/util.js');
|
||||
exports.vm = require.resolve('vm-browserify');
|
||||
exports.zlib = require.resolve('browserify-zlib');
|
||||
exports._process = require.resolve('process/browser');
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
# brace-expansion
|
||||
|
||||
[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html),
|
||||
as known from sh/bash, in JavaScript.
|
||||
|
||||
[](http://travis-ci.org/juliangruber/brace-expansion)
|
||||
[](https://www.npmjs.org/package/brace-expansion)
|
||||
[](https://greenkeeper.io/)
|
||||
|
||||
[](https://ci.testling.com/juliangruber/brace-expansion)
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
var expand = require('brace-expansion');
|
||||
|
||||
expand('file-{a,b,c}.jpg')
|
||||
// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
|
||||
|
||||
expand('-v{,,}')
|
||||
// => ['-v', '-v', '-v']
|
||||
|
||||
expand('file{0..2}.jpg')
|
||||
// => ['file0.jpg', 'file1.jpg', 'file2.jpg']
|
||||
|
||||
expand('file-{a..c}.jpg')
|
||||
// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
|
||||
|
||||
expand('file{2..0}.jpg')
|
||||
// => ['file2.jpg', 'file1.jpg', 'file0.jpg']
|
||||
|
||||
expand('file{0..4..2}.jpg')
|
||||
// => ['file0.jpg', 'file2.jpg', 'file4.jpg']
|
||||
|
||||
expand('file-{a..e..2}.jpg')
|
||||
// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg']
|
||||
|
||||
expand('file{00..10..5}.jpg')
|
||||
// => ['file00.jpg', 'file05.jpg', 'file10.jpg']
|
||||
|
||||
expand('{{A..C},{a..c}}')
|
||||
// => ['A', 'B', 'C', 'a', 'b', 'c']
|
||||
|
||||
expand('ppp{,config,oe{,conf}}')
|
||||
// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf']
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var expand = require('brace-expansion');
|
||||
```
|
||||
|
||||
### var expanded = expand(str)
|
||||
|
||||
Return an array of all possible and valid expansions of `str`. If none are
|
||||
found, `[str]` is returned.
|
||||
|
||||
Valid expansions are:
|
||||
|
||||
```js
|
||||
/^(.*,)+(.+)?$/
|
||||
// {a,b,...}
|
||||
```
|
||||
|
||||
A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`.
|
||||
|
||||
```js
|
||||
/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
|
||||
// {x..y[..incr]}
|
||||
```
|
||||
|
||||
A numeric sequence from `x` to `y` inclusive, with optional increment.
|
||||
If `x` or `y` start with a leading `0`, all the numbers will be padded
|
||||
to have equal length. Negative numbers and backwards iteration work too.
|
||||
|
||||
```js
|
||||
/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
|
||||
// {x..y[..incr]}
|
||||
```
|
||||
|
||||
An alphabetic sequence from `x` to `y` inclusive, with optional increment.
|
||||
`x` and `y` must be exactly one character, and if given, `incr` must be a
|
||||
number.
|
||||
|
||||
For compatibility reasons, the string `${` is not eligible for brace expansion.
|
||||
|
||||
## Installation
|
||||
|
||||
With [npm](https://npmjs.org) do:
|
||||
|
||||
```bash
|
||||
npm install brace-expansion
|
||||
```
|
||||
|
||||
## Contributors
|
||||
|
||||
- [Julian Gruber](https://github.com/juliangruber)
|
||||
- [Isaac Z. Schlueter](https://github.com/isaacs)
|
||||
|
||||
## Sponsors
|
||||
|
||||
This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)!
|
||||
|
||||
Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)!
|
||||
|
||||
## License
|
||||
|
||||
(MIT)
|
||||
|
||||
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
var concatMap = require('concat-map');
|
||||
var balanced = require('balanced-match');
|
||||
|
||||
module.exports = expandTop;
|
||||
|
||||
var escSlash = '\0SLASH'+Math.random()+'\0';
|
||||
var escOpen = '\0OPEN'+Math.random()+'\0';
|
||||
var escClose = '\0CLOSE'+Math.random()+'\0';
|
||||
var escComma = '\0COMMA'+Math.random()+'\0';
|
||||
var escPeriod = '\0PERIOD'+Math.random()+'\0';
|
||||
|
||||
function numeric(str) {
|
||||
return parseInt(str, 10) == str
|
||||
? parseInt(str, 10)
|
||||
: str.charCodeAt(0);
|
||||
}
|
||||
|
||||
function escapeBraces(str) {
|
||||
return str.split('\\\\').join(escSlash)
|
||||
.split('\\{').join(escOpen)
|
||||
.split('\\}').join(escClose)
|
||||
.split('\\,').join(escComma)
|
||||
.split('\\.').join(escPeriod);
|
||||
}
|
||||
|
||||
function unescapeBraces(str) {
|
||||
return str.split(escSlash).join('\\')
|
||||
.split(escOpen).join('{')
|
||||
.split(escClose).join('}')
|
||||
.split(escComma).join(',')
|
||||
.split(escPeriod).join('.');
|
||||
}
|
||||
|
||||
|
||||
// Basically just str.split(","), but handling cases
|
||||
// where we have nested braced sections, which should be
|
||||
// treated as individual members, like {a,{b,c},d}
|
||||
function parseCommaParts(str) {
|
||||
if (!str)
|
||||
return [''];
|
||||
|
||||
var parts = [];
|
||||
var m = balanced('{', '}', str);
|
||||
|
||||
if (!m)
|
||||
return str.split(',');
|
||||
|
||||
var pre = m.pre;
|
||||
var body = m.body;
|
||||
var post = m.post;
|
||||
var p = pre.split(',');
|
||||
|
||||
p[p.length-1] += '{' + body + '}';
|
||||
var postParts = parseCommaParts(post);
|
||||
if (post.length) {
|
||||
p[p.length-1] += postParts.shift();
|
||||
p.push.apply(p, postParts);
|
||||
}
|
||||
|
||||
parts.push.apply(parts, p);
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
function expandTop(str) {
|
||||
if (!str)
|
||||
return [];
|
||||
|
||||
// I don't know why Bash 4.3 does this, but it does.
|
||||
// Anything starting with {} will have the first two bytes preserved
|
||||
// but *only* at the top level, so {},a}b will not expand to anything,
|
||||
// but a{},b}c will be expanded to [a}c,abc].
|
||||
// One could argue that this is a bug in Bash, but since the goal of
|
||||
// this module is to match Bash's rules, we escape a leading {}
|
||||
if (str.substr(0, 2) === '{}') {
|
||||
str = '\\{\\}' + str.substr(2);
|
||||
}
|
||||
|
||||
return expand(escapeBraces(str), true).map(unescapeBraces);
|
||||
}
|
||||
|
||||
function identity(e) {
|
||||
return e;
|
||||
}
|
||||
|
||||
function embrace(str) {
|
||||
return '{' + str + '}';
|
||||
}
|
||||
function isPadded(el) {
|
||||
return /^-?0\d/.test(el);
|
||||
}
|
||||
|
||||
function lte(i, y) {
|
||||
return i <= y;
|
||||
}
|
||||
function gte(i, y) {
|
||||
return i >= y;
|
||||
}
|
||||
|
||||
function expand(str, isTop) {
|
||||
var expansions = [];
|
||||
|
||||
var m = balanced('{', '}', str);
|
||||
if (!m || /\$$/.test(m.pre)) return [str];
|
||||
|
||||
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
||||
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
||||
var isSequence = isNumericSequence || isAlphaSequence;
|
||||
var isOptions = m.body.indexOf(',') >= 0;
|
||||
if (!isSequence && !isOptions) {
|
||||
// {a},b}
|
||||
if (m.post.match(/,.*\}/)) {
|
||||
str = m.pre + '{' + m.body + escClose + m.post;
|
||||
return expand(str);
|
||||
}
|
||||
return [str];
|
||||
}
|
||||
|
||||
var n;
|
||||
if (isSequence) {
|
||||
n = m.body.split(/\.\./);
|
||||
} else {
|
||||
n = parseCommaParts(m.body);
|
||||
if (n.length === 1) {
|
||||
// x{{a,b}}y ==> x{a}y x{b}y
|
||||
n = expand(n[0], false).map(embrace);
|
||||
if (n.length === 1) {
|
||||
var post = m.post.length
|
||||
? expand(m.post, false)
|
||||
: [''];
|
||||
return post.map(function(p) {
|
||||
return m.pre + n[0] + p;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// at this point, n is the parts, and we know it's not a comma set
|
||||
// with a single entry.
|
||||
|
||||
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
||||
var pre = m.pre;
|
||||
var post = m.post.length
|
||||
? expand(m.post, false)
|
||||
: [''];
|
||||
|
||||
var N;
|
||||
|
||||
if (isSequence) {
|
||||
var x = numeric(n[0]);
|
||||
var y = numeric(n[1]);
|
||||
var width = Math.max(n[0].length, n[1].length)
|
||||
var incr = n.length == 3
|
||||
? Math.abs(numeric(n[2]))
|
||||
: 1;
|
||||
var test = lte;
|
||||
var reverse = y < x;
|
||||
if (reverse) {
|
||||
incr *= -1;
|
||||
test = gte;
|
||||
}
|
||||
var pad = n.some(isPadded);
|
||||
|
||||
N = [];
|
||||
|
||||
for (var i = x; test(i, y); i += incr) {
|
||||
var c;
|
||||
if (isAlphaSequence) {
|
||||
c = String.fromCharCode(i);
|
||||
if (c === '\\')
|
||||
c = '';
|
||||
} else {
|
||||
c = String(i);
|
||||
if (pad) {
|
||||
var need = width - c.length;
|
||||
if (need > 0) {
|
||||
var z = new Array(need + 1).join('0');
|
||||
if (i < 0)
|
||||
c = '-' + z + c.slice(1);
|
||||
else
|
||||
c = z + c;
|
||||
}
|
||||
}
|
||||
}
|
||||
N.push(c);
|
||||
}
|
||||
} else {
|
||||
N = concatMap(n, function(el) { return expand(el, false) });
|
||||
}
|
||||
|
||||
for (var j = 0; j < N.length; j++) {
|
||||
for (var k = 0; k < post.length; k++) {
|
||||
var expansion = pre + N[j] + post[k];
|
||||
if (!isTop || isSequence || expansion)
|
||||
expansions.push(expansion);
|
||||
}
|
||||
}
|
||||
|
||||
return expansions;
|
||||
}
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "brace-expansion",
|
||||
"description": "Brace expansion as known from sh/bash",
|
||||
"version": "1.1.11",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/juliangruber/brace-expansion.git"
|
||||
},
|
||||
"homepage": "https://github.com/juliangruber/brace-expansion",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "tape test/*.js",
|
||||
"gentest": "bash test/generate.sh",
|
||||
"bench": "matcha test/perf/bench.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"matcha": "^0.7.0",
|
||||
"tape": "^4.6.0"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"name": "Julian Gruber",
|
||||
"email": "mail@juliangruber.com",
|
||||
"url": "http://juliangruber.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"testling": {
|
||||
"files": "test/*.js",
|
||||
"browsers": [
|
||||
"ie/8..latest",
|
||||
"firefox/20..latest",
|
||||
"firefox/nightly",
|
||||
"chrome/25..latest",
|
||||
"chrome/canary",
|
||||
"opera/12..latest",
|
||||
"opera/next",
|
||||
"safari/5.1..latest",
|
||||
"ipad/6.0..latest",
|
||||
"iphone/6.0..latest",
|
||||
"android-browser/4.2..latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
## Glob Logo
|
||||
|
||||
Glob's logo created by Tanya Brassie <http://tanyabrassie.com/>, licensed
|
||||
under a Creative Commons Attribution-ShareAlike 4.0 International License
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
+378
@@ -0,0 +1,378 @@
|
||||
# Glob
|
||||
|
||||
Match files using the patterns the shell uses, like stars and stuff.
|
||||
|
||||
[](https://travis-ci.org/isaacs/node-glob/) [](https://ci.appveyor.com/project/isaacs/node-glob) [](https://coveralls.io/github/isaacs/node-glob?branch=master)
|
||||
|
||||
This is a glob implementation in JavaScript. It uses the `minimatch`
|
||||
library to do its matching.
|
||||
|
||||

|
||||
|
||||
## Usage
|
||||
|
||||
Install with npm
|
||||
|
||||
```
|
||||
npm i glob
|
||||
```
|
||||
|
||||
```javascript
|
||||
var glob = require("glob")
|
||||
|
||||
// options is optional
|
||||
glob("**/*.js", options, function (er, files) {
|
||||
// files is an array of filenames.
|
||||
// If the `nonull` option is set, and nothing
|
||||
// was found, then files is ["**/*.js"]
|
||||
// er is an error object or null.
|
||||
})
|
||||
```
|
||||
|
||||
## Glob Primer
|
||||
|
||||
"Globs" are the patterns you type when you do stuff like `ls *.js` on
|
||||
the command line, or put `build/*` in a `.gitignore` file.
|
||||
|
||||
Before parsing the path part patterns, braced sections are expanded
|
||||
into a set. Braced sections start with `{` and end with `}`, with any
|
||||
number of comma-delimited sections within. Braced sections may contain
|
||||
slash characters, so `a{/b/c,bcd}` would expand into `a/b/c` and `abcd`.
|
||||
|
||||
The following characters have special magic meaning when used in a
|
||||
path portion:
|
||||
|
||||
* `*` Matches 0 or more characters in a single path portion
|
||||
* `?` Matches 1 character
|
||||
* `[...]` Matches a range of characters, similar to a RegExp range.
|
||||
If the first character of the range is `!` or `^` then it matches
|
||||
any character not in the range.
|
||||
* `!(pattern|pattern|pattern)` Matches anything that does not match
|
||||
any of the patterns provided.
|
||||
* `?(pattern|pattern|pattern)` Matches zero or one occurrence of the
|
||||
patterns provided.
|
||||
* `+(pattern|pattern|pattern)` Matches one or more occurrences of the
|
||||
patterns provided.
|
||||
* `*(a|b|c)` Matches zero or more occurrences of the patterns provided
|
||||
* `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns
|
||||
provided
|
||||
* `**` If a "globstar" is alone in a path portion, then it matches
|
||||
zero or more directories and subdirectories searching for matches.
|
||||
It does not crawl symlinked directories.
|
||||
|
||||
### Dots
|
||||
|
||||
If a file or directory path portion has a `.` as the first character,
|
||||
then it will not match any glob pattern unless that pattern's
|
||||
corresponding path part also has a `.` as its first character.
|
||||
|
||||
For example, the pattern `a/.*/c` would match the file at `a/.b/c`.
|
||||
However the pattern `a/*/c` would not, because `*` does not start with
|
||||
a dot character.
|
||||
|
||||
You can make glob treat dots as normal characters by setting
|
||||
`dot:true` in the options.
|
||||
|
||||
### Basename Matching
|
||||
|
||||
If you set `matchBase:true` in the options, and the pattern has no
|
||||
slashes in it, then it will seek for any file anywhere in the tree
|
||||
with a matching basename. For example, `*.js` would match
|
||||
`test/simple/basic.js`.
|
||||
|
||||
### Empty Sets
|
||||
|
||||
If no matching files are found, then an empty array is returned. This
|
||||
differs from the shell, where the pattern itself is returned. For
|
||||
example:
|
||||
|
||||
$ echo a*s*d*f
|
||||
a*s*d*f
|
||||
|
||||
To get the bash-style behavior, set the `nonull:true` in the options.
|
||||
|
||||
### See Also:
|
||||
|
||||
* `man sh`
|
||||
* `man bash` (Search for "Pattern Matching")
|
||||
* `man 3 fnmatch`
|
||||
* `man 5 gitignore`
|
||||
* [minimatch documentation](https://github.com/isaacs/minimatch)
|
||||
|
||||
## glob.hasMagic(pattern, [options])
|
||||
|
||||
Returns `true` if there are any special characters in the pattern, and
|
||||
`false` otherwise.
|
||||
|
||||
Note that the options affect the results. If `noext:true` is set in
|
||||
the options object, then `+(a|b)` will not be considered a magic
|
||||
pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}`
|
||||
then that is considered magical, unless `nobrace:true` is set in the
|
||||
options.
|
||||
|
||||
## glob(pattern, [options], cb)
|
||||
|
||||
* `pattern` `{String}` Pattern to be matched
|
||||
* `options` `{Object}`
|
||||
* `cb` `{Function}`
|
||||
* `err` `{Error | null}`
|
||||
* `matches` `{Array<String>}` filenames found matching the pattern
|
||||
|
||||
Perform an asynchronous glob search.
|
||||
|
||||
## glob.sync(pattern, [options])
|
||||
|
||||
* `pattern` `{String}` Pattern to be matched
|
||||
* `options` `{Object}`
|
||||
* return: `{Array<String>}` filenames found matching the pattern
|
||||
|
||||
Perform a synchronous glob search.
|
||||
|
||||
## Class: glob.Glob
|
||||
|
||||
Create a Glob object by instantiating the `glob.Glob` class.
|
||||
|
||||
```javascript
|
||||
var Glob = require("glob").Glob
|
||||
var mg = new Glob(pattern, options, cb)
|
||||
```
|
||||
|
||||
It's an EventEmitter, and starts walking the filesystem to find matches
|
||||
immediately.
|
||||
|
||||
### new glob.Glob(pattern, [options], [cb])
|
||||
|
||||
* `pattern` `{String}` pattern to search for
|
||||
* `options` `{Object}`
|
||||
* `cb` `{Function}` Called when an error occurs, or matches are found
|
||||
* `err` `{Error | null}`
|
||||
* `matches` `{Array<String>}` filenames found matching the pattern
|
||||
|
||||
Note that if the `sync` flag is set in the options, then matches will
|
||||
be immediately available on the `g.found` member.
|
||||
|
||||
### Properties
|
||||
|
||||
* `minimatch` The minimatch object that the glob uses.
|
||||
* `options` The options object passed in.
|
||||
* `aborted` Boolean which is set to true when calling `abort()`. There
|
||||
is no way at this time to continue a glob search after aborting, but
|
||||
you can re-use the statCache to avoid having to duplicate syscalls.
|
||||
* `cache` Convenience object. Each field has the following possible
|
||||
values:
|
||||
* `false` - Path does not exist
|
||||
* `true` - Path exists
|
||||
* `'FILE'` - Path exists, and is not a directory
|
||||
* `'DIR'` - Path exists, and is a directory
|
||||
* `[file, entries, ...]` - Path exists, is a directory, and the
|
||||
array value is the results of `fs.readdir`
|
||||
* `statCache` Cache of `fs.stat` results, to prevent statting the same
|
||||
path multiple times.
|
||||
* `symlinks` A record of which paths are symbolic links, which is
|
||||
relevant in resolving `**` patterns.
|
||||
* `realpathCache` An optional object which is passed to `fs.realpath`
|
||||
to minimize unnecessary syscalls. It is stored on the instantiated
|
||||
Glob object, and may be re-used.
|
||||
|
||||
### Events
|
||||
|
||||
* `end` When the matching is finished, this is emitted with all the
|
||||
matches found. If the `nonull` option is set, and no match was found,
|
||||
then the `matches` list contains the original pattern. The matches
|
||||
are sorted, unless the `nosort` flag is set.
|
||||
* `match` Every time a match is found, this is emitted with the specific
|
||||
thing that matched. It is not deduplicated or resolved to a realpath.
|
||||
* `error` Emitted when an unexpected error is encountered, or whenever
|
||||
any fs error occurs if `options.strict` is set.
|
||||
* `abort` When `abort()` is called, this event is raised.
|
||||
|
||||
### Methods
|
||||
|
||||
* `pause` Temporarily stop the search
|
||||
* `resume` Resume the search
|
||||
* `abort` Stop the search forever
|
||||
|
||||
### Options
|
||||
|
||||
All the options that can be passed to Minimatch can also be passed to
|
||||
Glob to change pattern matching behavior. Also, some have been added,
|
||||
or have glob-specific ramifications.
|
||||
|
||||
All options are false by default, unless otherwise noted.
|
||||
|
||||
All options are added to the Glob object, as well.
|
||||
|
||||
If you are running many `glob` operations, you can pass a Glob object
|
||||
as the `options` argument to a subsequent operation to shortcut some
|
||||
`stat` and `readdir` calls. At the very least, you may pass in shared
|
||||
`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that
|
||||
parallel glob operations will be sped up by sharing information about
|
||||
the filesystem.
|
||||
|
||||
* `cwd` The current working directory in which to search. Defaults
|
||||
to `process.cwd()`.
|
||||
* `root` The place where patterns starting with `/` will be mounted
|
||||
onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
|
||||
systems, and `C:\` or some such on Windows.)
|
||||
* `dot` Include `.dot` files in normal matches and `globstar` matches.
|
||||
Note that an explicit dot in a portion of the pattern will always
|
||||
match dot files.
|
||||
* `nomount` By default, a pattern starting with a forward-slash will be
|
||||
"mounted" onto the root setting, so that a valid filesystem path is
|
||||
returned. Set this flag to disable that behavior.
|
||||
* `mark` Add a `/` character to directory matches. Note that this
|
||||
requires additional stat calls.
|
||||
* `nosort` Don't sort the results.
|
||||
* `stat` Set to true to stat *all* results. This reduces performance
|
||||
somewhat, and is completely unnecessary, unless `readdir` is presumed
|
||||
to be an untrustworthy indicator of file existence.
|
||||
* `silent` When an unusual error is encountered when attempting to
|
||||
read a directory, a warning will be printed to stderr. Set the
|
||||
`silent` option to true to suppress these warnings.
|
||||
* `strict` When an unusual error is encountered when attempting to
|
||||
read a directory, the process will just continue on in search of
|
||||
other matches. Set the `strict` option to raise an error in these
|
||||
cases.
|
||||
* `cache` See `cache` property above. Pass in a previously generated
|
||||
cache object to save some fs calls.
|
||||
* `statCache` A cache of results of filesystem information, to prevent
|
||||
unnecessary stat calls. While it should not normally be necessary
|
||||
to set this, you may pass the statCache from one glob() call to the
|
||||
options object of another, if you know that the filesystem will not
|
||||
change between calls. (See "Race Conditions" below.)
|
||||
* `symlinks` A cache of known symbolic links. You may pass in a
|
||||
previously generated `symlinks` object to save `lstat` calls when
|
||||
resolving `**` matches.
|
||||
* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead.
|
||||
* `nounique` In some cases, brace-expanded patterns can result in the
|
||||
same file showing up multiple times in the result set. By default,
|
||||
this implementation prevents duplicates in the result set. Set this
|
||||
flag to disable that behavior.
|
||||
* `nonull` Set to never return an empty set, instead returning a set
|
||||
containing the pattern itself. This is the default in glob(3).
|
||||
* `debug` Set to enable debug logging in minimatch and glob.
|
||||
* `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets.
|
||||
* `noglobstar` Do not match `**` against multiple filenames. (Ie,
|
||||
treat it as a normal `*` instead.)
|
||||
* `noext` Do not match `+(a|b)` "extglob" patterns.
|
||||
* `nocase` Perform a case-insensitive match. Note: on
|
||||
case-insensitive filesystems, non-magic patterns will match by
|
||||
default, since `stat` and `readdir` will not raise errors.
|
||||
* `matchBase` Perform a basename-only match if the pattern does not
|
||||
contain any slash characters. That is, `*.js` would be treated as
|
||||
equivalent to `**/*.js`, matching all js files in all directories.
|
||||
* `nodir` Do not match directories, only files. (Note: to match
|
||||
*only* directories, simply put a `/` at the end of the pattern.)
|
||||
* `ignore` Add a pattern or an array of glob patterns to exclude matches.
|
||||
Note: `ignore` patterns are *always* in `dot:true` mode, regardless
|
||||
of any other settings.
|
||||
* `follow` Follow symlinked directories when expanding `**` patterns.
|
||||
Note that this can result in a lot of duplicate references in the
|
||||
presence of cyclic links.
|
||||
* `realpath` Set to true to call `fs.realpath` on all of the results.
|
||||
In the case of a symlink that cannot be resolved, the full absolute
|
||||
path to the matched entry is returned (though it will usually be a
|
||||
broken symlink)
|
||||
* `absolute` Set to true to always receive absolute paths for matched
|
||||
files. Unlike `realpath`, this also affects the values returned in
|
||||
the `match` event.
|
||||
* `fs` File-system object with Node's `fs` API. By default, the built-in
|
||||
`fs` module will be used. Set to a volume provided by a library like
|
||||
`memfs` to avoid using the "real" file-system.
|
||||
|
||||
## Comparisons to other fnmatch/glob implementations
|
||||
|
||||
While strict compliance with the existing standards is a worthwhile
|
||||
goal, some discrepancies exist between node-glob and other
|
||||
implementations, and are intentional.
|
||||
|
||||
The double-star character `**` is supported by default, unless the
|
||||
`noglobstar` flag is set. This is supported in the manner of bsdglob
|
||||
and bash 4.3, where `**` only has special significance if it is the only
|
||||
thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
|
||||
`a/**b` will not.
|
||||
|
||||
Note that symlinked directories are not crawled as part of a `**`,
|
||||
though their contents may match against subsequent portions of the
|
||||
pattern. This prevents infinite loops and duplicates and the like.
|
||||
|
||||
If an escaped pattern has no matches, and the `nonull` flag is set,
|
||||
then glob returns the pattern as-provided, rather than
|
||||
interpreting the character escapes. For example,
|
||||
`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
|
||||
`"*a?"`. This is akin to setting the `nullglob` option in bash, except
|
||||
that it does not resolve escaped pattern characters.
|
||||
|
||||
If brace expansion is not disabled, then it is performed before any
|
||||
other interpretation of the glob pattern. Thus, a pattern like
|
||||
`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
|
||||
**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
|
||||
checked for validity. Since those two are valid, matching proceeds.
|
||||
|
||||
### Comments and Negation
|
||||
|
||||
Previously, this module let you mark a pattern as a "comment" if it
|
||||
started with a `#` character, or a "negated" pattern if it started
|
||||
with a `!` character.
|
||||
|
||||
These options were deprecated in version 5, and removed in version 6.
|
||||
|
||||
To specify things that should not match, use the `ignore` option.
|
||||
|
||||
## Windows
|
||||
|
||||
**Please only use forward-slashes in glob expressions.**
|
||||
|
||||
Though windows uses either `/` or `\` as its path separator, only `/`
|
||||
characters are used by this glob implementation. You must use
|
||||
forward-slashes **only** in glob expressions. Back-slashes will always
|
||||
be interpreted as escape characters, not path separators.
|
||||
|
||||
Results from absolute patterns such as `/foo/*` are mounted onto the
|
||||
root setting using `path.join`. On windows, this will by default result
|
||||
in `/foo/*` matching `C:\foo\bar.txt`.
|
||||
|
||||
## Race Conditions
|
||||
|
||||
Glob searching, by its very nature, is susceptible to race conditions,
|
||||
since it relies on directory walking and such.
|
||||
|
||||
As a result, it is possible that a file that exists when glob looks for
|
||||
it may have been deleted or modified by the time it returns the result.
|
||||
|
||||
As part of its internal implementation, this program caches all stat
|
||||
and readdir calls that it makes, in order to cut down on system
|
||||
overhead. However, this also makes it even more susceptible to races,
|
||||
especially if the cache or statCache objects are reused between glob
|
||||
calls.
|
||||
|
||||
Users are thus advised not to use a glob result as a guarantee of
|
||||
filesystem state in the face of rapid changes. For the vast majority
|
||||
of operations, this is never a problem.
|
||||
|
||||
## Glob Logo
|
||||
Glob's logo was created by [Tanya Brassie](http://tanyabrassie.com/). Logo files can be found [here](https://github.com/isaacs/node-glob/tree/master/logo).
|
||||
|
||||
The logo is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||
|
||||
## Contributing
|
||||
|
||||
Any change to behavior (including bugfixes) must come with a test.
|
||||
|
||||
Patches that fail tests or reduce performance will be rejected.
|
||||
|
||||
```
|
||||
# to run tests
|
||||
npm test
|
||||
|
||||
# to re-generate test fixtures
|
||||
npm run test-regen
|
||||
|
||||
# to benchmark against bash/zsh
|
||||
npm run bench
|
||||
|
||||
# to profile javascript
|
||||
npm run prof
|
||||
```
|
||||
|
||||

|
||||
+238
@@ -0,0 +1,238 @@
|
||||
exports.setopts = setopts
|
||||
exports.ownProp = ownProp
|
||||
exports.makeAbs = makeAbs
|
||||
exports.finish = finish
|
||||
exports.mark = mark
|
||||
exports.isIgnored = isIgnored
|
||||
exports.childrenIgnored = childrenIgnored
|
||||
|
||||
function ownProp (obj, field) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, field)
|
||||
}
|
||||
|
||||
var fs = require("fs")
|
||||
var path = require("path")
|
||||
var minimatch = require("minimatch")
|
||||
var isAbsolute = require("path-is-absolute")
|
||||
var Minimatch = minimatch.Minimatch
|
||||
|
||||
function alphasort (a, b) {
|
||||
return a.localeCompare(b, 'en')
|
||||
}
|
||||
|
||||
function setupIgnores (self, options) {
|
||||
self.ignore = options.ignore || []
|
||||
|
||||
if (!Array.isArray(self.ignore))
|
||||
self.ignore = [self.ignore]
|
||||
|
||||
if (self.ignore.length) {
|
||||
self.ignore = self.ignore.map(ignoreMap)
|
||||
}
|
||||
}
|
||||
|
||||
// ignore patterns are always in dot:true mode.
|
||||
function ignoreMap (pattern) {
|
||||
var gmatcher = null
|
||||
if (pattern.slice(-3) === '/**') {
|
||||
var gpattern = pattern.replace(/(\/\*\*)+$/, '')
|
||||
gmatcher = new Minimatch(gpattern, { dot: true })
|
||||
}
|
||||
|
||||
return {
|
||||
matcher: new Minimatch(pattern, { dot: true }),
|
||||
gmatcher: gmatcher
|
||||
}
|
||||
}
|
||||
|
||||
function setopts (self, pattern, options) {
|
||||
if (!options)
|
||||
options = {}
|
||||
|
||||
// base-matching: just use globstar for that.
|
||||
if (options.matchBase && -1 === pattern.indexOf("/")) {
|
||||
if (options.noglobstar) {
|
||||
throw new Error("base matching requires globstar")
|
||||
}
|
||||
pattern = "**/" + pattern
|
||||
}
|
||||
|
||||
self.silent = !!options.silent
|
||||
self.pattern = pattern
|
||||
self.strict = options.strict !== false
|
||||
self.realpath = !!options.realpath
|
||||
self.realpathCache = options.realpathCache || Object.create(null)
|
||||
self.follow = !!options.follow
|
||||
self.dot = !!options.dot
|
||||
self.mark = !!options.mark
|
||||
self.nodir = !!options.nodir
|
||||
if (self.nodir)
|
||||
self.mark = true
|
||||
self.sync = !!options.sync
|
||||
self.nounique = !!options.nounique
|
||||
self.nonull = !!options.nonull
|
||||
self.nosort = !!options.nosort
|
||||
self.nocase = !!options.nocase
|
||||
self.stat = !!options.stat
|
||||
self.noprocess = !!options.noprocess
|
||||
self.absolute = !!options.absolute
|
||||
self.fs = options.fs || fs
|
||||
|
||||
self.maxLength = options.maxLength || Infinity
|
||||
self.cache = options.cache || Object.create(null)
|
||||
self.statCache = options.statCache || Object.create(null)
|
||||
self.symlinks = options.symlinks || Object.create(null)
|
||||
|
||||
setupIgnores(self, options)
|
||||
|
||||
self.changedCwd = false
|
||||
var cwd = process.cwd()
|
||||
if (!ownProp(options, "cwd"))
|
||||
self.cwd = cwd
|
||||
else {
|
||||
self.cwd = path.resolve(options.cwd)
|
||||
self.changedCwd = self.cwd !== cwd
|
||||
}
|
||||
|
||||
self.root = options.root || path.resolve(self.cwd, "/")
|
||||
self.root = path.resolve(self.root)
|
||||
if (process.platform === "win32")
|
||||
self.root = self.root.replace(/\\/g, "/")
|
||||
|
||||
// TODO: is an absolute `cwd` supposed to be resolved against `root`?
|
||||
// e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test')
|
||||
self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd)
|
||||
if (process.platform === "win32")
|
||||
self.cwdAbs = self.cwdAbs.replace(/\\/g, "/")
|
||||
self.nomount = !!options.nomount
|
||||
|
||||
// disable comments and negation in Minimatch.
|
||||
// Note that they are not supported in Glob itself anyway.
|
||||
options.nonegate = true
|
||||
options.nocomment = true
|
||||
// always treat \ in patterns as escapes, not path separators
|
||||
options.allowWindowsEscape = false
|
||||
|
||||
self.minimatch = new Minimatch(pattern, options)
|
||||
self.options = self.minimatch.options
|
||||
}
|
||||
|
||||
function finish (self) {
|
||||
var nou = self.nounique
|
||||
var all = nou ? [] : Object.create(null)
|
||||
|
||||
for (var i = 0, l = self.matches.length; i < l; i ++) {
|
||||
var matches = self.matches[i]
|
||||
if (!matches || Object.keys(matches).length === 0) {
|
||||
if (self.nonull) {
|
||||
// do like the shell, and spit out the literal glob
|
||||
var literal = self.minimatch.globSet[i]
|
||||
if (nou)
|
||||
all.push(literal)
|
||||
else
|
||||
all[literal] = true
|
||||
}
|
||||
} else {
|
||||
// had matches
|
||||
var m = Object.keys(matches)
|
||||
if (nou)
|
||||
all.push.apply(all, m)
|
||||
else
|
||||
m.forEach(function (m) {
|
||||
all[m] = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (!nou)
|
||||
all = Object.keys(all)
|
||||
|
||||
if (!self.nosort)
|
||||
all = all.sort(alphasort)
|
||||
|
||||
// at *some* point we statted all of these
|
||||
if (self.mark) {
|
||||
for (var i = 0; i < all.length; i++) {
|
||||
all[i] = self._mark(all[i])
|
||||
}
|
||||
if (self.nodir) {
|
||||
all = all.filter(function (e) {
|
||||
var notDir = !(/\/$/.test(e))
|
||||
var c = self.cache[e] || self.cache[makeAbs(self, e)]
|
||||
if (notDir && c)
|
||||
notDir = c !== 'DIR' && !Array.isArray(c)
|
||||
return notDir
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (self.ignore.length)
|
||||
all = all.filter(function(m) {
|
||||
return !isIgnored(self, m)
|
||||
})
|
||||
|
||||
self.found = all
|
||||
}
|
||||
|
||||
function mark (self, p) {
|
||||
var abs = makeAbs(self, p)
|
||||
var c = self.cache[abs]
|
||||
var m = p
|
||||
if (c) {
|
||||
var isDir = c === 'DIR' || Array.isArray(c)
|
||||
var slash = p.slice(-1) === '/'
|
||||
|
||||
if (isDir && !slash)
|
||||
m += '/'
|
||||
else if (!isDir && slash)
|
||||
m = m.slice(0, -1)
|
||||
|
||||
if (m !== p) {
|
||||
var mabs = makeAbs(self, m)
|
||||
self.statCache[mabs] = self.statCache[abs]
|
||||
self.cache[mabs] = self.cache[abs]
|
||||
}
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// lotta situps...
|
||||
function makeAbs (self, f) {
|
||||
var abs = f
|
||||
if (f.charAt(0) === '/') {
|
||||
abs = path.join(self.root, f)
|
||||
} else if (isAbsolute(f) || f === '') {
|
||||
abs = f
|
||||
} else if (self.changedCwd) {
|
||||
abs = path.resolve(self.cwd, f)
|
||||
} else {
|
||||
abs = path.resolve(f)
|
||||
}
|
||||
|
||||
if (process.platform === 'win32')
|
||||
abs = abs.replace(/\\/g, '/')
|
||||
|
||||
return abs
|
||||
}
|
||||
|
||||
|
||||
// Return true, if pattern ends with globstar '**', for the accompanying parent directory.
|
||||
// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents
|
||||
function isIgnored (self, path) {
|
||||
if (!self.ignore.length)
|
||||
return false
|
||||
|
||||
return self.ignore.some(function(item) {
|
||||
return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path))
|
||||
})
|
||||
}
|
||||
|
||||
function childrenIgnored (self, path) {
|
||||
if (!self.ignore.length)
|
||||
return false
|
||||
|
||||
return self.ignore.some(function(item) {
|
||||
return !!(item.gmatcher && item.gmatcher.match(path))
|
||||
})
|
||||
}
|
||||
+790
@@ -0,0 +1,790 @@
|
||||
// Approach:
|
||||
//
|
||||
// 1. Get the minimatch set
|
||||
// 2. For each pattern in the set, PROCESS(pattern, false)
|
||||
// 3. Store matches per-set, then uniq them
|
||||
//
|
||||
// PROCESS(pattern, inGlobStar)
|
||||
// Get the first [n] items from pattern that are all strings
|
||||
// Join these together. This is PREFIX.
|
||||
// If there is no more remaining, then stat(PREFIX) and
|
||||
// add to matches if it succeeds. END.
|
||||
//
|
||||
// If inGlobStar and PREFIX is symlink and points to dir
|
||||
// set ENTRIES = []
|
||||
// else readdir(PREFIX) as ENTRIES
|
||||
// If fail, END
|
||||
//
|
||||
// with ENTRIES
|
||||
// If pattern[n] is GLOBSTAR
|
||||
// // handle the case where the globstar match is empty
|
||||
// // by pruning it out, and testing the resulting pattern
|
||||
// PROCESS(pattern[0..n] + pattern[n+1 .. $], false)
|
||||
// // handle other cases.
|
||||
// for ENTRY in ENTRIES (not dotfiles)
|
||||
// // attach globstar + tail onto the entry
|
||||
// // Mark that this entry is a globstar match
|
||||
// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true)
|
||||
//
|
||||
// else // not globstar
|
||||
// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
|
||||
// Test ENTRY against pattern[n]
|
||||
// If fails, continue
|
||||
// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
|
||||
//
|
||||
// Caveat:
|
||||
// Cache all stats and readdirs results to minimize syscall. Since all
|
||||
// we ever care about is existence and directory-ness, we can just keep
|
||||
// `true` for files, and [children,...] for directories, or `false` for
|
||||
// things that don't exist.
|
||||
|
||||
module.exports = glob
|
||||
|
||||
var rp = require('fs.realpath')
|
||||
var minimatch = require('minimatch')
|
||||
var Minimatch = minimatch.Minimatch
|
||||
var inherits = require('inherits')
|
||||
var EE = require('events').EventEmitter
|
||||
var path = require('path')
|
||||
var assert = require('assert')
|
||||
var isAbsolute = require('path-is-absolute')
|
||||
var globSync = require('./sync.js')
|
||||
var common = require('./common.js')
|
||||
var setopts = common.setopts
|
||||
var ownProp = common.ownProp
|
||||
var inflight = require('inflight')
|
||||
var util = require('util')
|
||||
var childrenIgnored = common.childrenIgnored
|
||||
var isIgnored = common.isIgnored
|
||||
|
||||
var once = require('once')
|
||||
|
||||
function glob (pattern, options, cb) {
|
||||
if (typeof options === 'function') cb = options, options = {}
|
||||
if (!options) options = {}
|
||||
|
||||
if (options.sync) {
|
||||
if (cb)
|
||||
throw new TypeError('callback provided to sync glob')
|
||||
return globSync(pattern, options)
|
||||
}
|
||||
|
||||
return new Glob(pattern, options, cb)
|
||||
}
|
||||
|
||||
glob.sync = globSync
|
||||
var GlobSync = glob.GlobSync = globSync.GlobSync
|
||||
|
||||
// old api surface
|
||||
glob.glob = glob
|
||||
|
||||
function extend (origin, add) {
|
||||
if (add === null || typeof add !== 'object') {
|
||||
return origin
|
||||
}
|
||||
|
||||
var keys = Object.keys(add)
|
||||
var i = keys.length
|
||||
while (i--) {
|
||||
origin[keys[i]] = add[keys[i]]
|
||||
}
|
||||
return origin
|
||||
}
|
||||
|
||||
glob.hasMagic = function (pattern, options_) {
|
||||
var options = extend({}, options_)
|
||||
options.noprocess = true
|
||||
|
||||
var g = new Glob(pattern, options)
|
||||
var set = g.minimatch.set
|
||||
|
||||
if (!pattern)
|
||||
return false
|
||||
|
||||
if (set.length > 1)
|
||||
return true
|
||||
|
||||
for (var j = 0; j < set[0].length; j++) {
|
||||
if (typeof set[0][j] !== 'string')
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
glob.Glob = Glob
|
||||
inherits(Glob, EE)
|
||||
function Glob (pattern, options, cb) {
|
||||
if (typeof options === 'function') {
|
||||
cb = options
|
||||
options = null
|
||||
}
|
||||
|
||||
if (options && options.sync) {
|
||||
if (cb)
|
||||
throw new TypeError('callback provided to sync glob')
|
||||
return new GlobSync(pattern, options)
|
||||
}
|
||||
|
||||
if (!(this instanceof Glob))
|
||||
return new Glob(pattern, options, cb)
|
||||
|
||||
setopts(this, pattern, options)
|
||||
this._didRealPath = false
|
||||
|
||||
// process each pattern in the minimatch set
|
||||
var n = this.minimatch.set.length
|
||||
|
||||
// The matches are stored as {<filename>: true,...} so that
|
||||
// duplicates are automagically pruned.
|
||||
// Later, we do an Object.keys() on these.
|
||||
// Keep them as a list so we can fill in when nonull is set.
|
||||
this.matches = new Array(n)
|
||||
|
||||
if (typeof cb === 'function') {
|
||||
cb = once(cb)
|
||||
this.on('error', cb)
|
||||
this.on('end', function (matches) {
|
||||
cb(null, matches)
|
||||
})
|
||||
}
|
||||
|
||||
var self = this
|
||||
this._processing = 0
|
||||
|
||||
this._emitQueue = []
|
||||
this._processQueue = []
|
||||
this.paused = false
|
||||
|
||||
if (this.noprocess)
|
||||
return this
|
||||
|
||||
if (n === 0)
|
||||
return done()
|
||||
|
||||
var sync = true
|
||||
for (var i = 0; i < n; i ++) {
|
||||
this._process(this.minimatch.set[i], i, false, done)
|
||||
}
|
||||
sync = false
|
||||
|
||||
function done () {
|
||||
--self._processing
|
||||
if (self._processing <= 0) {
|
||||
if (sync) {
|
||||
process.nextTick(function () {
|
||||
self._finish()
|
||||
})
|
||||
} else {
|
||||
self._finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Glob.prototype._finish = function () {
|
||||
assert(this instanceof Glob)
|
||||
if (this.aborted)
|
||||
return
|
||||
|
||||
if (this.realpath && !this._didRealpath)
|
||||
return this._realpath()
|
||||
|
||||
common.finish(this)
|
||||
this.emit('end', this.found)
|
||||
}
|
||||
|
||||
Glob.prototype._realpath = function () {
|
||||
if (this._didRealpath)
|
||||
return
|
||||
|
||||
this._didRealpath = true
|
||||
|
||||
var n = this.matches.length
|
||||
if (n === 0)
|
||||
return this._finish()
|
||||
|
||||
var self = this
|
||||
for (var i = 0; i < this.matches.length; i++)
|
||||
this._realpathSet(i, next)
|
||||
|
||||
function next () {
|
||||
if (--n === 0)
|
||||
self._finish()
|
||||
}
|
||||
}
|
||||
|
||||
Glob.prototype._realpathSet = function (index, cb) {
|
||||
var matchset = this.matches[index]
|
||||
if (!matchset)
|
||||
return cb()
|
||||
|
||||
var found = Object.keys(matchset)
|
||||
var self = this
|
||||
var n = found.length
|
||||
|
||||
if (n === 0)
|
||||
return cb()
|
||||
|
||||
var set = this.matches[index] = Object.create(null)
|
||||
found.forEach(function (p, i) {
|
||||
// If there's a problem with the stat, then it means that
|
||||
// one or more of the links in the realpath couldn't be
|
||||
// resolved. just return the abs value in that case.
|
||||
p = self._makeAbs(p)
|
||||
rp.realpath(p, self.realpathCache, function (er, real) {
|
||||
if (!er)
|
||||
set[real] = true
|
||||
else if (er.syscall === 'stat')
|
||||
set[p] = true
|
||||
else
|
||||
self.emit('error', er) // srsly wtf right here
|
||||
|
||||
if (--n === 0) {
|
||||
self.matches[index] = set
|
||||
cb()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Glob.prototype._mark = function (p) {
|
||||
return common.mark(this, p)
|
||||
}
|
||||
|
||||
Glob.prototype._makeAbs = function (f) {
|
||||
return common.makeAbs(this, f)
|
||||
}
|
||||
|
||||
Glob.prototype.abort = function () {
|
||||
this.aborted = true
|
||||
this.emit('abort')
|
||||
}
|
||||
|
||||
Glob.prototype.pause = function () {
|
||||
if (!this.paused) {
|
||||
this.paused = true
|
||||
this.emit('pause')
|
||||
}
|
||||
}
|
||||
|
||||
Glob.prototype.resume = function () {
|
||||
if (this.paused) {
|
||||
this.emit('resume')
|
||||
this.paused = false
|
||||
if (this._emitQueue.length) {
|
||||
var eq = this._emitQueue.slice(0)
|
||||
this._emitQueue.length = 0
|
||||
for (var i = 0; i < eq.length; i ++) {
|
||||
var e = eq[i]
|
||||
this._emitMatch(e[0], e[1])
|
||||
}
|
||||
}
|
||||
if (this._processQueue.length) {
|
||||
var pq = this._processQueue.slice(0)
|
||||
this._processQueue.length = 0
|
||||
for (var i = 0; i < pq.length; i ++) {
|
||||
var p = pq[i]
|
||||
this._processing--
|
||||
this._process(p[0], p[1], p[2], p[3])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Glob.prototype._process = function (pattern, index, inGlobStar, cb) {
|
||||
assert(this instanceof Glob)
|
||||
assert(typeof cb === 'function')
|
||||
|
||||
if (this.aborted)
|
||||
return
|
||||
|
||||
this._processing++
|
||||
if (this.paused) {
|
||||
this._processQueue.push([pattern, index, inGlobStar, cb])
|
||||
return
|
||||
}
|
||||
|
||||
//console.error('PROCESS %d', this._processing, pattern)
|
||||
|
||||
// Get the first [n] parts of pattern that are all strings.
|
||||
var n = 0
|
||||
while (typeof pattern[n] === 'string') {
|
||||
n ++
|
||||
}
|
||||
// now n is the index of the first one that is *not* a string.
|
||||
|
||||
// see if there's anything else
|
||||
var prefix
|
||||
switch (n) {
|
||||
// if not, then this is rather simple
|
||||
case pattern.length:
|
||||
this._processSimple(pattern.join('/'), index, cb)
|
||||
return
|
||||
|
||||
case 0:
|
||||
// pattern *starts* with some non-trivial item.
|
||||
// going to readdir(cwd), but not include the prefix in matches.
|
||||
prefix = null
|
||||
break
|
||||
|
||||
default:
|
||||
// pattern has some string bits in the front.
|
||||
// whatever it starts with, whether that's 'absolute' like /foo/bar,
|
||||
// or 'relative' like '../baz'
|
||||
prefix = pattern.slice(0, n).join('/')
|
||||
break
|
||||
}
|
||||
|
||||
var remain = pattern.slice(n)
|
||||
|
||||
// get the list of entries.
|
||||
var read
|
||||
if (prefix === null)
|
||||
read = '.'
|
||||
else if (isAbsolute(prefix) ||
|
||||
isAbsolute(pattern.map(function (p) {
|
||||
return typeof p === 'string' ? p : '[*]'
|
||||
}).join('/'))) {
|
||||
if (!prefix || !isAbsolute(prefix))
|
||||
prefix = '/' + prefix
|
||||
read = prefix
|
||||
} else
|
||||
read = prefix
|
||||
|
||||
var abs = this._makeAbs(read)
|
||||
|
||||
//if ignored, skip _processing
|
||||
if (childrenIgnored(this, read))
|
||||
return cb()
|
||||
|
||||
var isGlobStar = remain[0] === minimatch.GLOBSTAR
|
||||
if (isGlobStar)
|
||||
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb)
|
||||
else
|
||||
this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb)
|
||||
}
|
||||
|
||||
Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) {
|
||||
var self = this
|
||||
this._readdir(abs, inGlobStar, function (er, entries) {
|
||||
return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
|
||||
})
|
||||
}
|
||||
|
||||
Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
|
||||
|
||||
// if the abs isn't a dir, then nothing can match!
|
||||
if (!entries)
|
||||
return cb()
|
||||
|
||||
// It will only match dot entries if it starts with a dot, or if
|
||||
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
||||
var pn = remain[0]
|
||||
var negate = !!this.minimatch.negate
|
||||
var rawGlob = pn._glob
|
||||
var dotOk = this.dot || rawGlob.charAt(0) === '.'
|
||||
|
||||
var matchedEntries = []
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
var e = entries[i]
|
||||
if (e.charAt(0) !== '.' || dotOk) {
|
||||
var m
|
||||
if (negate && !prefix) {
|
||||
m = !e.match(pn)
|
||||
} else {
|
||||
m = e.match(pn)
|
||||
}
|
||||
if (m)
|
||||
matchedEntries.push(e)
|
||||
}
|
||||
}
|
||||
|
||||
//console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries)
|
||||
|
||||
var len = matchedEntries.length
|
||||
// If there are no matched entries, then nothing matches.
|
||||
if (len === 0)
|
||||
return cb()
|
||||
|
||||
// if this is the last remaining pattern bit, then no need for
|
||||
// an additional stat *unless* the user has specified mark or
|
||||
// stat explicitly. We know they exist, since readdir returned
|
||||
// them.
|
||||
|
||||
if (remain.length === 1 && !this.mark && !this.stat) {
|
||||
if (!this.matches[index])
|
||||
this.matches[index] = Object.create(null)
|
||||
|
||||
for (var i = 0; i < len; i ++) {
|
||||
var e = matchedEntries[i]
|
||||
if (prefix) {
|
||||
if (prefix !== '/')
|
||||
e = prefix + '/' + e
|
||||
else
|
||||
e = prefix + e
|
||||
}
|
||||
|
||||
if (e.charAt(0) === '/' && !this.nomount) {
|
||||
e = path.join(this.root, e)
|
||||
}
|
||||
this._emitMatch(index, e)
|
||||
}
|
||||
// This was the last one, and no stats were needed
|
||||
return cb()
|
||||
}
|
||||
|
||||
// now test all matched entries as stand-ins for that part
|
||||
// of the pattern.
|
||||
remain.shift()
|
||||
for (var i = 0; i < len; i ++) {
|
||||
var e = matchedEntries[i]
|
||||
var newPattern
|
||||
if (prefix) {
|
||||
if (prefix !== '/')
|
||||
e = prefix + '/' + e
|
||||
else
|
||||
e = prefix + e
|
||||
}
|
||||
this._process([e].concat(remain), index, inGlobStar, cb)
|
||||
}
|
||||
cb()
|
||||
}
|
||||
|
||||
Glob.prototype._emitMatch = function (index, e) {
|
||||
if (this.aborted)
|
||||
return
|
||||
|
||||
if (isIgnored(this, e))
|
||||
return
|
||||
|
||||
if (this.paused) {
|
||||
this._emitQueue.push([index, e])
|
||||
return
|
||||
}
|
||||
|
||||
var abs = isAbsolute(e) ? e : this._makeAbs(e)
|
||||
|
||||
if (this.mark)
|
||||
e = this._mark(e)
|
||||
|
||||
if (this.absolute)
|
||||
e = abs
|
||||
|
||||
if (this.matches[index][e])
|
||||
return
|
||||
|
||||
if (this.nodir) {
|
||||
var c = this.cache[abs]
|
||||
if (c === 'DIR' || Array.isArray(c))
|
||||
return
|
||||
}
|
||||
|
||||
this.matches[index][e] = true
|
||||
|
||||
var st = this.statCache[abs]
|
||||
if (st)
|
||||
this.emit('stat', e, st)
|
||||
|
||||
this.emit('match', e)
|
||||
}
|
||||
|
||||
Glob.prototype._readdirInGlobStar = function (abs, cb) {
|
||||
if (this.aborted)
|
||||
return
|
||||
|
||||
// follow all symlinked directories forever
|
||||
// just proceed as if this is a non-globstar situation
|
||||
if (this.follow)
|
||||
return this._readdir(abs, false, cb)
|
||||
|
||||
var lstatkey = 'lstat\0' + abs
|
||||
var self = this
|
||||
var lstatcb = inflight(lstatkey, lstatcb_)
|
||||
|
||||
if (lstatcb)
|
||||
self.fs.lstat(abs, lstatcb)
|
||||
|
||||
function lstatcb_ (er, lstat) {
|
||||
if (er && er.code === 'ENOENT')
|
||||
return cb()
|
||||
|
||||
var isSym = lstat && lstat.isSymbolicLink()
|
||||
self.symlinks[abs] = isSym
|
||||
|
||||
// If it's not a symlink or a dir, then it's definitely a regular file.
|
||||
// don't bother doing a readdir in that case.
|
||||
if (!isSym && lstat && !lstat.isDirectory()) {
|
||||
self.cache[abs] = 'FILE'
|
||||
cb()
|
||||
} else
|
||||
self._readdir(abs, false, cb)
|
||||
}
|
||||
}
|
||||
|
||||
Glob.prototype._readdir = function (abs, inGlobStar, cb) {
|
||||
if (this.aborted)
|
||||
return
|
||||
|
||||
cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb)
|
||||
if (!cb)
|
||||
return
|
||||
|
||||
//console.error('RD %j %j', +inGlobStar, abs)
|
||||
if (inGlobStar && !ownProp(this.symlinks, abs))
|
||||
return this._readdirInGlobStar(abs, cb)
|
||||
|
||||
if (ownProp(this.cache, abs)) {
|
||||
var c = this.cache[abs]
|
||||
if (!c || c === 'FILE')
|
||||
return cb()
|
||||
|
||||
if (Array.isArray(c))
|
||||
return cb(null, c)
|
||||
}
|
||||
|
||||
var self = this
|
||||
self.fs.readdir(abs, readdirCb(this, abs, cb))
|
||||
}
|
||||
|
||||
function readdirCb (self, abs, cb) {
|
||||
return function (er, entries) {
|
||||
if (er)
|
||||
self._readdirError(abs, er, cb)
|
||||
else
|
||||
self._readdirEntries(abs, entries, cb)
|
||||
}
|
||||
}
|
||||
|
||||
Glob.prototype._readdirEntries = function (abs, entries, cb) {
|
||||
if (this.aborted)
|
||||
return
|
||||
|
||||
// if we haven't asked to stat everything, then just
|
||||
// assume that everything in there exists, so we can avoid
|
||||
// having to stat it a second time.
|
||||
if (!this.mark && !this.stat) {
|
||||
for (var i = 0; i < entries.length; i ++) {
|
||||
var e = entries[i]
|
||||
if (abs === '/')
|
||||
e = abs + e
|
||||
else
|
||||
e = abs + '/' + e
|
||||
this.cache[e] = true
|
||||
}
|
||||
}
|
||||
|
||||
this.cache[abs] = entries
|
||||
return cb(null, entries)
|
||||
}
|
||||
|
||||
Glob.prototype._readdirError = function (f, er, cb) {
|
||||
if (this.aborted)
|
||||
return
|
||||
|
||||
// handle errors, and cache the information
|
||||
switch (er.code) {
|
||||
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
|
||||
case 'ENOTDIR': // totally normal. means it *does* exist.
|
||||
var abs = this._makeAbs(f)
|
||||
this.cache[abs] = 'FILE'
|
||||
if (abs === this.cwdAbs) {
|
||||
var error = new Error(er.code + ' invalid cwd ' + this.cwd)
|
||||
error.path = this.cwd
|
||||
error.code = er.code
|
||||
this.emit('error', error)
|
||||
this.abort()
|
||||
}
|
||||
break
|
||||
|
||||
case 'ENOENT': // not terribly unusual
|
||||
case 'ELOOP':
|
||||
case 'ENAMETOOLONG':
|
||||
case 'UNKNOWN':
|
||||
this.cache[this._makeAbs(f)] = false
|
||||
break
|
||||
|
||||
default: // some unusual error. Treat as failure.
|
||||
this.cache[this._makeAbs(f)] = false
|
||||
if (this.strict) {
|
||||
this.emit('error', er)
|
||||
// If the error is handled, then we abort
|
||||
// if not, we threw out of here
|
||||
this.abort()
|
||||
}
|
||||
if (!this.silent)
|
||||
console.error('glob error', er)
|
||||
break
|
||||
}
|
||||
|
||||
return cb()
|
||||
}
|
||||
|
||||
Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) {
|
||||
var self = this
|
||||
this._readdir(abs, inGlobStar, function (er, entries) {
|
||||
self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
|
||||
//console.error('pgs2', prefix, remain[0], entries)
|
||||
|
||||
// no entries means not a dir, so it can never have matches
|
||||
// foo.txt/** doesn't match foo.txt
|
||||
if (!entries)
|
||||
return cb()
|
||||
|
||||
// test without the globstar, and with every child both below
|
||||
// and replacing the globstar.
|
||||
var remainWithoutGlobStar = remain.slice(1)
|
||||
var gspref = prefix ? [ prefix ] : []
|
||||
var noGlobStar = gspref.concat(remainWithoutGlobStar)
|
||||
|
||||
// the noGlobStar pattern exits the inGlobStar state
|
||||
this._process(noGlobStar, index, false, cb)
|
||||
|
||||
var isSym = this.symlinks[abs]
|
||||
var len = entries.length
|
||||
|
||||
// If it's a symlink, and we're in a globstar, then stop
|
||||
if (isSym && inGlobStar)
|
||||
return cb()
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
var e = entries[i]
|
||||
if (e.charAt(0) === '.' && !this.dot)
|
||||
continue
|
||||
|
||||
// these two cases enter the inGlobStar state
|
||||
var instead = gspref.concat(entries[i], remainWithoutGlobStar)
|
||||
this._process(instead, index, true, cb)
|
||||
|
||||
var below = gspref.concat(entries[i], remain)
|
||||
this._process(below, index, true, cb)
|
||||
}
|
||||
|
||||
cb()
|
||||
}
|
||||
|
||||
Glob.prototype._processSimple = function (prefix, index, cb) {
|
||||
// XXX review this. Shouldn't it be doing the mounting etc
|
||||
// before doing stat? kinda weird?
|
||||
var self = this
|
||||
this._stat(prefix, function (er, exists) {
|
||||
self._processSimple2(prefix, index, er, exists, cb)
|
||||
})
|
||||
}
|
||||
Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) {
|
||||
|
||||
//console.error('ps2', prefix, exists)
|
||||
|
||||
if (!this.matches[index])
|
||||
this.matches[index] = Object.create(null)
|
||||
|
||||
// If it doesn't exist, then just mark the lack of results
|
||||
if (!exists)
|
||||
return cb()
|
||||
|
||||
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
||||
var trail = /[\/\\]$/.test(prefix)
|
||||
if (prefix.charAt(0) === '/') {
|
||||
prefix = path.join(this.root, prefix)
|
||||
} else {
|
||||
prefix = path.resolve(this.root, prefix)
|
||||
if (trail)
|
||||
prefix += '/'
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === 'win32')
|
||||
prefix = prefix.replace(/\\/g, '/')
|
||||
|
||||
// Mark this as a match
|
||||
this._emitMatch(index, prefix)
|
||||
cb()
|
||||
}
|
||||
|
||||
// Returns either 'DIR', 'FILE', or false
|
||||
Glob.prototype._stat = function (f, cb) {
|
||||
var abs = this._makeAbs(f)
|
||||
var needDir = f.slice(-1) === '/'
|
||||
|
||||
if (f.length > this.maxLength)
|
||||
return cb()
|
||||
|
||||
if (!this.stat && ownProp(this.cache, abs)) {
|
||||
var c = this.cache[abs]
|
||||
|
||||
if (Array.isArray(c))
|
||||
c = 'DIR'
|
||||
|
||||
// It exists, but maybe not how we need it
|
||||
if (!needDir || c === 'DIR')
|
||||
return cb(null, c)
|
||||
|
||||
if (needDir && c === 'FILE')
|
||||
return cb()
|
||||
|
||||
// otherwise we have to stat, because maybe c=true
|
||||
// if we know it exists, but not what it is.
|
||||
}
|
||||
|
||||
var exists
|
||||
var stat = this.statCache[abs]
|
||||
if (stat !== undefined) {
|
||||
if (stat === false)
|
||||
return cb(null, stat)
|
||||
else {
|
||||
var type = stat.isDirectory() ? 'DIR' : 'FILE'
|
||||
if (needDir && type === 'FILE')
|
||||
return cb()
|
||||
else
|
||||
return cb(null, type, stat)
|
||||
}
|
||||
}
|
||||
|
||||
var self = this
|
||||
var statcb = inflight('stat\0' + abs, lstatcb_)
|
||||
if (statcb)
|
||||
self.fs.lstat(abs, statcb)
|
||||
|
||||
function lstatcb_ (er, lstat) {
|
||||
if (lstat && lstat.isSymbolicLink()) {
|
||||
// If it's a symlink, then treat it as the target, unless
|
||||
// the target does not exist, then treat it as a file.
|
||||
return self.fs.stat(abs, function (er, stat) {
|
||||
if (er)
|
||||
self._stat2(f, abs, null, lstat, cb)
|
||||
else
|
||||
self._stat2(f, abs, er, stat, cb)
|
||||
})
|
||||
} else {
|
||||
self._stat2(f, abs, er, lstat, cb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
|
||||
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
|
||||
this.statCache[abs] = false
|
||||
return cb()
|
||||
}
|
||||
|
||||
var needDir = f.slice(-1) === '/'
|
||||
this.statCache[abs] = stat
|
||||
|
||||
if (abs.slice(-1) === '/' && stat && !stat.isDirectory())
|
||||
return cb(null, false, stat)
|
||||
|
||||
var c = true
|
||||
if (stat)
|
||||
c = stat.isDirectory() ? 'DIR' : 'FILE'
|
||||
this.cache[abs] = this.cache[abs] || c
|
||||
|
||||
if (needDir && c === 'FILE')
|
||||
return cb()
|
||||
|
||||
return cb(null, c, stat)
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
|
||||
"name": "glob",
|
||||
"description": "a little globber",
|
||||
"version": "7.2.3",
|
||||
"publishConfig": {
|
||||
"tag": "v7-legacy"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/isaacs/node-glob.git"
|
||||
},
|
||||
"main": "glob.js",
|
||||
"files": [
|
||||
"glob.js",
|
||||
"sync.js",
|
||||
"common.js"
|
||||
],
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"memfs": "^3.2.0",
|
||||
"mkdirp": "0",
|
||||
"rimraf": "^2.2.8",
|
||||
"tap": "^15.0.6",
|
||||
"tick": "0.0.6"
|
||||
},
|
||||
"tap": {
|
||||
"before": "test/00-setup.js",
|
||||
"after": "test/zz-cleanup.js",
|
||||
"jobs": 1
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "npm run benchclean",
|
||||
"profclean": "rm -f v8.log profile.txt",
|
||||
"test": "tap",
|
||||
"test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js",
|
||||
"bench": "bash benchmark.sh",
|
||||
"prof": "bash prof.sh && cat profile.txt",
|
||||
"benchclean": "node benchclean.js"
|
||||
},
|
||||
"license": "ISC",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
}
|
||||
+486
@@ -0,0 +1,486 @@
|
||||
module.exports = globSync
|
||||
globSync.GlobSync = GlobSync
|
||||
|
||||
var rp = require('fs.realpath')
|
||||
var minimatch = require('minimatch')
|
||||
var Minimatch = minimatch.Minimatch
|
||||
var Glob = require('./glob.js').Glob
|
||||
var util = require('util')
|
||||
var path = require('path')
|
||||
var assert = require('assert')
|
||||
var isAbsolute = require('path-is-absolute')
|
||||
var common = require('./common.js')
|
||||
var setopts = common.setopts
|
||||
var ownProp = common.ownProp
|
||||
var childrenIgnored = common.childrenIgnored
|
||||
var isIgnored = common.isIgnored
|
||||
|
||||
function globSync (pattern, options) {
|
||||
if (typeof options === 'function' || arguments.length === 3)
|
||||
throw new TypeError('callback provided to sync glob\n'+
|
||||
'See: https://github.com/isaacs/node-glob/issues/167')
|
||||
|
||||
return new GlobSync(pattern, options).found
|
||||
}
|
||||
|
||||
function GlobSync (pattern, options) {
|
||||
if (!pattern)
|
||||
throw new Error('must provide pattern')
|
||||
|
||||
if (typeof options === 'function' || arguments.length === 3)
|
||||
throw new TypeError('callback provided to sync glob\n'+
|
||||
'See: https://github.com/isaacs/node-glob/issues/167')
|
||||
|
||||
if (!(this instanceof GlobSync))
|
||||
return new GlobSync(pattern, options)
|
||||
|
||||
setopts(this, pattern, options)
|
||||
|
||||
if (this.noprocess)
|
||||
return this
|
||||
|
||||
var n = this.minimatch.set.length
|
||||
this.matches = new Array(n)
|
||||
for (var i = 0; i < n; i ++) {
|
||||
this._process(this.minimatch.set[i], i, false)
|
||||
}
|
||||
this._finish()
|
||||
}
|
||||
|
||||
GlobSync.prototype._finish = function () {
|
||||
assert.ok(this instanceof GlobSync)
|
||||
if (this.realpath) {
|
||||
var self = this
|
||||
this.matches.forEach(function (matchset, index) {
|
||||
var set = self.matches[index] = Object.create(null)
|
||||
for (var p in matchset) {
|
||||
try {
|
||||
p = self._makeAbs(p)
|
||||
var real = rp.realpathSync(p, self.realpathCache)
|
||||
set[real] = true
|
||||
} catch (er) {
|
||||
if (er.syscall === 'stat')
|
||||
set[self._makeAbs(p)] = true
|
||||
else
|
||||
throw er
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
common.finish(this)
|
||||
}
|
||||
|
||||
|
||||
GlobSync.prototype._process = function (pattern, index, inGlobStar) {
|
||||
assert.ok(this instanceof GlobSync)
|
||||
|
||||
// Get the first [n] parts of pattern that are all strings.
|
||||
var n = 0
|
||||
while (typeof pattern[n] === 'string') {
|
||||
n ++
|
||||
}
|
||||
// now n is the index of the first one that is *not* a string.
|
||||
|
||||
// See if there's anything else
|
||||
var prefix
|
||||
switch (n) {
|
||||
// if not, then this is rather simple
|
||||
case pattern.length:
|
||||
this._processSimple(pattern.join('/'), index)
|
||||
return
|
||||
|
||||
case 0:
|
||||
// pattern *starts* with some non-trivial item.
|
||||
// going to readdir(cwd), but not include the prefix in matches.
|
||||
prefix = null
|
||||
break
|
||||
|
||||
default:
|
||||
// pattern has some string bits in the front.
|
||||
// whatever it starts with, whether that's 'absolute' like /foo/bar,
|
||||
// or 'relative' like '../baz'
|
||||
prefix = pattern.slice(0, n).join('/')
|
||||
break
|
||||
}
|
||||
|
||||
var remain = pattern.slice(n)
|
||||
|
||||
// get the list of entries.
|
||||
var read
|
||||
if (prefix === null)
|
||||
read = '.'
|
||||
else if (isAbsolute(prefix) ||
|
||||
isAbsolute(pattern.map(function (p) {
|
||||
return typeof p === 'string' ? p : '[*]'
|
||||
}).join('/'))) {
|
||||
if (!prefix || !isAbsolute(prefix))
|
||||
prefix = '/' + prefix
|
||||
read = prefix
|
||||
} else
|
||||
read = prefix
|
||||
|
||||
var abs = this._makeAbs(read)
|
||||
|
||||
//if ignored, skip processing
|
||||
if (childrenIgnored(this, read))
|
||||
return
|
||||
|
||||
var isGlobStar = remain[0] === minimatch.GLOBSTAR
|
||||
if (isGlobStar)
|
||||
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar)
|
||||
else
|
||||
this._processReaddir(prefix, read, abs, remain, index, inGlobStar)
|
||||
}
|
||||
|
||||
|
||||
GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) {
|
||||
var entries = this._readdir(abs, inGlobStar)
|
||||
|
||||
// if the abs isn't a dir, then nothing can match!
|
||||
if (!entries)
|
||||
return
|
||||
|
||||
// It will only match dot entries if it starts with a dot, or if
|
||||
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
||||
var pn = remain[0]
|
||||
var negate = !!this.minimatch.negate
|
||||
var rawGlob = pn._glob
|
||||
var dotOk = this.dot || rawGlob.charAt(0) === '.'
|
||||
|
||||
var matchedEntries = []
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
var e = entries[i]
|
||||
if (e.charAt(0) !== '.' || dotOk) {
|
||||
var m
|
||||
if (negate && !prefix) {
|
||||
m = !e.match(pn)
|
||||
} else {
|
||||
m = e.match(pn)
|
||||
}
|
||||
if (m)
|
||||
matchedEntries.push(e)
|
||||
}
|
||||
}
|
||||
|
||||
var len = matchedEntries.length
|
||||
// If there are no matched entries, then nothing matches.
|
||||
if (len === 0)
|
||||
return
|
||||
|
||||
// if this is the last remaining pattern bit, then no need for
|
||||
// an additional stat *unless* the user has specified mark or
|
||||
// stat explicitly. We know they exist, since readdir returned
|
||||
// them.
|
||||
|
||||
if (remain.length === 1 && !this.mark && !this.stat) {
|
||||
if (!this.matches[index])
|
||||
this.matches[index] = Object.create(null)
|
||||
|
||||
for (var i = 0; i < len; i ++) {
|
||||
var e = matchedEntries[i]
|
||||
if (prefix) {
|
||||
if (prefix.slice(-1) !== '/')
|
||||
e = prefix + '/' + e
|
||||
else
|
||||
e = prefix + e
|
||||
}
|
||||
|
||||
if (e.charAt(0) === '/' && !this.nomount) {
|
||||
e = path.join(this.root, e)
|
||||
}
|
||||
this._emitMatch(index, e)
|
||||
}
|
||||
// This was the last one, and no stats were needed
|
||||
return
|
||||
}
|
||||
|
||||
// now test all matched entries as stand-ins for that part
|
||||
// of the pattern.
|
||||
remain.shift()
|
||||
for (var i = 0; i < len; i ++) {
|
||||
var e = matchedEntries[i]
|
||||
var newPattern
|
||||
if (prefix)
|
||||
newPattern = [prefix, e]
|
||||
else
|
||||
newPattern = [e]
|
||||
this._process(newPattern.concat(remain), index, inGlobStar)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GlobSync.prototype._emitMatch = function (index, e) {
|
||||
if (isIgnored(this, e))
|
||||
return
|
||||
|
||||
var abs = this._makeAbs(e)
|
||||
|
||||
if (this.mark)
|
||||
e = this._mark(e)
|
||||
|
||||
if (this.absolute) {
|
||||
e = abs
|
||||
}
|
||||
|
||||
if (this.matches[index][e])
|
||||
return
|
||||
|
||||
if (this.nodir) {
|
||||
var c = this.cache[abs]
|
||||
if (c === 'DIR' || Array.isArray(c))
|
||||
return
|
||||
}
|
||||
|
||||
this.matches[index][e] = true
|
||||
|
||||
if (this.stat)
|
||||
this._stat(e)
|
||||
}
|
||||
|
||||
|
||||
GlobSync.prototype._readdirInGlobStar = function (abs) {
|
||||
// follow all symlinked directories forever
|
||||
// just proceed as if this is a non-globstar situation
|
||||
if (this.follow)
|
||||
return this._readdir(abs, false)
|
||||
|
||||
var entries
|
||||
var lstat
|
||||
var stat
|
||||
try {
|
||||
lstat = this.fs.lstatSync(abs)
|
||||
} catch (er) {
|
||||
if (er.code === 'ENOENT') {
|
||||
// lstat failed, doesn't exist
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
var isSym = lstat && lstat.isSymbolicLink()
|
||||
this.symlinks[abs] = isSym
|
||||
|
||||
// If it's not a symlink or a dir, then it's definitely a regular file.
|
||||
// don't bother doing a readdir in that case.
|
||||
if (!isSym && lstat && !lstat.isDirectory())
|
||||
this.cache[abs] = 'FILE'
|
||||
else
|
||||
entries = this._readdir(abs, false)
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
GlobSync.prototype._readdir = function (abs, inGlobStar) {
|
||||
var entries
|
||||
|
||||
if (inGlobStar && !ownProp(this.symlinks, abs))
|
||||
return this._readdirInGlobStar(abs)
|
||||
|
||||
if (ownProp(this.cache, abs)) {
|
||||
var c = this.cache[abs]
|
||||
if (!c || c === 'FILE')
|
||||
return null
|
||||
|
||||
if (Array.isArray(c))
|
||||
return c
|
||||
}
|
||||
|
||||
try {
|
||||
return this._readdirEntries(abs, this.fs.readdirSync(abs))
|
||||
} catch (er) {
|
||||
this._readdirError(abs, er)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
GlobSync.prototype._readdirEntries = function (abs, entries) {
|
||||
// if we haven't asked to stat everything, then just
|
||||
// assume that everything in there exists, so we can avoid
|
||||
// having to stat it a second time.
|
||||
if (!this.mark && !this.stat) {
|
||||
for (var i = 0; i < entries.length; i ++) {
|
||||
var e = entries[i]
|
||||
if (abs === '/')
|
||||
e = abs + e
|
||||
else
|
||||
e = abs + '/' + e
|
||||
this.cache[e] = true
|
||||
}
|
||||
}
|
||||
|
||||
this.cache[abs] = entries
|
||||
|
||||
// mark and cache dir-ness
|
||||
return entries
|
||||
}
|
||||
|
||||
GlobSync.prototype._readdirError = function (f, er) {
|
||||
// handle errors, and cache the information
|
||||
switch (er.code) {
|
||||
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
|
||||
case 'ENOTDIR': // totally normal. means it *does* exist.
|
||||
var abs = this._makeAbs(f)
|
||||
this.cache[abs] = 'FILE'
|
||||
if (abs === this.cwdAbs) {
|
||||
var error = new Error(er.code + ' invalid cwd ' + this.cwd)
|
||||
error.path = this.cwd
|
||||
error.code = er.code
|
||||
throw error
|
||||
}
|
||||
break
|
||||
|
||||
case 'ENOENT': // not terribly unusual
|
||||
case 'ELOOP':
|
||||
case 'ENAMETOOLONG':
|
||||
case 'UNKNOWN':
|
||||
this.cache[this._makeAbs(f)] = false
|
||||
break
|
||||
|
||||
default: // some unusual error. Treat as failure.
|
||||
this.cache[this._makeAbs(f)] = false
|
||||
if (this.strict)
|
||||
throw er
|
||||
if (!this.silent)
|
||||
console.error('glob error', er)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) {
|
||||
|
||||
var entries = this._readdir(abs, inGlobStar)
|
||||
|
||||
// no entries means not a dir, so it can never have matches
|
||||
// foo.txt/** doesn't match foo.txt
|
||||
if (!entries)
|
||||
return
|
||||
|
||||
// test without the globstar, and with every child both below
|
||||
// and replacing the globstar.
|
||||
var remainWithoutGlobStar = remain.slice(1)
|
||||
var gspref = prefix ? [ prefix ] : []
|
||||
var noGlobStar = gspref.concat(remainWithoutGlobStar)
|
||||
|
||||
// the noGlobStar pattern exits the inGlobStar state
|
||||
this._process(noGlobStar, index, false)
|
||||
|
||||
var len = entries.length
|
||||
var isSym = this.symlinks[abs]
|
||||
|
||||
// If it's a symlink, and we're in a globstar, then stop
|
||||
if (isSym && inGlobStar)
|
||||
return
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
var e = entries[i]
|
||||
if (e.charAt(0) === '.' && !this.dot)
|
||||
continue
|
||||
|
||||
// these two cases enter the inGlobStar state
|
||||
var instead = gspref.concat(entries[i], remainWithoutGlobStar)
|
||||
this._process(instead, index, true)
|
||||
|
||||
var below = gspref.concat(entries[i], remain)
|
||||
this._process(below, index, true)
|
||||
}
|
||||
}
|
||||
|
||||
GlobSync.prototype._processSimple = function (prefix, index) {
|
||||
// XXX review this. Shouldn't it be doing the mounting etc
|
||||
// before doing stat? kinda weird?
|
||||
var exists = this._stat(prefix)
|
||||
|
||||
if (!this.matches[index])
|
||||
this.matches[index] = Object.create(null)
|
||||
|
||||
// If it doesn't exist, then just mark the lack of results
|
||||
if (!exists)
|
||||
return
|
||||
|
||||
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
||||
var trail = /[\/\\]$/.test(prefix)
|
||||
if (prefix.charAt(0) === '/') {
|
||||
prefix = path.join(this.root, prefix)
|
||||
} else {
|
||||
prefix = path.resolve(this.root, prefix)
|
||||
if (trail)
|
||||
prefix += '/'
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === 'win32')
|
||||
prefix = prefix.replace(/\\/g, '/')
|
||||
|
||||
// Mark this as a match
|
||||
this._emitMatch(index, prefix)
|
||||
}
|
||||
|
||||
// Returns either 'DIR', 'FILE', or false
|
||||
GlobSync.prototype._stat = function (f) {
|
||||
var abs = this._makeAbs(f)
|
||||
var needDir = f.slice(-1) === '/'
|
||||
|
||||
if (f.length > this.maxLength)
|
||||
return false
|
||||
|
||||
if (!this.stat && ownProp(this.cache, abs)) {
|
||||
var c = this.cache[abs]
|
||||
|
||||
if (Array.isArray(c))
|
||||
c = 'DIR'
|
||||
|
||||
// It exists, but maybe not how we need it
|
||||
if (!needDir || c === 'DIR')
|
||||
return c
|
||||
|
||||
if (needDir && c === 'FILE')
|
||||
return false
|
||||
|
||||
// otherwise we have to stat, because maybe c=true
|
||||
// if we know it exists, but not what it is.
|
||||
}
|
||||
|
||||
var exists
|
||||
var stat = this.statCache[abs]
|
||||
if (!stat) {
|
||||
var lstat
|
||||
try {
|
||||
lstat = this.fs.lstatSync(abs)
|
||||
} catch (er) {
|
||||
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
|
||||
this.statCache[abs] = false
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (lstat && lstat.isSymbolicLink()) {
|
||||
try {
|
||||
stat = this.fs.statSync(abs)
|
||||
} catch (er) {
|
||||
stat = lstat
|
||||
}
|
||||
} else {
|
||||
stat = lstat
|
||||
}
|
||||
}
|
||||
|
||||
this.statCache[abs] = stat
|
||||
|
||||
var c = true
|
||||
if (stat)
|
||||
c = stat.isDirectory() ? 'DIR' : 'FILE'
|
||||
|
||||
this.cache[abs] = this.cache[abs] || c
|
||||
|
||||
if (needDir && c === 'FILE')
|
||||
return false
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
GlobSync.prototype._mark = function (p) {
|
||||
return common.mark(this, p)
|
||||
}
|
||||
|
||||
GlobSync.prototype._makeAbs = function (f) {
|
||||
return common.makeAbs(this, f)
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
# minimatch
|
||||
|
||||
A minimal matching utility.
|
||||
|
||||
[](http://travis-ci.org/isaacs/minimatch)
|
||||
|
||||
|
||||
This is the matching library used internally by npm.
|
||||
|
||||
It works by converting glob expressions into JavaScript `RegExp`
|
||||
objects.
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var minimatch = require("minimatch")
|
||||
|
||||
minimatch("bar.foo", "*.foo") // true!
|
||||
minimatch("bar.foo", "*.bar") // false!
|
||||
minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
Supports these glob features:
|
||||
|
||||
* Brace Expansion
|
||||
* Extended glob matching
|
||||
* "Globstar" `**` matching
|
||||
|
||||
See:
|
||||
|
||||
* `man sh`
|
||||
* `man bash`
|
||||
* `man 3 fnmatch`
|
||||
* `man 5 gitignore`
|
||||
|
||||
## Minimatch Class
|
||||
|
||||
Create a minimatch object by instantiating the `minimatch.Minimatch` class.
|
||||
|
||||
```javascript
|
||||
var Minimatch = require("minimatch").Minimatch
|
||||
var mm = new Minimatch(pattern, options)
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
* `pattern` The original pattern the minimatch object represents.
|
||||
* `options` The options supplied to the constructor.
|
||||
* `set` A 2-dimensional array of regexp or string expressions.
|
||||
Each row in the
|
||||
array corresponds to a brace-expanded pattern. Each item in the row
|
||||
corresponds to a single path-part. For example, the pattern
|
||||
`{a,b/c}/d` would expand to a set of patterns like:
|
||||
|
||||
[ [ a, d ]
|
||||
, [ b, c, d ] ]
|
||||
|
||||
If a portion of the pattern doesn't have any "magic" in it
|
||||
(that is, it's something like `"foo"` rather than `fo*o?`), then it
|
||||
will be left as a string rather than converted to a regular
|
||||
expression.
|
||||
|
||||
* `regexp` Created by the `makeRe` method. A single regular expression
|
||||
expressing the entire pattern. This is useful in cases where you wish
|
||||
to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
|
||||
* `negate` True if the pattern is negated.
|
||||
* `comment` True if the pattern is a comment.
|
||||
* `empty` True if the pattern is `""`.
|
||||
|
||||
### Methods
|
||||
|
||||
* `makeRe` Generate the `regexp` member if necessary, and return it.
|
||||
Will return `false` if the pattern is invalid.
|
||||
* `match(fname)` Return true if the filename matches the pattern, or
|
||||
false otherwise.
|
||||
* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
|
||||
filename, and match it against a single row in the `regExpSet`. This
|
||||
method is mainly for internal use, but is exposed so that it can be
|
||||
used by a glob-walker that needs to avoid excessive filesystem calls.
|
||||
|
||||
All other methods are internal, and will be called as necessary.
|
||||
|
||||
### minimatch(path, pattern, options)
|
||||
|
||||
Main export. Tests a path against the pattern using the options.
|
||||
|
||||
```javascript
|
||||
var isJS = minimatch(file, "*.js", { matchBase: true })
|
||||
```
|
||||
|
||||
### minimatch.filter(pattern, options)
|
||||
|
||||
Returns a function that tests its
|
||||
supplied argument, suitable for use with `Array.filter`. Example:
|
||||
|
||||
```javascript
|
||||
var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
|
||||
```
|
||||
|
||||
### minimatch.match(list, pattern, options)
|
||||
|
||||
Match against the list of
|
||||
files, in the style of fnmatch or glob. If nothing is matched, and
|
||||
options.nonull is set, then return a list containing the pattern itself.
|
||||
|
||||
```javascript
|
||||
var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
|
||||
```
|
||||
|
||||
### minimatch.makeRe(pattern, options)
|
||||
|
||||
Make a regular expression object from the pattern.
|
||||
|
||||
## Options
|
||||
|
||||
All options are `false` by default.
|
||||
|
||||
### debug
|
||||
|
||||
Dump a ton of stuff to stderr.
|
||||
|
||||
### nobrace
|
||||
|
||||
Do not expand `{a,b}` and `{1..3}` brace sets.
|
||||
|
||||
### noglobstar
|
||||
|
||||
Disable `**` matching against multiple folder names.
|
||||
|
||||
### dot
|
||||
|
||||
Allow patterns to match filenames starting with a period, even if
|
||||
the pattern does not explicitly have a period in that spot.
|
||||
|
||||
Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
|
||||
is set.
|
||||
|
||||
### noext
|
||||
|
||||
Disable "extglob" style patterns like `+(a|b)`.
|
||||
|
||||
### nocase
|
||||
|
||||
Perform a case-insensitive match.
|
||||
|
||||
### nonull
|
||||
|
||||
When a match is not found by `minimatch.match`, return a list containing
|
||||
the pattern itself if this option is set. When not set, an empty list
|
||||
is returned if there are no matches.
|
||||
|
||||
### matchBase
|
||||
|
||||
If set, then patterns without slashes will be matched
|
||||
against the basename of the path if it contains slashes. For example,
|
||||
`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
|
||||
|
||||
### nocomment
|
||||
|
||||
Suppress the behavior of treating `#` at the start of a pattern as a
|
||||
comment.
|
||||
|
||||
### nonegate
|
||||
|
||||
Suppress the behavior of treating a leading `!` character as negation.
|
||||
|
||||
### flipNegate
|
||||
|
||||
Returns from negate expressions the same as if they were not negated.
|
||||
(Ie, true on a hit, false on a miss.)
|
||||
|
||||
### partial
|
||||
|
||||
Compare a partial path to a pattern. As long as the parts of the path that
|
||||
are present are not contradicted by the pattern, it will be treated as a
|
||||
match. This is useful in applications where you're walking through a
|
||||
folder structure, and don't yet have the full path, but want to ensure that
|
||||
you do not walk down paths that can never be a match.
|
||||
|
||||
For example,
|
||||
|
||||
```js
|
||||
minimatch('/a/b', '/a/*/c/d', { partial: true }) // true, might be /a/b/c/d
|
||||
minimatch('/a/b', '/**/d', { partial: true }) // true, might be /a/b/.../d
|
||||
minimatch('/x/y/z', '/a/**/z', { partial: true }) // false, because x !== a
|
||||
```
|
||||
|
||||
### allowWindowsEscape
|
||||
|
||||
Windows path separator `\` is by default converted to `/`, which
|
||||
prohibits the usage of `\` as a escape character. This flag skips that
|
||||
behavior and allows using the escape character.
|
||||
|
||||
## Comparisons to other fnmatch/glob implementations
|
||||
|
||||
While strict compliance with the existing standards is a worthwhile
|
||||
goal, some discrepancies exist between minimatch and other
|
||||
implementations, and are intentional.
|
||||
|
||||
If the pattern starts with a `!` character, then it is negated. Set the
|
||||
`nonegate` flag to suppress this behavior, and treat leading `!`
|
||||
characters normally. This is perhaps relevant if you wish to start the
|
||||
pattern with a negative extglob pattern like `!(a|B)`. Multiple `!`
|
||||
characters at the start of a pattern will negate the pattern multiple
|
||||
times.
|
||||
|
||||
If a pattern starts with `#`, then it is treated as a comment, and
|
||||
will not match anything. Use `\#` to match a literal `#` at the
|
||||
start of a line, or set the `nocomment` flag to suppress this behavior.
|
||||
|
||||
The double-star character `**` is supported by default, unless the
|
||||
`noglobstar` flag is set. This is supported in the manner of bsdglob
|
||||
and bash 4.1, where `**` only has special significance if it is the only
|
||||
thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but
|
||||
`a/**b` will not.
|
||||
|
||||
If an escaped pattern has no matches, and the `nonull` flag is set,
|
||||
then minimatch.match returns the pattern as-provided, rather than
|
||||
interpreting the character escapes. For example,
|
||||
`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
|
||||
`"*a?"`. This is akin to setting the `nullglob` option in bash, except
|
||||
that it does not resolve escaped pattern characters.
|
||||
|
||||
If brace expansion is not disabled, then it is performed before any
|
||||
other interpretation of the glob pattern. Thus, a pattern like
|
||||
`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
|
||||
**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
|
||||
checked for validity. Since those two are valid, matching proceeds.
|
||||
+947
@@ -0,0 +1,947 @@
|
||||
module.exports = minimatch
|
||||
minimatch.Minimatch = Minimatch
|
||||
|
||||
var path = (function () { try { return require('path') } catch (e) {}}()) || {
|
||||
sep: '/'
|
||||
}
|
||||
minimatch.sep = path.sep
|
||||
|
||||
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
|
||||
var expand = require('brace-expansion')
|
||||
|
||||
var plTypes = {
|
||||
'!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
|
||||
'?': { open: '(?:', close: ')?' },
|
||||
'+': { open: '(?:', close: ')+' },
|
||||
'*': { open: '(?:', close: ')*' },
|
||||
'@': { open: '(?:', close: ')' }
|
||||
}
|
||||
|
||||
// any single thing other than /
|
||||
// don't need to escape / when using new RegExp()
|
||||
var qmark = '[^/]'
|
||||
|
||||
// * => any number of characters
|
||||
var star = qmark + '*?'
|
||||
|
||||
// ** when dots are allowed. Anything goes, except .. and .
|
||||
// not (^ or / followed by one or two dots followed by $ or /),
|
||||
// followed by anything, any number of times.
|
||||
var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
|
||||
|
||||
// not a ^ or / followed by a dot,
|
||||
// followed by anything, any number of times.
|
||||
var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
|
||||
|
||||
// characters that need to be escaped in RegExp.
|
||||
var reSpecials = charSet('().*{}+?[]^$\\!')
|
||||
|
||||
// "abc" -> { a:true, b:true, c:true }
|
||||
function charSet (s) {
|
||||
return s.split('').reduce(function (set, c) {
|
||||
set[c] = true
|
||||
return set
|
||||
}, {})
|
||||
}
|
||||
|
||||
// normalizes slashes.
|
||||
var slashSplit = /\/+/
|
||||
|
||||
minimatch.filter = filter
|
||||
function filter (pattern, options) {
|
||||
options = options || {}
|
||||
return function (p, i, list) {
|
||||
return minimatch(p, pattern, options)
|
||||
}
|
||||
}
|
||||
|
||||
function ext (a, b) {
|
||||
b = b || {}
|
||||
var t = {}
|
||||
Object.keys(a).forEach(function (k) {
|
||||
t[k] = a[k]
|
||||
})
|
||||
Object.keys(b).forEach(function (k) {
|
||||
t[k] = b[k]
|
||||
})
|
||||
return t
|
||||
}
|
||||
|
||||
minimatch.defaults = function (def) {
|
||||
if (!def || typeof def !== 'object' || !Object.keys(def).length) {
|
||||
return minimatch
|
||||
}
|
||||
|
||||
var orig = minimatch
|
||||
|
||||
var m = function minimatch (p, pattern, options) {
|
||||
return orig(p, pattern, ext(def, options))
|
||||
}
|
||||
|
||||
m.Minimatch = function Minimatch (pattern, options) {
|
||||
return new orig.Minimatch(pattern, ext(def, options))
|
||||
}
|
||||
m.Minimatch.defaults = function defaults (options) {
|
||||
return orig.defaults(ext(def, options)).Minimatch
|
||||
}
|
||||
|
||||
m.filter = function filter (pattern, options) {
|
||||
return orig.filter(pattern, ext(def, options))
|
||||
}
|
||||
|
||||
m.defaults = function defaults (options) {
|
||||
return orig.defaults(ext(def, options))
|
||||
}
|
||||
|
||||
m.makeRe = function makeRe (pattern, options) {
|
||||
return orig.makeRe(pattern, ext(def, options))
|
||||
}
|
||||
|
||||
m.braceExpand = function braceExpand (pattern, options) {
|
||||
return orig.braceExpand(pattern, ext(def, options))
|
||||
}
|
||||
|
||||
m.match = function (list, pattern, options) {
|
||||
return orig.match(list, pattern, ext(def, options))
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
Minimatch.defaults = function (def) {
|
||||
return minimatch.defaults(def).Minimatch
|
||||
}
|
||||
|
||||
function minimatch (p, pattern, options) {
|
||||
assertValidPattern(pattern)
|
||||
|
||||
if (!options) options = {}
|
||||
|
||||
// shortcut: comments match nothing.
|
||||
if (!options.nocomment && pattern.charAt(0) === '#') {
|
||||
return false
|
||||
}
|
||||
|
||||
return new Minimatch(pattern, options).match(p)
|
||||
}
|
||||
|
||||
function Minimatch (pattern, options) {
|
||||
if (!(this instanceof Minimatch)) {
|
||||
return new Minimatch(pattern, options)
|
||||
}
|
||||
|
||||
assertValidPattern(pattern)
|
||||
|
||||
if (!options) options = {}
|
||||
|
||||
pattern = pattern.trim()
|
||||
|
||||
// windows support: need to use /, not \
|
||||
if (!options.allowWindowsEscape && path.sep !== '/') {
|
||||
pattern = pattern.split(path.sep).join('/')
|
||||
}
|
||||
|
||||
this.options = options
|
||||
this.set = []
|
||||
this.pattern = pattern
|
||||
this.regexp = null
|
||||
this.negate = false
|
||||
this.comment = false
|
||||
this.empty = false
|
||||
this.partial = !!options.partial
|
||||
|
||||
// make the set of regexps etc.
|
||||
this.make()
|
||||
}
|
||||
|
||||
Minimatch.prototype.debug = function () {}
|
||||
|
||||
Minimatch.prototype.make = make
|
||||
function make () {
|
||||
var pattern = this.pattern
|
||||
var options = this.options
|
||||
|
||||
// empty patterns and comments match nothing.
|
||||
if (!options.nocomment && pattern.charAt(0) === '#') {
|
||||
this.comment = true
|
||||
return
|
||||
}
|
||||
if (!pattern) {
|
||||
this.empty = true
|
||||
return
|
||||
}
|
||||
|
||||
// step 1: figure out negation, etc.
|
||||
this.parseNegate()
|
||||
|
||||
// step 2: expand braces
|
||||
var set = this.globSet = this.braceExpand()
|
||||
|
||||
if (options.debug) this.debug = function debug() { console.error.apply(console, arguments) }
|
||||
|
||||
this.debug(this.pattern, set)
|
||||
|
||||
// step 3: now we have a set, so turn each one into a series of path-portion
|
||||
// matching patterns.
|
||||
// These will be regexps, except in the case of "**", which is
|
||||
// set to the GLOBSTAR object for globstar behavior,
|
||||
// and will not contain any / characters
|
||||
set = this.globParts = set.map(function (s) {
|
||||
return s.split(slashSplit)
|
||||
})
|
||||
|
||||
this.debug(this.pattern, set)
|
||||
|
||||
// glob --> regexps
|
||||
set = set.map(function (s, si, set) {
|
||||
return s.map(this.parse, this)
|
||||
}, this)
|
||||
|
||||
this.debug(this.pattern, set)
|
||||
|
||||
// filter out everything that didn't compile properly.
|
||||
set = set.filter(function (s) {
|
||||
return s.indexOf(false) === -1
|
||||
})
|
||||
|
||||
this.debug(this.pattern, set)
|
||||
|
||||
this.set = set
|
||||
}
|
||||
|
||||
Minimatch.prototype.parseNegate = parseNegate
|
||||
function parseNegate () {
|
||||
var pattern = this.pattern
|
||||
var negate = false
|
||||
var options = this.options
|
||||
var negateOffset = 0
|
||||
|
||||
if (options.nonegate) return
|
||||
|
||||
for (var i = 0, l = pattern.length
|
||||
; i < l && pattern.charAt(i) === '!'
|
||||
; i++) {
|
||||
negate = !negate
|
||||
negateOffset++
|
||||
}
|
||||
|
||||
if (negateOffset) this.pattern = pattern.substr(negateOffset)
|
||||
this.negate = negate
|
||||
}
|
||||
|
||||
// Brace expansion:
|
||||
// a{b,c}d -> abd acd
|
||||
// a{b,}c -> abc ac
|
||||
// a{0..3}d -> a0d a1d a2d a3d
|
||||
// a{b,c{d,e}f}g -> abg acdfg acefg
|
||||
// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
|
||||
//
|
||||
// Invalid sets are not expanded.
|
||||
// a{2..}b -> a{2..}b
|
||||
// a{b}c -> a{b}c
|
||||
minimatch.braceExpand = function (pattern, options) {
|
||||
return braceExpand(pattern, options)
|
||||
}
|
||||
|
||||
Minimatch.prototype.braceExpand = braceExpand
|
||||
|
||||
function braceExpand (pattern, options) {
|
||||
if (!options) {
|
||||
if (this instanceof Minimatch) {
|
||||
options = this.options
|
||||
} else {
|
||||
options = {}
|
||||
}
|
||||
}
|
||||
|
||||
pattern = typeof pattern === 'undefined'
|
||||
? this.pattern : pattern
|
||||
|
||||
assertValidPattern(pattern)
|
||||
|
||||
// Thanks to Yeting Li <https://github.com/yetingli> for
|
||||
// improving this regexp to avoid a ReDOS vulnerability.
|
||||
if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
|
||||
// shortcut. no need to expand.
|
||||
return [pattern]
|
||||
}
|
||||
|
||||
return expand(pattern)
|
||||
}
|
||||
|
||||
var MAX_PATTERN_LENGTH = 1024 * 64
|
||||
var assertValidPattern = function (pattern) {
|
||||
if (typeof pattern !== 'string') {
|
||||
throw new TypeError('invalid pattern')
|
||||
}
|
||||
|
||||
if (pattern.length > MAX_PATTERN_LENGTH) {
|
||||
throw new TypeError('pattern is too long')
|
||||
}
|
||||
}
|
||||
|
||||
// parse a component of the expanded set.
|
||||
// At this point, no pattern may contain "/" in it
|
||||
// so we're going to return a 2d array, where each entry is the full
|
||||
// pattern, split on '/', and then turned into a regular expression.
|
||||
// A regexp is made at the end which joins each array with an
|
||||
// escaped /, and another full one which joins each regexp with |.
|
||||
//
|
||||
// Following the lead of Bash 4.1, note that "**" only has special meaning
|
||||
// when it is the *only* thing in a path portion. Otherwise, any series
|
||||
// of * is equivalent to a single *. Globstar behavior is enabled by
|
||||
// default, and can be disabled by setting options.noglobstar.
|
||||
Minimatch.prototype.parse = parse
|
||||
var SUBPARSE = {}
|
||||
function parse (pattern, isSub) {
|
||||
assertValidPattern(pattern)
|
||||
|
||||
var options = this.options
|
||||
|
||||
// shortcuts
|
||||
if (pattern === '**') {
|
||||
if (!options.noglobstar)
|
||||
return GLOBSTAR
|
||||
else
|
||||
pattern = '*'
|
||||
}
|
||||
if (pattern === '') return ''
|
||||
|
||||
var re = ''
|
||||
var hasMagic = !!options.nocase
|
||||
var escaping = false
|
||||
// ? => one single character
|
||||
var patternListStack = []
|
||||
var negativeLists = []
|
||||
var stateChar
|
||||
var inClass = false
|
||||
var reClassStart = -1
|
||||
var classStart = -1
|
||||
// . and .. never match anything that doesn't start with .,
|
||||
// even when options.dot is set.
|
||||
var patternStart = pattern.charAt(0) === '.' ? '' // anything
|
||||
// not (start or / followed by . or .. followed by / or end)
|
||||
: options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
|
||||
: '(?!\\.)'
|
||||
var self = this
|
||||
|
||||
function clearStateChar () {
|
||||
if (stateChar) {
|
||||
// we had some state-tracking character
|
||||
// that wasn't consumed by this pass.
|
||||
switch (stateChar) {
|
||||
case '*':
|
||||
re += star
|
||||
hasMagic = true
|
||||
break
|
||||
case '?':
|
||||
re += qmark
|
||||
hasMagic = true
|
||||
break
|
||||
default:
|
||||
re += '\\' + stateChar
|
||||
break
|
||||
}
|
||||
self.debug('clearStateChar %j %j', stateChar, re)
|
||||
stateChar = false
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0, len = pattern.length, c
|
||||
; (i < len) && (c = pattern.charAt(i))
|
||||
; i++) {
|
||||
this.debug('%s\t%s %s %j', pattern, i, re, c)
|
||||
|
||||
// skip over any that are escaped.
|
||||
if (escaping && reSpecials[c]) {
|
||||
re += '\\' + c
|
||||
escaping = false
|
||||
continue
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
/* istanbul ignore next */
|
||||
case '/': {
|
||||
// completely not allowed, even escaped.
|
||||
// Should already be path-split by now.
|
||||
return false
|
||||
}
|
||||
|
||||
case '\\':
|
||||
clearStateChar()
|
||||
escaping = true
|
||||
continue
|
||||
|
||||
// the various stateChar values
|
||||
// for the "extglob" stuff.
|
||||
case '?':
|
||||
case '*':
|
||||
case '+':
|
||||
case '@':
|
||||
case '!':
|
||||
this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
|
||||
|
||||
// all of those are literals inside a class, except that
|
||||
// the glob [!a] means [^a] in regexp
|
||||
if (inClass) {
|
||||
this.debug(' in class')
|
||||
if (c === '!' && i === classStart + 1) c = '^'
|
||||
re += c
|
||||
continue
|
||||
}
|
||||
|
||||
// if we already have a stateChar, then it means
|
||||
// that there was something like ** or +? in there.
|
||||
// Handle the stateChar, then proceed with this one.
|
||||
self.debug('call clearStateChar %j', stateChar)
|
||||
clearStateChar()
|
||||
stateChar = c
|
||||
// if extglob is disabled, then +(asdf|foo) isn't a thing.
|
||||
// just clear the statechar *now*, rather than even diving into
|
||||
// the patternList stuff.
|
||||
if (options.noext) clearStateChar()
|
||||
continue
|
||||
|
||||
case '(':
|
||||
if (inClass) {
|
||||
re += '('
|
||||
continue
|
||||
}
|
||||
|
||||
if (!stateChar) {
|
||||
re += '\\('
|
||||
continue
|
||||
}
|
||||
|
||||
patternListStack.push({
|
||||
type: stateChar,
|
||||
start: i - 1,
|
||||
reStart: re.length,
|
||||
open: plTypes[stateChar].open,
|
||||
close: plTypes[stateChar].close
|
||||
})
|
||||
// negation is (?:(?!js)[^/]*)
|
||||
re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
|
||||
this.debug('plType %j %j', stateChar, re)
|
||||
stateChar = false
|
||||
continue
|
||||
|
||||
case ')':
|
||||
if (inClass || !patternListStack.length) {
|
||||
re += '\\)'
|
||||
continue
|
||||
}
|
||||
|
||||
clearStateChar()
|
||||
hasMagic = true
|
||||
var pl = patternListStack.pop()
|
||||
// negation is (?:(?!js)[^/]*)
|
||||
// The others are (?:<pattern>)<type>
|
||||
re += pl.close
|
||||
if (pl.type === '!') {
|
||||
negativeLists.push(pl)
|
||||
}
|
||||
pl.reEnd = re.length
|
||||
continue
|
||||
|
||||
case '|':
|
||||
if (inClass || !patternListStack.length || escaping) {
|
||||
re += '\\|'
|
||||
escaping = false
|
||||
continue
|
||||
}
|
||||
|
||||
clearStateChar()
|
||||
re += '|'
|
||||
continue
|
||||
|
||||
// these are mostly the same in regexp and glob
|
||||
case '[':
|
||||
// swallow any state-tracking char before the [
|
||||
clearStateChar()
|
||||
|
||||
if (inClass) {
|
||||
re += '\\' + c
|
||||
continue
|
||||
}
|
||||
|
||||
inClass = true
|
||||
classStart = i
|
||||
reClassStart = re.length
|
||||
re += c
|
||||
continue
|
||||
|
||||
case ']':
|
||||
// a right bracket shall lose its special
|
||||
// meaning and represent itself in
|
||||
// a bracket expression if it occurs
|
||||
// first in the list. -- POSIX.2 2.8.3.2
|
||||
if (i === classStart + 1 || !inClass) {
|
||||
re += '\\' + c
|
||||
escaping = false
|
||||
continue
|
||||
}
|
||||
|
||||
// handle the case where we left a class open.
|
||||
// "[z-a]" is valid, equivalent to "\[z-a\]"
|
||||
// split where the last [ was, make sure we don't have
|
||||
// an invalid re. if so, re-walk the contents of the
|
||||
// would-be class to re-translate any characters that
|
||||
// were passed through as-is
|
||||
// TODO: It would probably be faster to determine this
|
||||
// without a try/catch and a new RegExp, but it's tricky
|
||||
// to do safely. For now, this is safe and works.
|
||||
var cs = pattern.substring(classStart + 1, i)
|
||||
try {
|
||||
RegExp('[' + cs + ']')
|
||||
} catch (er) {
|
||||
// not a valid class!
|
||||
var sp = this.parse(cs, SUBPARSE)
|
||||
re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
|
||||
hasMagic = hasMagic || sp[1]
|
||||
inClass = false
|
||||
continue
|
||||
}
|
||||
|
||||
// finish up the class.
|
||||
hasMagic = true
|
||||
inClass = false
|
||||
re += c
|
||||
continue
|
||||
|
||||
default:
|
||||
// swallow any state char that wasn't consumed
|
||||
clearStateChar()
|
||||
|
||||
if (escaping) {
|
||||
// no need
|
||||
escaping = false
|
||||
} else if (reSpecials[c]
|
||||
&& !(c === '^' && inClass)) {
|
||||
re += '\\'
|
||||
}
|
||||
|
||||
re += c
|
||||
|
||||
} // switch
|
||||
} // for
|
||||
|
||||
// handle the case where we left a class open.
|
||||
// "[abc" is valid, equivalent to "\[abc"
|
||||
if (inClass) {
|
||||
// split where the last [ was, and escape it
|
||||
// this is a huge pita. We now have to re-walk
|
||||
// the contents of the would-be class to re-translate
|
||||
// any characters that were passed through as-is
|
||||
cs = pattern.substr(classStart + 1)
|
||||
sp = this.parse(cs, SUBPARSE)
|
||||
re = re.substr(0, reClassStart) + '\\[' + sp[0]
|
||||
hasMagic = hasMagic || sp[1]
|
||||
}
|
||||
|
||||
// handle the case where we had a +( thing at the *end*
|
||||
// of the pattern.
|
||||
// each pattern list stack adds 3 chars, and we need to go through
|
||||
// and escape any | chars that were passed through as-is for the regexp.
|
||||
// Go through and escape them, taking care not to double-escape any
|
||||
// | chars that were already escaped.
|
||||
for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
|
||||
var tail = re.slice(pl.reStart + pl.open.length)
|
||||
this.debug('setting tail', re, pl)
|
||||
// maybe some even number of \, then maybe 1 \, followed by a |
|
||||
tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
|
||||
if (!$2) {
|
||||
// the | isn't already escaped, so escape it.
|
||||
$2 = '\\'
|
||||
}
|
||||
|
||||
// need to escape all those slashes *again*, without escaping the
|
||||
// one that we need for escaping the | character. As it works out,
|
||||
// escaping an even number of slashes can be done by simply repeating
|
||||
// it exactly after itself. That's why this trick works.
|
||||
//
|
||||
// I am sorry that you have to see this.
|
||||
return $1 + $1 + $2 + '|'
|
||||
})
|
||||
|
||||
this.debug('tail=%j\n %s', tail, tail, pl, re)
|
||||
var t = pl.type === '*' ? star
|
||||
: pl.type === '?' ? qmark
|
||||
: '\\' + pl.type
|
||||
|
||||
hasMagic = true
|
||||
re = re.slice(0, pl.reStart) + t + '\\(' + tail
|
||||
}
|
||||
|
||||
// handle trailing things that only matter at the very end.
|
||||
clearStateChar()
|
||||
if (escaping) {
|
||||
// trailing \\
|
||||
re += '\\\\'
|
||||
}
|
||||
|
||||
// only need to apply the nodot start if the re starts with
|
||||
// something that could conceivably capture a dot
|
||||
var addPatternStart = false
|
||||
switch (re.charAt(0)) {
|
||||
case '[': case '.': case '(': addPatternStart = true
|
||||
}
|
||||
|
||||
// Hack to work around lack of negative lookbehind in JS
|
||||
// A pattern like: *.!(x).!(y|z) needs to ensure that a name
|
||||
// like 'a.xyz.yz' doesn't match. So, the first negative
|
||||
// lookahead, has to look ALL the way ahead, to the end of
|
||||
// the pattern.
|
||||
for (var n = negativeLists.length - 1; n > -1; n--) {
|
||||
var nl = negativeLists[n]
|
||||
|
||||
var nlBefore = re.slice(0, nl.reStart)
|
||||
var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
|
||||
var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
|
||||
var nlAfter = re.slice(nl.reEnd)
|
||||
|
||||
nlLast += nlAfter
|
||||
|
||||
// Handle nested stuff like *(*.js|!(*.json)), where open parens
|
||||
// mean that we should *not* include the ) in the bit that is considered
|
||||
// "after" the negated section.
|
||||
var openParensBefore = nlBefore.split('(').length - 1
|
||||
var cleanAfter = nlAfter
|
||||
for (i = 0; i < openParensBefore; i++) {
|
||||
cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
|
||||
}
|
||||
nlAfter = cleanAfter
|
||||
|
||||
var dollar = ''
|
||||
if (nlAfter === '' && isSub !== SUBPARSE) {
|
||||
dollar = '$'
|
||||
}
|
||||
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
|
||||
re = newRe
|
||||
}
|
||||
|
||||
// if the re is not "" at this point, then we need to make sure
|
||||
// it doesn't match against an empty path part.
|
||||
// Otherwise a/* will match a/, which it should not.
|
||||
if (re !== '' && hasMagic) {
|
||||
re = '(?=.)' + re
|
||||
}
|
||||
|
||||
if (addPatternStart) {
|
||||
re = patternStart + re
|
||||
}
|
||||
|
||||
// parsing just a piece of a larger pattern.
|
||||
if (isSub === SUBPARSE) {
|
||||
return [re, hasMagic]
|
||||
}
|
||||
|
||||
// skip the regexp for non-magical patterns
|
||||
// unescape anything in it, though, so that it'll be
|
||||
// an exact match against a file etc.
|
||||
if (!hasMagic) {
|
||||
return globUnescape(pattern)
|
||||
}
|
||||
|
||||
var flags = options.nocase ? 'i' : ''
|
||||
try {
|
||||
var regExp = new RegExp('^' + re + '$', flags)
|
||||
} catch (er) /* istanbul ignore next - should be impossible */ {
|
||||
// If it was an invalid regular expression, then it can't match
|
||||
// anything. This trick looks for a character after the end of
|
||||
// the string, which is of course impossible, except in multi-line
|
||||
// mode, but it's not a /m regex.
|
||||
return new RegExp('$.')
|
||||
}
|
||||
|
||||
regExp._glob = pattern
|
||||
regExp._src = re
|
||||
|
||||
return regExp
|
||||
}
|
||||
|
||||
minimatch.makeRe = function (pattern, options) {
|
||||
return new Minimatch(pattern, options || {}).makeRe()
|
||||
}
|
||||
|
||||
Minimatch.prototype.makeRe = makeRe
|
||||
function makeRe () {
|
||||
if (this.regexp || this.regexp === false) return this.regexp
|
||||
|
||||
// at this point, this.set is a 2d array of partial
|
||||
// pattern strings, or "**".
|
||||
//
|
||||
// It's better to use .match(). This function shouldn't
|
||||
// be used, really, but it's pretty convenient sometimes,
|
||||
// when you just want to work with a regex.
|
||||
var set = this.set
|
||||
|
||||
if (!set.length) {
|
||||
this.regexp = false
|
||||
return this.regexp
|
||||
}
|
||||
var options = this.options
|
||||
|
||||
var twoStar = options.noglobstar ? star
|
||||
: options.dot ? twoStarDot
|
||||
: twoStarNoDot
|
||||
var flags = options.nocase ? 'i' : ''
|
||||
|
||||
var re = set.map(function (pattern) {
|
||||
return pattern.map(function (p) {
|
||||
return (p === GLOBSTAR) ? twoStar
|
||||
: (typeof p === 'string') ? regExpEscape(p)
|
||||
: p._src
|
||||
}).join('\\\/')
|
||||
}).join('|')
|
||||
|
||||
// must match entire pattern
|
||||
// ending in a * or ** will make it less strict.
|
||||
re = '^(?:' + re + ')$'
|
||||
|
||||
// can match anything, as long as it's not this.
|
||||
if (this.negate) re = '^(?!' + re + ').*$'
|
||||
|
||||
try {
|
||||
this.regexp = new RegExp(re, flags)
|
||||
} catch (ex) /* istanbul ignore next - should be impossible */ {
|
||||
this.regexp = false
|
||||
}
|
||||
return this.regexp
|
||||
}
|
||||
|
||||
minimatch.match = function (list, pattern, options) {
|
||||
options = options || {}
|
||||
var mm = new Minimatch(pattern, options)
|
||||
list = list.filter(function (f) {
|
||||
return mm.match(f)
|
||||
})
|
||||
if (mm.options.nonull && !list.length) {
|
||||
list.push(pattern)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
Minimatch.prototype.match = function match (f, partial) {
|
||||
if (typeof partial === 'undefined') partial = this.partial
|
||||
this.debug('match', f, this.pattern)
|
||||
// short-circuit in the case of busted things.
|
||||
// comments, etc.
|
||||
if (this.comment) return false
|
||||
if (this.empty) return f === ''
|
||||
|
||||
if (f === '/' && partial) return true
|
||||
|
||||
var options = this.options
|
||||
|
||||
// windows: need to use /, not \
|
||||
if (path.sep !== '/') {
|
||||
f = f.split(path.sep).join('/')
|
||||
}
|
||||
|
||||
// treat the test path as a set of pathparts.
|
||||
f = f.split(slashSplit)
|
||||
this.debug(this.pattern, 'split', f)
|
||||
|
||||
// just ONE of the pattern sets in this.set needs to match
|
||||
// in order for it to be valid. If negating, then just one
|
||||
// match means that we have failed.
|
||||
// Either way, return on the first hit.
|
||||
|
||||
var set = this.set
|
||||
this.debug(this.pattern, 'set', set)
|
||||
|
||||
// Find the basename of the path by looking for the last non-empty segment
|
||||
var filename
|
||||
var i
|
||||
for (i = f.length - 1; i >= 0; i--) {
|
||||
filename = f[i]
|
||||
if (filename) break
|
||||
}
|
||||
|
||||
for (i = 0; i < set.length; i++) {
|
||||
var pattern = set[i]
|
||||
var file = f
|
||||
if (options.matchBase && pattern.length === 1) {
|
||||
file = [filename]
|
||||
}
|
||||
var hit = this.matchOne(file, pattern, partial)
|
||||
if (hit) {
|
||||
if (options.flipNegate) return true
|
||||
return !this.negate
|
||||
}
|
||||
}
|
||||
|
||||
// didn't get any hits. this is success if it's a negative
|
||||
// pattern, failure otherwise.
|
||||
if (options.flipNegate) return false
|
||||
return this.negate
|
||||
}
|
||||
|
||||
// set partial to true to test if, for example,
|
||||
// "/a/b" matches the start of "/*/b/*/d"
|
||||
// Partial means, if you run out of file before you run
|
||||
// out of pattern, then that's fine, as long as all
|
||||
// the parts match.
|
||||
Minimatch.prototype.matchOne = function (file, pattern, partial) {
|
||||
var options = this.options
|
||||
|
||||
this.debug('matchOne',
|
||||
{ 'this': this, file: file, pattern: pattern })
|
||||
|
||||
this.debug('matchOne', file.length, pattern.length)
|
||||
|
||||
for (var fi = 0,
|
||||
pi = 0,
|
||||
fl = file.length,
|
||||
pl = pattern.length
|
||||
; (fi < fl) && (pi < pl)
|
||||
; fi++, pi++) {
|
||||
this.debug('matchOne loop')
|
||||
var p = pattern[pi]
|
||||
var f = file[fi]
|
||||
|
||||
this.debug(pattern, p, f)
|
||||
|
||||
// should be impossible.
|
||||
// some invalid regexp stuff in the set.
|
||||
/* istanbul ignore if */
|
||||
if (p === false) return false
|
||||
|
||||
if (p === GLOBSTAR) {
|
||||
this.debug('GLOBSTAR', [pattern, p, f])
|
||||
|
||||
// "**"
|
||||
// a/**/b/**/c would match the following:
|
||||
// a/b/x/y/z/c
|
||||
// a/x/y/z/b/c
|
||||
// a/b/x/b/x/c
|
||||
// a/b/c
|
||||
// To do this, take the rest of the pattern after
|
||||
// the **, and see if it would match the file remainder.
|
||||
// If so, return success.
|
||||
// If not, the ** "swallows" a segment, and try again.
|
||||
// This is recursively awful.
|
||||
//
|
||||
// a/**/b/**/c matching a/b/x/y/z/c
|
||||
// - a matches a
|
||||
// - doublestar
|
||||
// - matchOne(b/x/y/z/c, b/**/c)
|
||||
// - b matches b
|
||||
// - doublestar
|
||||
// - matchOne(x/y/z/c, c) -> no
|
||||
// - matchOne(y/z/c, c) -> no
|
||||
// - matchOne(z/c, c) -> no
|
||||
// - matchOne(c, c) yes, hit
|
||||
var fr = fi
|
||||
var pr = pi + 1
|
||||
if (pr === pl) {
|
||||
this.debug('** at the end')
|
||||
// a ** at the end will just swallow the rest.
|
||||
// We have found a match.
|
||||
// however, it will not swallow /.x, unless
|
||||
// options.dot is set.
|
||||
// . and .. are *never* matched by **, for explosively
|
||||
// exponential reasons.
|
||||
for (; fi < fl; fi++) {
|
||||
if (file[fi] === '.' || file[fi] === '..' ||
|
||||
(!options.dot && file[fi].charAt(0) === '.')) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ok, let's see if we can swallow whatever we can.
|
||||
while (fr < fl) {
|
||||
var swallowee = file[fr]
|
||||
|
||||
this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
|
||||
|
||||
// XXX remove this slice. Just pass the start index.
|
||||
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
|
||||
this.debug('globstar found match!', fr, fl, swallowee)
|
||||
// found a match.
|
||||
return true
|
||||
} else {
|
||||
// can't swallow "." or ".." ever.
|
||||
// can only swallow ".foo" when explicitly asked.
|
||||
if (swallowee === '.' || swallowee === '..' ||
|
||||
(!options.dot && swallowee.charAt(0) === '.')) {
|
||||
this.debug('dot detected!', file, fr, pattern, pr)
|
||||
break
|
||||
}
|
||||
|
||||
// ** swallows a segment, and continue.
|
||||
this.debug('globstar swallow a segment, and continue')
|
||||
fr++
|
||||
}
|
||||
}
|
||||
|
||||
// no match was found.
|
||||
// However, in partial mode, we can't say this is necessarily over.
|
||||
// If there's more *pattern* left, then
|
||||
/* istanbul ignore if */
|
||||
if (partial) {
|
||||
// ran out of file
|
||||
this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
|
||||
if (fr === fl) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// something other than **
|
||||
// non-magic patterns just have to match exactly
|
||||
// patterns with magic have been turned into regexps.
|
||||
var hit
|
||||
if (typeof p === 'string') {
|
||||
hit = f === p
|
||||
this.debug('string match', p, f, hit)
|
||||
} else {
|
||||
hit = f.match(p)
|
||||
this.debug('pattern match', p, f, hit)
|
||||
}
|
||||
|
||||
if (!hit) return false
|
||||
}
|
||||
|
||||
// Note: ending in / means that we'll get a final ""
|
||||
// at the end of the pattern. This can only match a
|
||||
// corresponding "" at the end of the file.
|
||||
// If the file ends in /, then it can only match a
|
||||
// a pattern that ends in /, unless the pattern just
|
||||
// doesn't have any more for it. But, a/b/ should *not*
|
||||
// match "a/b/*", even though "" matches against the
|
||||
// [^/]*? pattern, except in partial mode, where it might
|
||||
// simply not be reached yet.
|
||||
// However, a/b/ should still satisfy a/*
|
||||
|
||||
// now either we fell off the end of the pattern, or we're done.
|
||||
if (fi === fl && pi === pl) {
|
||||
// ran out of pattern and filename at the same time.
|
||||
// an exact hit!
|
||||
return true
|
||||
} else if (fi === fl) {
|
||||
// ran out of file, but still had pattern left.
|
||||
// this is ok if we're doing the match as part of
|
||||
// a glob fs traversal.
|
||||
return partial
|
||||
} else /* istanbul ignore else */ if (pi === pl) {
|
||||
// ran out of pattern, still have file left.
|
||||
// this is only acceptable if we're on the very last
|
||||
// empty segment of a file with a trailing slash.
|
||||
// a/* should match a/b/
|
||||
return (fi === fl - 1) && (file[fi] === '')
|
||||
}
|
||||
|
||||
// should be unreachable.
|
||||
/* istanbul ignore next */
|
||||
throw new Error('wtf?')
|
||||
}
|
||||
|
||||
// replace stuff like \* with *
|
||||
function globUnescape (s) {
|
||||
return s.replace(/\\(.)/g, '$1')
|
||||
}
|
||||
|
||||
function regExpEscape (s) {
|
||||
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
||||
"name": "minimatch",
|
||||
"description": "a glob matcher in javascript",
|
||||
"version": "3.1.2",
|
||||
"publishConfig": {
|
||||
"tag": "v3-legacy"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/isaacs/minimatch.git"
|
||||
},
|
||||
"main": "minimatch.js",
|
||||
"scripts": {
|
||||
"test": "tap",
|
||||
"preversion": "npm test",
|
||||
"postversion": "npm publish",
|
||||
"postpublish": "git push origin --all; git push origin --tags"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tap": "^15.1.6"
|
||||
},
|
||||
"license": "ISC",
|
||||
"files": [
|
||||
"minimatch.js"
|
||||
]
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"name": "browserify",
|
||||
"version": "17.0.0",
|
||||
"description": "browser-side require() the node way",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"browserify": "bin/cmd.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/browserify/browserify.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"keywords": [
|
||||
"browser",
|
||||
"require",
|
||||
"commonjs",
|
||||
"commonj-esque",
|
||||
"bundle",
|
||||
"npm",
|
||||
"javascript"
|
||||
],
|
||||
"dependencies": {
|
||||
"JSONStream": "^1.0.3",
|
||||
"assert": "^1.4.0",
|
||||
"browser-pack": "^6.0.1",
|
||||
"browser-resolve": "^2.0.0",
|
||||
"browserify-zlib": "~0.2.0",
|
||||
"buffer": "~5.2.1",
|
||||
"cached-path-relative": "^1.0.0",
|
||||
"concat-stream": "^1.6.0",
|
||||
"console-browserify": "^1.1.0",
|
||||
"constants-browserify": "~1.0.0",
|
||||
"crypto-browserify": "^3.0.0",
|
||||
"defined": "^1.0.0",
|
||||
"deps-sort": "^2.0.1",
|
||||
"domain-browser": "^1.2.0",
|
||||
"duplexer2": "~0.1.2",
|
||||
"events": "^3.0.0",
|
||||
"glob": "^7.1.0",
|
||||
"has": "^1.0.0",
|
||||
"htmlescape": "^1.1.0",
|
||||
"https-browserify": "^1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"insert-module-globals": "^7.2.1",
|
||||
"labeled-stream-splicer": "^2.0.0",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"module-deps": "^6.2.3",
|
||||
"os-browserify": "~0.3.0",
|
||||
"parents": "^1.0.1",
|
||||
"path-browserify": "^1.0.0",
|
||||
"process": "~0.11.0",
|
||||
"punycode": "^1.3.2",
|
||||
"querystring-es3": "~0.2.0",
|
||||
"read-only-stream": "^2.0.0",
|
||||
"readable-stream": "^2.0.2",
|
||||
"resolve": "^1.1.4",
|
||||
"shasum-object": "^1.0.0",
|
||||
"shell-quote": "^1.6.1",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"stream-http": "^3.0.0",
|
||||
"string_decoder": "^1.1.1",
|
||||
"subarg": "^1.0.0",
|
||||
"syntax-error": "^1.1.1",
|
||||
"through2": "^2.0.0",
|
||||
"timers-browserify": "^1.0.1",
|
||||
"tty-browserify": "0.0.1",
|
||||
"url": "~0.11.0",
|
||||
"util": "~0.12.0",
|
||||
"vm-browserify": "^1.0.0",
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"backbone": "~0.9.2",
|
||||
"browser-unpack": "^1.1.1",
|
||||
"coffee-script": "~1.10.0",
|
||||
"coffeeify": "~1.1.0",
|
||||
"has-object-spread": "^1.0.0",
|
||||
"has-template-literals": "^1.0.0",
|
||||
"isstream": "^0.1.2",
|
||||
"make-generator-function": "^1.1.0",
|
||||
"semver": "^5.5.0",
|
||||
"seq": "0.3.5",
|
||||
"tap": "^10.7.2",
|
||||
"temp": "=0.8.3",
|
||||
"through": "^2.3.4"
|
||||
},
|
||||
"author": {
|
||||
"name": "James Halliday",
|
||||
"email": "mail@substack.net",
|
||||
"url": "http://substack.net"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tap test/*.js"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
+831
@@ -0,0 +1,831 @@
|
||||
# browserify
|
||||
|
||||
`require('modules')` in the browser
|
||||
|
||||
Use a [node](http://nodejs.org)-style `require()` to organize your browser code
|
||||
and load modules installed by [npm](https://www.npmjs.com).
|
||||
|
||||
browserify will recursively analyze all the `require()` calls in your app in
|
||||
order to build a bundle you can serve up to the browser in a single `<script>`
|
||||
tag.
|
||||
|
||||
[](https://travis-ci.org/browserify/browserify)
|
||||
|
||||

|
||||
|
||||
# getting started
|
||||
|
||||
If you're new to browserify, check out the
|
||||
[browserify handbook](https://github.com/browserify/browserify-handbook)
|
||||
and the resources on [browserify.org](http://browserify.org/).
|
||||
|
||||
# example
|
||||
|
||||
Whip up a file, `main.js` with some `require()`s in it. You can use relative
|
||||
paths like `'./foo.js'` and `'../lib/bar.js'` or module paths like `'gamma'`
|
||||
that will search `node_modules/` using
|
||||
[node's module lookup algorithm](https://github.com/browserify/resolve).
|
||||
|
||||
``` js
|
||||
var foo = require('./foo.js');
|
||||
var bar = require('../lib/bar.js');
|
||||
var gamma = require('gamma');
|
||||
|
||||
var elem = document.getElementById('result');
|
||||
var x = foo(100) + bar('baz');
|
||||
elem.textContent = gamma(x);
|
||||
```
|
||||
|
||||
Export functionality by assigning onto `module.exports` or `exports`:
|
||||
|
||||
``` js
|
||||
module.exports = function (n) { return n * 111 }
|
||||
```
|
||||
|
||||
Now just use the `browserify` command to build a bundle starting at `main.js`:
|
||||
|
||||
```
|
||||
$ browserify main.js > bundle.js
|
||||
```
|
||||
|
||||
All of the modules that `main.js` needs are included in the `bundle.js` from a
|
||||
recursive walk of the `require()` graph using
|
||||
[required](https://github.com/defunctzombie/node-required).
|
||||
|
||||
To use this bundle, just toss a `<script src="bundle.js"></script>` into your
|
||||
html!
|
||||
|
||||
# install
|
||||
|
||||
With [npm](https://www.npmjs.com/) do:
|
||||
|
||||
```
|
||||
npm install -g browserify
|
||||
```
|
||||
|
||||
# usage
|
||||
|
||||
```
|
||||
Usage: browserify [entry files] {OPTIONS}
|
||||
|
||||
Standard Options:
|
||||
|
||||
--outfile, -o Write the browserify bundle to this file.
|
||||
If unspecified, browserify prints to stdout.
|
||||
|
||||
--require, -r A module name or file to bundle.require()
|
||||
Optionally use a colon separator to set the target.
|
||||
|
||||
--entry, -e An entry point of your app
|
||||
|
||||
--ignore, -i Replace a file with an empty stub. Files can be globs.
|
||||
|
||||
--exclude, -u Omit a file from the output bundle. Files can be globs.
|
||||
|
||||
--external, -x Reference a file from another bundle. Files can be globs.
|
||||
|
||||
--transform, -t Use a transform module on top-level files.
|
||||
|
||||
--command, -c Use a transform command on top-level files.
|
||||
|
||||
--standalone -s Generate a UMD bundle for the supplied export name.
|
||||
This bundle works with other module systems and sets the name
|
||||
given as a window global if no module system is found.
|
||||
|
||||
--debug -d Enable source maps that allow you to debug your files
|
||||
separately.
|
||||
|
||||
--help, -h Show this message
|
||||
|
||||
For advanced options, type `browserify --help advanced`.
|
||||
|
||||
Specify a parameter.
|
||||
```
|
||||
|
||||
```
|
||||
Advanced Options:
|
||||
|
||||
--insert-globals, --ig, --fast [default: false]
|
||||
|
||||
Skip detection and always insert definitions for process, global,
|
||||
__filename, and __dirname.
|
||||
|
||||
benefit: faster builds
|
||||
cost: extra bytes
|
||||
|
||||
--insert-global-vars, --igv
|
||||
|
||||
Comma-separated list of global variables to detect and define.
|
||||
Default: __filename,__dirname,process,Buffer,global
|
||||
|
||||
--detect-globals, --dg [default: true]
|
||||
|
||||
Detect the presence of process, global, __filename, and __dirname and define
|
||||
these values when present.
|
||||
|
||||
benefit: npm modules more likely to work
|
||||
cost: slower builds
|
||||
|
||||
--ignore-missing, --im [default: false]
|
||||
|
||||
Ignore `require()` statements that don't resolve to anything.
|
||||
|
||||
--noparse=FILE
|
||||
|
||||
Don't parse FILE at all. This will make bundling much, much faster for giant
|
||||
libs like jquery or threejs.
|
||||
|
||||
--no-builtins
|
||||
|
||||
Turn off builtins. This is handy when you want to run a bundle in node which
|
||||
provides the core builtins.
|
||||
|
||||
--no-commondir
|
||||
|
||||
Turn off setting a commondir. This is useful if you want to preserve the
|
||||
original paths that a bundle was generated with.
|
||||
|
||||
--no-bundle-external
|
||||
|
||||
Turn off bundling of all external modules. This is useful if you only want
|
||||
to bundle your local files.
|
||||
|
||||
--bare
|
||||
|
||||
Alias for both --no-builtins, --no-commondir, and sets --insert-global-vars
|
||||
to just "__filename,__dirname". This is handy if you want to run bundles in
|
||||
node.
|
||||
|
||||
--no-browser-field, --no-bf
|
||||
|
||||
Turn off package.json browser field resolution. This is also handy if you
|
||||
need to run a bundle in node.
|
||||
|
||||
--transform-key
|
||||
|
||||
Instead of the default package.json#browserify#transform field to list
|
||||
all transforms to apply when running browserify, a custom field, like, e.g.
|
||||
package.json#browserify#production or package.json#browserify#staging
|
||||
can be used, by for example running:
|
||||
* `browserify index.js --transform-key=production > bundle.js`
|
||||
* `browserify index.js --transform-key=staging > bundle.js`
|
||||
|
||||
--node
|
||||
|
||||
Alias for --bare and --no-browser-field.
|
||||
|
||||
--full-paths
|
||||
|
||||
Turn off converting module ids into numerical indexes. This is useful for
|
||||
preserving the original paths that a bundle was generated with.
|
||||
|
||||
--deps
|
||||
|
||||
Instead of standard bundle output, print the dependency array generated by
|
||||
module-deps.
|
||||
|
||||
--no-dedupe
|
||||
|
||||
Turn off deduping.
|
||||
|
||||
--list
|
||||
|
||||
Print each file in the dependency graph. Useful for makefiles.
|
||||
|
||||
--extension=EXTENSION
|
||||
|
||||
Consider files with specified EXTENSION as modules, this option can used
|
||||
multiple times.
|
||||
|
||||
--global-transform=MODULE, -g MODULE
|
||||
|
||||
Use a transform module on all files after any ordinary transforms have run.
|
||||
|
||||
--ignore-transform=MODULE, -it MODULE
|
||||
|
||||
Do not run certain transformations, even if specified elsewhere.
|
||||
|
||||
--plugin=MODULE, -p MODULE
|
||||
|
||||
Register MODULE as a plugin.
|
||||
|
||||
Passing arguments to transforms and plugins:
|
||||
|
||||
For -t, -g, and -p, you may use subarg syntax to pass options to the
|
||||
transforms or plugin function as the second parameter. For example:
|
||||
|
||||
-t [ foo -x 3 --beep ]
|
||||
|
||||
will call the `foo` transform for each applicable file by calling:
|
||||
|
||||
foo(file, { x: 3, beep: true })
|
||||
|
||||
```
|
||||
|
||||
# compatibility
|
||||
|
||||
Many [npm](https://www.npmjs.com/) modules that don't do IO will just work after being
|
||||
browserified. Others take more work.
|
||||
|
||||
Many node built-in modules have been wrapped to work in the browser, but only
|
||||
when you explicitly `require()` or use their functionality.
|
||||
|
||||
When you `require()` any of these modules, you will get a browser-specific shim:
|
||||
|
||||
* [assert](https://www.npmjs.com/package/assert)
|
||||
* [buffer](https://www.npmjs.com/package/buffer)
|
||||
* [console](https://www.npmjs.com/package/console-browserify)
|
||||
* [constants](https://www.npmjs.com/package/constants-browserify)
|
||||
* [crypto](https://www.npmjs.com/package/crypto-browserify)
|
||||
* [domain](https://www.npmjs.com/package/domain-browser)
|
||||
* [events](https://www.npmjs.com/package/events)
|
||||
* [http](https://www.npmjs.com/package/stream-http)
|
||||
* [https](https://www.npmjs.com/package/https-browserify)
|
||||
* [os](https://www.npmjs.com/package/os-browserify)
|
||||
* [path](https://www.npmjs.com/package/path-browserify)
|
||||
* [punycode](https://www.npmjs.com/package/punycode)
|
||||
* [querystring](https://www.npmjs.com/package/querystring-es3)
|
||||
* [stream](https://www.npmjs.com/package/stream-browserify)
|
||||
* [string_decoder](https://www.npmjs.com/package/string_decoder)
|
||||
* [timers](https://www.npmjs.com/package/timers-browserify)
|
||||
* [tty](https://www.npmjs.com/package/tty-browserify)
|
||||
* [url](https://www.npmjs.com/package/url)
|
||||
* [util](https://www.npmjs.com/package/util)
|
||||
* [vm](https://www.npmjs.com/package/vm-browserify)
|
||||
* [zlib](https://www.npmjs.com/package/browserify-zlib)
|
||||
|
||||
Additionally, if you use any of these variables, they
|
||||
[will be defined](https://github.com/browserify/insert-module-globals)
|
||||
in the bundled output in a browser-appropriate way:
|
||||
|
||||
* [process](https://www.npmjs.com/package/process)
|
||||
* [Buffer](https://www.npmjs.com/package/buffer)
|
||||
* global - top-level scope object (window)
|
||||
* __filename - file path of the currently executing file
|
||||
* __dirname - directory path of the currently executing file
|
||||
|
||||
# more examples
|
||||
|
||||
## external requires
|
||||
|
||||
You can just as easily create a bundle that will export a `require()` function so
|
||||
you can `require()` modules from another script tag. Here we'll create a
|
||||
`bundle.js` with the [through](https://www.npmjs.com/package/through)
|
||||
and [duplexer](https://www.npmjs.com/package/duplexer) modules.
|
||||
|
||||
```
|
||||
$ browserify -r through -r duplexer -r ./my-file.js:my-module > bundle.js
|
||||
```
|
||||
|
||||
Then in your page you can do:
|
||||
|
||||
``` html
|
||||
<script src="bundle.js"></script>
|
||||
<script>
|
||||
var through = require('through');
|
||||
var duplexer = require('duplexer');
|
||||
var myModule = require('my-module');
|
||||
/* ... */
|
||||
</script>
|
||||
```
|
||||
|
||||
## external source maps
|
||||
|
||||
If you prefer the source maps be saved to a separate `.js.map` source map file, you may use
|
||||
[exorcist](https://github.com/thlorenz/exorcist) in order to achieve that. It's as simple as:
|
||||
|
||||
```
|
||||
$ browserify main.js --debug | exorcist bundle.js.map > bundle.js
|
||||
```
|
||||
|
||||
Learn about additional options [here](https://github.com/thlorenz/exorcist#usage).
|
||||
|
||||
## multiple bundles
|
||||
|
||||
If browserify finds a `require`d function already defined in the page scope, it
|
||||
will fall back to that function if it didn't find any matches in its own set of
|
||||
bundled modules.
|
||||
|
||||
In this way, you can use browserify to split up bundles among multiple pages to
|
||||
get the benefit of caching for shared, infrequently-changing modules, while
|
||||
still being able to use `require()`. Just use a combination of `--external` and
|
||||
`--require` to factor out common dependencies.
|
||||
|
||||
For example, if a website with 2 pages, `beep.js`:
|
||||
|
||||
``` js
|
||||
var robot = require('./robot.js');
|
||||
console.log(robot('beep'));
|
||||
```
|
||||
|
||||
and `boop.js`:
|
||||
|
||||
``` js
|
||||
var robot = require('./robot.js');
|
||||
console.log(robot('boop'));
|
||||
```
|
||||
|
||||
both depend on `robot.js`:
|
||||
|
||||
``` js
|
||||
module.exports = function (s) { return s.toUpperCase() + '!' };
|
||||
```
|
||||
|
||||
```
|
||||
$ browserify -r ./robot.js > static/common.js
|
||||
$ browserify -x ./robot.js beep.js > static/beep.js
|
||||
$ browserify -x ./robot.js boop.js > static/boop.js
|
||||
```
|
||||
|
||||
Then on the beep page you can have:
|
||||
|
||||
``` html
|
||||
<script src="common.js"></script>
|
||||
<script src="beep.js"></script>
|
||||
```
|
||||
|
||||
while the boop page can have:
|
||||
|
||||
``` html
|
||||
<script src="common.js"></script>
|
||||
<script src="boop.js"></script>
|
||||
```
|
||||
|
||||
This approach using `-r` and `-x` works fine for a small number of split assets,
|
||||
but there are plugins for automatically factoring out components which are
|
||||
described in the
|
||||
[partitioning section of the browserify handbook](https://github.com/browserify/browserify-handbook#partitioning).
|
||||
|
||||
## api example
|
||||
|
||||
You can use the API directly too:
|
||||
|
||||
``` js
|
||||
var browserify = require('browserify');
|
||||
var b = browserify();
|
||||
b.add('./browser/main.js');
|
||||
b.bundle().pipe(process.stdout);
|
||||
```
|
||||
|
||||
# methods
|
||||
|
||||
``` js
|
||||
var browserify = require('browserify')
|
||||
```
|
||||
|
||||
## `browserify([files] [, opts])`
|
||||
|
||||
Returns a new browserify instance.
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
files
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
String, file object, or array of those types (they may be mixed) specifying entry file(s).
|
||||
</dd>
|
||||
|
||||
<dt>
|
||||
opts
|
||||
</dt>
|
||||
|
||||
<dd>
|
||||
Object.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
`files` and `opts` are both optional, but must be in the order shown if both are
|
||||
passed.
|
||||
|
||||
Entry files may be passed in `files` and / or `opts.entries`.
|
||||
|
||||
External requires may be specified in `opts.require`, accepting the same formats
|
||||
that the `files` argument does.
|
||||
|
||||
If an entry file is a stream, its contents will be used. You should pass
|
||||
`opts.basedir` when using streaming files so that relative requires can be
|
||||
resolved.
|
||||
|
||||
`opts.entries` has the same definition as `files`.
|
||||
|
||||
`opts.noParse` is an array which will skip all require() and global parsing for
|
||||
each file in the array. Use this for giant libs like jquery or threejs that
|
||||
don't have any requires or node-style globals but take forever to parse.
|
||||
|
||||
`opts.transform` is an array of transform functions or modules names which will
|
||||
transform the source code before the parsing.
|
||||
|
||||
`opts.ignoreTransform` is an array of transformations that will not be run,
|
||||
even if specified elsewhere.
|
||||
|
||||
`opts.plugin` is an array of plugin functions or module names to use. See the
|
||||
plugins section below for details.
|
||||
|
||||
`opts.extensions` is an array of optional extra extensions for the module lookup
|
||||
machinery to use when the extension has not been specified.
|
||||
By default browserify considers only `.js` and `.json` files in such cases.
|
||||
|
||||
`opts.basedir` is the directory that browserify starts bundling from for
|
||||
filenames that start with `.`.
|
||||
|
||||
`opts.paths` is an array of directories that browserify searches when looking
|
||||
for modules which are not referenced using relative path. Can be absolute or
|
||||
relative to `basedir`. Equivalent of setting `NODE_PATH` environmental variable
|
||||
when calling `browserify` command.
|
||||
|
||||
`opts.commondir` sets the algorithm used to parse out the common paths. Use
|
||||
`false` to turn this off, otherwise it uses the
|
||||
[commondir](https://www.npmjs.com/package/commondir) module.
|
||||
|
||||
`opts.fullPaths` disables converting module ids into numerical indexes. This is
|
||||
useful for preserving the original paths that a bundle was generated with.
|
||||
|
||||
`opts.builtins` sets the list of built-ins to use, which by default is set in
|
||||
`lib/builtins.js` in this distribution.
|
||||
|
||||
`opts.bundleExternal` boolean option to set if external modules should be
|
||||
bundled. Defaults to true.
|
||||
|
||||
When `opts.browserField` is false, the package.json browser field will be
|
||||
ignored. When `opts.browserField` is set to a `string`, then a custom field name
|
||||
can be used instead of the default `"browser"` field.
|
||||
|
||||
When `opts.insertGlobals` is true, always insert `process`, `global`,
|
||||
`__filename`, and `__dirname` without analyzing the AST for faster builds but
|
||||
larger output bundles. Default false.
|
||||
|
||||
When `opts.detectGlobals` is true, scan all files for `process`, `global`,
|
||||
`__filename`, and `__dirname`, defining as necessary. With this option npm
|
||||
modules are more likely to work but bundling takes longer. Default true.
|
||||
|
||||
When `opts.ignoreMissing` is true, ignore `require()` statements that don't
|
||||
resolve to anything.
|
||||
|
||||
When `opts.debug` is true, add a source map inline to the end of the bundle.
|
||||
This makes debugging easier because you can see all the original files if
|
||||
you are in a modern enough browser.
|
||||
|
||||
When `opts.standalone` is a non-empty string, a standalone module is created
|
||||
with that name and a [umd](https://github.com/forbeslindesay/umd) wrapper.
|
||||
You can use namespaces in the standalone global export using a `.` in the string
|
||||
name as a separator, for example `'A.B.C'`. The global export will be [sanitized
|
||||
and camel cased](https://github.com/ForbesLindesay/umd#name-casing-and-characters).
|
||||
|
||||
Note that in standalone mode the `require()` calls from the original source will
|
||||
still be around, which may trip up AMD loaders scanning for `require()` calls.
|
||||
You can remove these calls with
|
||||
[derequire](https://www.npmjs.com/package/derequire):
|
||||
|
||||
```
|
||||
$ npm install -g derequire
|
||||
$ browserify main.js --standalone Foo | derequire > bundle.js
|
||||
```
|
||||
|
||||
`opts.insertGlobalVars` will be passed to
|
||||
[insert-module-globals](https://www.npmjs.com/package/insert-module-globals)
|
||||
as the `opts.vars` parameter.
|
||||
|
||||
`opts.externalRequireName` defaults to `'require'` in `expose` mode but you can
|
||||
use another name.
|
||||
|
||||
`opts.bare` creates a bundle that does not include Node builtins, and does not
|
||||
replace global Node variables except for `__dirname` and `__filename`.
|
||||
|
||||
`opts.node` creates a bundle that runs in Node and does not use the browser
|
||||
versions of dependencies. Same as passing `{ bare: true, browserField: false }`.
|
||||
|
||||
Note that if files do not contain javascript source code then you also need to
|
||||
specify a corresponding transform for them.
|
||||
|
||||
All other options are forwarded along to
|
||||
[module-deps](https://www.npmjs.com/package/module-deps)
|
||||
and [browser-pack](https://www.npmjs.com/package/browser-pack) directly.
|
||||
|
||||
## b.add(file, opts)
|
||||
|
||||
Add an entry file from `file` that will be executed when the bundle loads.
|
||||
|
||||
If `file` is an array, each item in `file` will be added as an entry file.
|
||||
|
||||
## b.require(file, opts)
|
||||
|
||||
Make `file` available from outside the bundle with `require(file)`.
|
||||
|
||||
The `file` param is anything that can be resolved by `require.resolve()`,
|
||||
including files from `node_modules`. Like with `require.resolve()`, you must
|
||||
prefix `file` with `./` to require a local file (not in `node_modules`).
|
||||
|
||||
`file` can also be a stream, but you should also use `opts.basedir` so that
|
||||
relative requires will be resolvable.
|
||||
|
||||
If `file` is an array, each item in `file` will be required.
|
||||
In `file` array form, you can use a string or object for each item. Object items
|
||||
should have a `file` property and the rest of the parameters will be used for
|
||||
the `opts`.
|
||||
|
||||
Use the `expose` property of opts to specify a custom dependency name.
|
||||
`require('./vendor/angular/angular.js', {expose: 'angular'})` enables `require('angular')`
|
||||
|
||||
## b.bundle(cb)
|
||||
|
||||
Bundle the files and their dependencies into a single javascript file.
|
||||
|
||||
Return a readable stream with the javascript file contents or
|
||||
optionally specify a `cb(err, buf)` to get the buffered results.
|
||||
|
||||
## b.external(file)
|
||||
|
||||
Prevent `file` from being loaded into the current bundle, instead referencing
|
||||
from another bundle.
|
||||
|
||||
If `file` is an array, each item in `file` will be externalized.
|
||||
|
||||
If `file` is another bundle, that bundle's contents will be read and excluded
|
||||
from the current bundle as the bundle in `file` gets bundled.
|
||||
|
||||
## b.ignore(file)
|
||||
|
||||
Prevent the module name or file at `file` from showing up in the output bundle.
|
||||
|
||||
If `file` is an array, each item in `file` will be ignored.
|
||||
|
||||
Instead you will get a file with `module.exports = {}`.
|
||||
|
||||
## b.exclude(file)
|
||||
|
||||
Prevent the module name or file at `file` from showing up in the output bundle.
|
||||
|
||||
If `file` is an array, each item in `file` will be excluded.
|
||||
|
||||
If your code tries to `require()` that file it will throw unless you've provided
|
||||
another mechanism for loading it.
|
||||
|
||||
## b.transform(tr, opts={})
|
||||
|
||||
Transform source code before parsing it for `require()` calls with the transform
|
||||
function or module name `tr`.
|
||||
|
||||
If `tr` is a function, it will be called with `tr(file)` and it should return a
|
||||
[through-stream](https://github.com/substack/stream-handbook#through)
|
||||
that takes the raw file contents and produces the transformed source.
|
||||
|
||||
If `tr` is a string, it should be a module name or file path of a
|
||||
[transform module](https://github.com/browserify/module-deps#transforms)
|
||||
with a signature of:
|
||||
|
||||
``` js
|
||||
var through = require('through');
|
||||
module.exports = function (file) { return through() };
|
||||
```
|
||||
|
||||
You don't need to necessarily use the
|
||||
[through](https://www.npmjs.com/package/through) module.
|
||||
Browserify is compatible with the newer, more verbose
|
||||
[Transform streams](http://nodejs.org/api/stream.html#stream_class_stream_transform_1)
|
||||
built into Node v0.10.
|
||||
|
||||
Here's how you might compile coffee script on the fly using `.transform()`:
|
||||
|
||||
``` js
|
||||
var coffee = require('coffee-script');
|
||||
var through = require('through');
|
||||
|
||||
b.transform(function (file) {
|
||||
var data = '';
|
||||
return through(write, end);
|
||||
|
||||
function write (buf) { data += buf }
|
||||
function end () {
|
||||
this.queue(coffee.compile(data));
|
||||
this.queue(null);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Note that on the command-line with the `-c` flag you can just do:
|
||||
|
||||
```
|
||||
$ browserify -c 'coffee -sc' main.coffee > bundle.js
|
||||
```
|
||||
|
||||
Or better still, use the [coffeeify](https://github.com/jnordberg/coffeeify)
|
||||
module:
|
||||
|
||||
```
|
||||
$ npm install coffeeify
|
||||
$ browserify -t coffeeify main.coffee > bundle.js
|
||||
```
|
||||
|
||||
If `opts.global` is `true`, the transform will operate on ALL files, despite
|
||||
whether they exist up a level in a `node_modules/` directory. Use global
|
||||
transforms cautiously and sparingly, since most of the time an ordinary
|
||||
transform will suffice. You can also not configure global transforms in a
|
||||
`package.json` like you can with ordinary transforms.
|
||||
|
||||
Global transforms always run after any ordinary transforms have run.
|
||||
|
||||
Transforms may obtain options from the command-line with
|
||||
[subarg](https://www.npmjs.com/package/subarg) syntax:
|
||||
|
||||
```
|
||||
$ browserify -t [ foo --bar=555 ] main.js
|
||||
```
|
||||
|
||||
or from the api:
|
||||
|
||||
```
|
||||
b.transform('foo', { bar: 555 })
|
||||
```
|
||||
|
||||
In both cases, these options are provided as the second argument to the
|
||||
transform function:
|
||||
|
||||
```
|
||||
module.exports = function (file, opts) { /* opts.bar === 555 */ }
|
||||
```
|
||||
|
||||
Options sent to the browserify constructor are also provided under
|
||||
`opts._flags`. These browserify options are sometimes required if your transform
|
||||
needs to do something different when browserify is run in debug mode, for
|
||||
example.
|
||||
|
||||
## b.plugin(plugin, opts)
|
||||
|
||||
Register a `plugin` with `opts`. Plugins can be a string module name or a
|
||||
function the same as transforms.
|
||||
|
||||
`plugin(b, opts)` is called with the browserify instance `b`.
|
||||
|
||||
For more information, consult the plugins section below.
|
||||
|
||||
## b.pipeline
|
||||
|
||||
There is an internal
|
||||
[labeled-stream-splicer](https://www.npmjs.com/package/labeled-stream-splicer)
|
||||
pipeline with these labels:
|
||||
|
||||
* `'record'` - save inputs to play back later on subsequent `bundle()` calls
|
||||
* `'deps'` - [module-deps](https://www.npmjs.com/package/module-deps)
|
||||
* `'json'` - adds `module.exports=` to the beginning of json files
|
||||
* `'unbom'` - remove byte-order markers
|
||||
* `'unshebang'` - remove #! labels on the first line
|
||||
* `'syntax'` - check for syntax errors
|
||||
* `'sort'` - sort the dependencies for deterministic bundles
|
||||
* `'dedupe'` - remove duplicate source contents
|
||||
* `'label'` - apply integer labels to files
|
||||
* `'emit-deps'` - emit `'dep'` event
|
||||
* `'debug'` - apply source maps
|
||||
* `'pack'` - [browser-pack](https://www.npmjs.com/package/browser-pack)
|
||||
* `'wrap'` - apply final wrapping, `require=` and a newline and semicolon
|
||||
|
||||
You can call `b.pipeline.get()` with a label name to get a handle on a stream pipeline
|
||||
that you can `push()`, `unshift()`, or `splice()` to insert your own transform
|
||||
streams.
|
||||
|
||||
## b.reset(opts)
|
||||
|
||||
Reset the pipeline back to a normal state. This function is called automatically
|
||||
when `bundle()` is called multiple times.
|
||||
|
||||
This function triggers a 'reset' event.
|
||||
|
||||
# package.json
|
||||
|
||||
browserify uses the `package.json` in its module resolution algorithm, just like
|
||||
node. If there is a `"main"` field, browserify will start resolving the package
|
||||
at that point. If there is no `"main"` field, browserify will look for an
|
||||
`"index.js"` file in the module root directory. Here are some more
|
||||
sophisticated things you can do in the package.json:
|
||||
|
||||
## browser field
|
||||
|
||||
There is a special "[browser](https://github.com/defunctzombie/package-browser-field-spec)" field you can
|
||||
set in your package.json on a per-module basis to override file resolution for
|
||||
browser-specific versions of files.
|
||||
|
||||
For example, if you want to have a browser-specific module entry point for your
|
||||
`"main"` field you can just set the `"browser"` field to a string:
|
||||
|
||||
``` json
|
||||
"browser": "./browser.js"
|
||||
```
|
||||
|
||||
or you can have overrides on a per-file basis:
|
||||
|
||||
``` json
|
||||
"browser": {
|
||||
"fs": "level-fs",
|
||||
"./lib/ops.js": "./browser/opts.js"
|
||||
}
|
||||
```
|
||||
|
||||
Note that the browser field only applies to files in the local module, and like
|
||||
transforms, it doesn't apply into `node_modules` directories.
|
||||
|
||||
## browserify.transform
|
||||
|
||||
You can specify source transforms in the package.json in the
|
||||
`browserify.transform` field. There is more information about how source
|
||||
transforms work in package.json on the
|
||||
[module-deps readme](https://github.com/browserify/module-deps#transforms).
|
||||
|
||||
For example, if your module requires [brfs](https://www.npmjs.com/package/brfs), you
|
||||
can add
|
||||
|
||||
``` json
|
||||
"browserify": { "transform": [ "brfs" ] }
|
||||
```
|
||||
|
||||
to your package.json. Now when somebody `require()`s your module, brfs will
|
||||
automatically be applied to the files in your module without explicit
|
||||
intervention by the person using your module. Make sure to add transforms to
|
||||
your package.json dependencies field.
|
||||
|
||||
# events
|
||||
|
||||
## b.on('file', function (file, id, parent) {})
|
||||
## b.pipeline.on('file', function (file, id, parent) {})
|
||||
|
||||
When a file is resolved for the bundle, the bundle emits a `'file'` event with
|
||||
the full `file` path, the `id` string passed to `require()`, and the `parent`
|
||||
object used by
|
||||
[browser-resolve](https://github.com/defunctzombie/node-browser-resolve).
|
||||
|
||||
You could use the `file` event to implement a file watcher to regenerate bundles
|
||||
when files change.
|
||||
|
||||
## b.on('package', function (pkg) {})
|
||||
## b.pipeline.on('package', function (pkg) {})
|
||||
|
||||
When a package file is read, this event fires with the contents. The package
|
||||
directory is available at `pkg.__dirname`.
|
||||
|
||||
## b.on('bundle', function (bundle) {})
|
||||
|
||||
When `.bundle()` is called, this event fires with the `bundle` output stream.
|
||||
|
||||
## b.on('reset', function () {})
|
||||
|
||||
When the `.reset()` method is called or implicitly called by another call to
|
||||
`.bundle()`, this event fires.
|
||||
|
||||
## b.on('transform', function (tr, file) {})
|
||||
## b.pipeline.on('transform', function (tr, file) {})
|
||||
|
||||
When a transform is applied to a file, the `'transform'` event fires on the
|
||||
bundle stream with the transform stream `tr` and the `file` that the transform
|
||||
is being applied to.
|
||||
|
||||
# plugins
|
||||
|
||||
For some more advanced use-cases, a transform is not sufficiently extensible.
|
||||
Plugins are modules that take the bundle instance as their first parameter and
|
||||
an option hash as their second.
|
||||
|
||||
Plugins can be used to do perform some fancy features that transforms can't do.
|
||||
For example, [factor-bundle](https://www.npmjs.com/package/factor-bundle) is a
|
||||
plugin that can factor out common dependencies from multiple entry-points into a
|
||||
common bundle. Use plugins with `-p` and pass options to plugins with
|
||||
[subarg](https://www.npmjs.com/package/subarg) syntax:
|
||||
|
||||
```
|
||||
browserify x.js y.js -p [ factor-bundle -o bundle/x.js -o bundle/y.js ] \
|
||||
> bundle/common.js
|
||||
```
|
||||
|
||||
For a list of plugins, consult the
|
||||
[browserify-plugin tag](https://www.npmjs.com/browse/keyword/browserify-plugin)
|
||||
on npm.
|
||||
|
||||
# list of source transforms
|
||||
|
||||
There is a [wiki page that lists the known browserify
|
||||
transforms](https://github.com/browserify/browserify/wiki/list-of-transforms).
|
||||
|
||||
If you write a transform, make sure to add your transform to that wiki page and
|
||||
add a package.json keyword of `browserify-transform` so that
|
||||
[people can browse for all the browserify
|
||||
transforms](https://www.npmjs.com/browse/keyword/browserify-transform) on npmjs.org.
|
||||
|
||||
# third-party tools
|
||||
|
||||
There is a [wiki page that lists the known browserify
|
||||
tools](https://github.com/browserify/browserify/wiki/browserify-tools).
|
||||
|
||||
If you write a tool, make sure to add it to that wiki page and
|
||||
add a package.json keyword of `browserify-tool` so that
|
||||
[people can browse for all the browserify
|
||||
tools](https://www.npmjs.com/browse/keyword/browserify-tool) on npmjs.org.
|
||||
|
||||
# changelog
|
||||
|
||||
Releases are documented in
|
||||
[changelog.markdown](changelog.markdown) and on the
|
||||
[browserify twitter feed](https://twitter.com/browserify).
|
||||
|
||||
# license
|
||||
|
||||
[MIT](./LICENSE)
|
||||
|
||||

|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
Only the latest major version is supported at any given time.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a security vulnerability, please use the
|
||||
[Tidelift security contact](https://tidelift.com/security).
|
||||
Tidelift will coordinate the fix and disclosure.
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
var test = require('tap').test;
|
||||
var fromArgs = require('../bin/args.js');
|
||||
var path = require('path');
|
||||
var vm = require('vm');
|
||||
|
||||
test('bundle from an arguments array', function (t) {
|
||||
t.plan(2);
|
||||
|
||||
var b = fromArgs([ __dirname + '/entry/two.js', '-s', 'XYZ' ]);
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
var c = { window: {} };
|
||||
vm.runInNewContext(src, c);
|
||||
t.equal(c.window.XYZ, 2);
|
||||
});
|
||||
});
|
||||
|
||||
test('external flag for node modules', function(t) {
|
||||
t.plan(2);
|
||||
|
||||
var b = fromArgs([ __dirname + '/external_args/main.js', '-x', 'backbone' ]);
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, {t: t});
|
||||
});
|
||||
});
|
||||
|
||||
test('bundle from an arguments with --insert-global-vars', function (t) {
|
||||
t.plan(4);
|
||||
|
||||
var b = fromArgs([
|
||||
__dirname + '/global/filename.js',
|
||||
'--insert-global-vars=__filename,__dirname',
|
||||
'--basedir', __dirname
|
||||
]);
|
||||
b.require(__dirname + '/global/filename.js', { expose: 'x' });
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err, 'b.bundle()');
|
||||
var c = {}, x;
|
||||
vm.runInNewContext(src, c);
|
||||
t.doesNotThrow(function() {
|
||||
x = c.require('x');
|
||||
}, 'x = c.require(\'x\')');
|
||||
t.equal(x && x.filename, '/global/filename.js', 'x.filename');
|
||||
t.equal(x && x.dirname, '/global', 'x.dirname');
|
||||
})
|
||||
});
|
||||
|
||||
test('numeric module names', function(t) {
|
||||
t.plan(1);
|
||||
|
||||
var b = fromArgs([ '-x', '1337' ]);
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
});
|
||||
});
|
||||
|
||||
test('entry expose', function (t) {
|
||||
t.plan(3)
|
||||
|
||||
var b = fromArgs([
|
||||
path.join(__dirname, '/entry_expose/main.js'),
|
||||
'--require', path.join(__dirname, '/entry_expose/main.js') + ':x',
|
||||
]);
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
var c = { console: { log: log } };
|
||||
function log (msg) { t.equal(msg, 'wow') }
|
||||
vm.runInNewContext(src, c);
|
||||
t.equal(c.require('x'), 555);
|
||||
})
|
||||
});
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
var browserify = require('../');
|
||||
var vm = require('vm');
|
||||
var test = require('tap').test;
|
||||
|
||||
test('array add', function (t) {
|
||||
var expected = [ 'ONE', 'TWO', 'THREE' ];
|
||||
t.plan(expected.length);
|
||||
|
||||
var b = browserify();
|
||||
var files = [
|
||||
__dirname + '/array/one.js',
|
||||
__dirname + '/array/two.js',
|
||||
__dirname + '/array/three.js'
|
||||
];
|
||||
b.add(files);
|
||||
b.bundle(function (err, src) {
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (msg) {
|
||||
t.equal(msg, expected.shift());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('array require', function (t) {
|
||||
t.plan(3);
|
||||
|
||||
var b = browserify();
|
||||
var files = [ 'defined', 'subarg' ];
|
||||
b.require(files);
|
||||
b.bundle(function (err, src) {
|
||||
var c = {};
|
||||
vm.runInNewContext(src, c);
|
||||
|
||||
t.equal(c.require('defined')(undefined, true), true);
|
||||
t.equal(c.require('defined')(undefined, false), false);
|
||||
t.deepEqual(c.require('subarg')(['-x', '3']), { x: 3, _: [] });
|
||||
});
|
||||
});
|
||||
|
||||
test('array require opts', function (t) {
|
||||
t.plan(3);
|
||||
|
||||
var b = browserify();
|
||||
var files = [
|
||||
{ file: require.resolve('defined'), expose: 'abc' },
|
||||
{ file: require.resolve('subarg'), expose: 'def' }
|
||||
];
|
||||
b.require(files);
|
||||
b.bundle(function (err, src) {
|
||||
var c = {};
|
||||
vm.runInNewContext(src, c);
|
||||
|
||||
t.equal(c.require('abc')(undefined, true), true);
|
||||
t.equal(c.require('abc')(undefined, false), false);
|
||||
t.deepEqual(c.require('def')(['-x', '3']), { x: 3, _: [] });
|
||||
});
|
||||
});
|
||||
|
||||
test('array external', function (t) {
|
||||
t.plan(2);
|
||||
|
||||
var b = browserify(__dirname + '/external/main.js');
|
||||
b.external(['util','freelist']);
|
||||
b.bundle(function (err, src) {
|
||||
if (err) return t.fail(err);
|
||||
vm.runInNewContext(
|
||||
'function require (x) {'
|
||||
+ 'if (x==="freelist") return function (n) { return n + 1000 }'
|
||||
+ '}'
|
||||
+ src,
|
||||
{ t: t }
|
||||
);
|
||||
});
|
||||
});
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log('ONE');
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log('THREE');
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log('TWO');
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
var browserify = require('../');
|
||||
var fs = require('fs');
|
||||
var vm = require('vm');
|
||||
var test = require('tap').test;
|
||||
|
||||
var src = fs.readFileSync(__dirname + '/async/src.js','utf8');
|
||||
var canAsync = true;
|
||||
try { Function(src) } catch (err) { canAsync = false }
|
||||
|
||||
if (!canAsync) console.error('# async/await unsupported in this environment')
|
||||
else test('async/await', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/async/src.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.error(err)
|
||||
var c = {
|
||||
console: { log: log },
|
||||
setTimeout: setTimeout,
|
||||
clearTimeout: clearTimeout
|
||||
}
|
||||
vm.runInNewContext(src, c);
|
||||
function log (msg) { t.equal(msg, 60) }
|
||||
});
|
||||
});
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
function f (x) { return new Promise(resolve => {
|
||||
process.nextTick(() => { resolve(x) }) }) }
|
||||
|
||||
async function add (x) {
|
||||
return x + await f(20) + await f(30)
|
||||
}
|
||||
|
||||
add(10).then(v => { console.log(v) })
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
var browserify = require('../');
|
||||
var vm = require('vm');
|
||||
var backbone = require('backbone');
|
||||
var test = require('tap').test;
|
||||
|
||||
test('backbone', function (t) {
|
||||
t.plan(3);
|
||||
var b = browserify();
|
||||
b.require('backbone');
|
||||
b.bundle(function (err, buf) {
|
||||
t.ok(Buffer.isBuffer(buf));
|
||||
var src = buf.toString('utf8');
|
||||
t.ok(src.length > 0);
|
||||
|
||||
var c = { console: console };
|
||||
vm.runInNewContext(src, c);
|
||||
t.deepEqual(
|
||||
Object.keys(backbone).sort(),
|
||||
Object.keys(c.require('backbone')).sort()
|
||||
);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
var test = require('tap').test;
|
||||
var spawn = require('child_process').spawn;
|
||||
var browserify = require('../');
|
||||
var path = require('path');
|
||||
var concat = require('concat-stream');
|
||||
var vm = require('vm');
|
||||
var fs = require('fs');
|
||||
var through = require('through2');
|
||||
var temp = require('temp');
|
||||
temp.track();
|
||||
var tmpdir = temp.mkdirSync({prefix: 'browserify-test'});
|
||||
|
||||
test('bare', function (t) {
|
||||
t.plan(4);
|
||||
|
||||
var cwd = process.cwd();
|
||||
process.chdir(__dirname);
|
||||
|
||||
var ps = spawn(process.execPath, [
|
||||
path.resolve(__dirname, '../bin/cmd.js'),
|
||||
'-', '--bare'
|
||||
]);
|
||||
ps.stdout.pipe(concat(function (body) {
|
||||
vm.runInNewContext(body, {
|
||||
Buffer: function (s) { return s.toLowerCase() },
|
||||
console: {
|
||||
log: function (msg) { t.equal(msg, 'abc') }
|
||||
}
|
||||
});
|
||||
vm.runInNewContext(body, {
|
||||
Buffer: Buffer,
|
||||
console: {
|
||||
log: function (msg) {
|
||||
t.ok(Buffer.isBuffer(msg));
|
||||
t.equal(msg.toString('utf8'), 'ABC')
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
ps.stdin.end('console.log(Buffer("ABC"))');
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
t.equal(code, 0);
|
||||
});
|
||||
});
|
||||
|
||||
test('bare api', function (t) {
|
||||
t.plan(3);
|
||||
|
||||
var input = through();
|
||||
var b = browserify(input, { bare: true });
|
||||
b.bundle().pipe(concat(function (body) {
|
||||
vm.runInNewContext(body, {
|
||||
Buffer: function (s) { return s.toLowerCase() },
|
||||
console: {
|
||||
log: function (msg) { t.equal(msg, 'abc') }
|
||||
}
|
||||
});
|
||||
vm.runInNewContext(body, {
|
||||
Buffer: Buffer,
|
||||
console: {
|
||||
log: function (msg) {
|
||||
t.ok(Buffer.isBuffer(msg));
|
||||
t.equal(msg.toString('utf8'), 'ABC')
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
input.end('console.log(Buffer("ABC"))');
|
||||
});
|
||||
|
||||
test('bare inserts __filename,__dirname but not process,global,Buffer', function (t) {
|
||||
t.plan(2);
|
||||
|
||||
var file = path.resolve(__dirname, 'bare/main.js');
|
||||
var ps = spawn(process.execPath, [
|
||||
path.resolve(__dirname, '../bin/cmd.js'),
|
||||
file,
|
||||
'--bare'
|
||||
]);
|
||||
|
||||
ps.stdout.pipe(concat(function (body) {
|
||||
vm.runInNewContext(body, {
|
||||
require: require,
|
||||
__dirname: process.cwd(),
|
||||
console: {
|
||||
log: function (msg) {
|
||||
t.same(msg, [
|
||||
path.join(__dirname, 'bare'),
|
||||
path.join(__dirname, 'bare/main.js'),
|
||||
'undefined',
|
||||
'undefined',
|
||||
'undefined'
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
ps.stdin.end();
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
t.equal(code, 0);
|
||||
});
|
||||
});
|
||||
|
||||
test('bare inserts dynamic __filename,__dirname', function (t) {
|
||||
t.plan(2);
|
||||
|
||||
var file = path.join(tmpdir, 'dirname-filename.js');
|
||||
|
||||
fs.writeFileSync(
|
||||
file,
|
||||
fs.readFileSync(path.resolve(__dirname, 'bare/dirname-filename.js'))
|
||||
);
|
||||
|
||||
var ps = spawn(process.execPath, [
|
||||
path.resolve(__dirname, '../bin/cmd.js'),
|
||||
file,
|
||||
'--bare'
|
||||
]);
|
||||
|
||||
ps.stdout.pipe(concat(function (body) {
|
||||
vm.runInNewContext(body, {
|
||||
require: require,
|
||||
__dirname: process.cwd(),
|
||||
console: {
|
||||
log: function (msg) {
|
||||
t.same(msg, [
|
||||
path.dirname(file),
|
||||
file
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
ps.stdin.end();
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
t.equal(code, 0);
|
||||
});
|
||||
});
|
||||
|
||||
test('bare inserts dynamic __filename,__dirname with basedir', function (t) {
|
||||
t.plan(2);
|
||||
|
||||
var file = 'dirname-filename.js';
|
||||
var ps = spawn(process.execPath, [
|
||||
path.resolve(__dirname, '../bin/cmd.js'),
|
||||
file,
|
||||
'--bare',
|
||||
'--basedir=' + path.join(__dirname, 'bare')
|
||||
]);
|
||||
|
||||
ps.stdout.pipe(concat(function (body) {
|
||||
vm.runInNewContext(body, {
|
||||
require: require,
|
||||
__dirname: process.cwd(),
|
||||
console: {
|
||||
log: function (msg) {
|
||||
t.same(msg, [
|
||||
__dirname,
|
||||
path.join(__dirname, file)
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
ps.stdin.end();
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
t.equal(code, 0);
|
||||
});
|
||||
});
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
console.log([
|
||||
__dirname,
|
||||
__filename
|
||||
]);
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
console.log([
|
||||
__dirname,
|
||||
__filename,
|
||||
typeof process,
|
||||
typeof global,
|
||||
typeof Buffer
|
||||
]);
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
var test = require('tap').test;
|
||||
var spawn = require('child_process').spawn;
|
||||
var path = require('path');
|
||||
var concat = require('concat-stream');
|
||||
var vm = require('vm');
|
||||
|
||||
test('bare shebang', function (t) {
|
||||
t.plan(4);
|
||||
|
||||
var ps = spawn(process.execPath, [
|
||||
path.resolve(__dirname, '../bin/cmd.js'),
|
||||
'-', '--bare'
|
||||
]);
|
||||
ps.stderr.pipe(process.stderr);
|
||||
ps.stdout.pipe(concat(function (body) {
|
||||
vm.runInNewContext(body, {
|
||||
Buffer: function (s) { return s.toLowerCase() },
|
||||
console: {
|
||||
log: function (msg) { t.equal(msg, 'woo') }
|
||||
}
|
||||
});
|
||||
vm.runInNewContext(body, {
|
||||
Buffer: Buffer,
|
||||
console: {
|
||||
log: function (msg) {
|
||||
t.ok(Buffer.isBuffer(msg));
|
||||
t.equal(msg.toString('utf8'), 'WOO')
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
ps.stdin.end('#!/usr/bin/env node\nconsole.log(Buffer("WOO"))');
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
t.equal(code, 0);
|
||||
});
|
||||
});
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
var test = require('tap').test;
|
||||
var spawn = require('child_process').spawn;
|
||||
var path = require('path');
|
||||
var vm = require('vm');
|
||||
|
||||
test('bin', function (t) {
|
||||
t.plan(3);
|
||||
|
||||
var cwd = process.cwd();
|
||||
process.chdir(__dirname);
|
||||
|
||||
var ps = spawn(process.execPath, [
|
||||
path.resolve(__dirname, '../bin/cmd.js'),
|
||||
'entry/main.js'
|
||||
]);
|
||||
var src = '';
|
||||
var err = '';
|
||||
ps.stdout.on('data', function (buf) { src += buf });
|
||||
ps.stderr.on('data', function (buf) { err += buf });
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
t.equal(code, 0);
|
||||
t.equal(err, '');
|
||||
|
||||
var allDone = false;
|
||||
var c = { done : function () { allDone = true } };
|
||||
|
||||
vm.runInNewContext(src, c);
|
||||
t.ok(allDone);
|
||||
});
|
||||
});
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
var test = require('tap').test;
|
||||
var spawn = require('child_process').spawn;
|
||||
var path = require('path');
|
||||
var vm = require('vm');
|
||||
|
||||
test('bin --entry', function (t) {
|
||||
t.plan(3);
|
||||
|
||||
var cwd = process.cwd();
|
||||
process.chdir(__dirname);
|
||||
|
||||
var ps = spawn(process.execPath, [
|
||||
path.resolve(__dirname, '../bin/cmd.js'),
|
||||
'--entry', 'entry/main.js'
|
||||
]);
|
||||
var src = '';
|
||||
var err = '';
|
||||
ps.stdout.on('data', function (buf) { src += buf });
|
||||
ps.stderr.on('data', function (buf) { err += buf });
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
t.equal(code, 0);
|
||||
t.equal(err, '');
|
||||
|
||||
var allDone = false;
|
||||
var c = { done : function () { allDone = true } };
|
||||
|
||||
vm.runInNewContext(src, c);
|
||||
t.ok(allDone);
|
||||
});
|
||||
});
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
var browserify = require('../');
|
||||
var spawn = require('child_process').spawn;
|
||||
var test = require('tap').test;
|
||||
var path = require('path')
|
||||
var semver = require('semver');
|
||||
|
||||
// TODO this should be fixable I guess
|
||||
var flaky = process.platform === 'win32' && semver.satisfies(process.version, 'v0.10.x');
|
||||
|
||||
test('function transform', { skip: flaky }, function (t) {
|
||||
t.plan(3);
|
||||
var ps = spawn(process.execPath, [
|
||||
path.resolve(__dirname, '../bin/cmd.js'),
|
||||
'-t', './tr.js', './main.js'
|
||||
], {cwd: path.resolve(__dirname, 'bin_tr_error')});
|
||||
var src = '';
|
||||
var err = '';
|
||||
ps.stdout.on('data', function (buf) { src += buf });
|
||||
ps.stderr.on('data', function (buf) { err += buf });
|
||||
|
||||
ps.on('exit', function (code) {
|
||||
t.notEqual(code, 0);
|
||||
var errorFile = path.resolve(__dirname, 'bin_tr_error', 'tr.js');
|
||||
t.notEqual(err.indexOf('there was error'), -1, 'Error should contain error message')
|
||||
t.notEqual(err.indexOf(errorFile), -1, 'Error should contain stack trace')
|
||||
});
|
||||
});
|
||||
+1
@@ -0,0 +1 @@
|
||||
t.equal(XXX * 5, 555);
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
var through = require('through2');
|
||||
|
||||
module.exports = function (file, opts) {
|
||||
var data = '';
|
||||
return through(write, end);
|
||||
|
||||
function write (buf, enc, next) { data += buf; next() }
|
||||
function end () {
|
||||
this.emit('error', new Error('there was error'))
|
||||
this.push(null);
|
||||
}
|
||||
};
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
var browserify = require('../');
|
||||
var vm = require('vm');
|
||||
var test = require('tap').test;
|
||||
|
||||
test('byte order marker', function (t) {
|
||||
t.plan(2);
|
||||
|
||||
var b = browserify(__dirname + '/bom/hello.js');
|
||||
b.bundle(function (err, src) {
|
||||
if (err) t.fail(err);
|
||||
var c = {
|
||||
console: { log: function (msg) {
|
||||
t.equal(msg, 'hello');
|
||||
} }
|
||||
};
|
||||
vm.runInNewContext(src, c);
|
||||
t.notOk(/\ufeff/.test(src.toString('utf8')));
|
||||
});
|
||||
});
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log('hello')
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
var test = require('tap').test;
|
||||
var vm = require('vm');
|
||||
var browserify = require('../');
|
||||
|
||||
test('browser field file no ext', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_file/xyz');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (msg) { t.equal(msg, 'cool beans') }
|
||||
});
|
||||
});
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"./xyz": "wow.js"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log('cool beans');
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
var browserify = require('../');
|
||||
var vm = require('vm');
|
||||
var test = require('tap').test;
|
||||
|
||||
test('browser field resolve (a)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/a/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.equal(x, 555) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (b)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/b/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.equal(x, 444) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (c)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/c/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.equal(x, 333) }
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('browser field resolve (d)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/d/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.equal(x, 222) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (e)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/e/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.equal(x, 111) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (f)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/f/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.equal(x, 999) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (g)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/g/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.deepEqual(x, {}) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (h)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/h/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.deepEqual(x, {}) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (i)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/i/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.deepEqual(x, 5000) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (j)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/j/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.deepEqual(x, 5000) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (k)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/k/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.deepEqual(x, 3000) }
|
||||
});
|
||||
});
|
||||
|
||||
test('browser field resolve (l)', function (t) {
|
||||
t.plan(2);
|
||||
var b = browserify(__dirname + '/browser_field_resolve/l/main.js');
|
||||
b.bundle(function (err, src) {
|
||||
t.ifError(err);
|
||||
vm.runInNewContext(src, { console: { log: log } });
|
||||
function log (x) { t.deepEqual(x, 3000) }
|
||||
});
|
||||
});
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log(require('zzz'))
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"zzz": "aaa"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log(require('zzz'))
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"zzz": "./x"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 444
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log(require('./z.js'))
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"./z": "./x"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 333
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log(require('./z.js'))
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"./z.js": "./x.js"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 222
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log(require('./z.js'))
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"./z": "./x.js"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 111
|
||||
+1
@@ -0,0 +1 @@
|
||||
console.log(require('aaa/what.js'))
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"aaa/what": "./x.js"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 999
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
try { var x = require('./x') } catch (err) {}
|
||||
console.log(x)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"./x.js": false
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 1000
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
try { var x = require('./x.js') } catch (err) {}
|
||||
console.log(x)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"./x": false
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 1000
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 5000
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
var x = require('./x.js')
|
||||
console.log(x)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"browser": {
|
||||
"./x": "./browser"
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
module.exports = 1000
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user