react / react-0.13.3 / examples / basic-commonjs / node_modules / browserify / node_modules / browser-resolve / index.js
80713 views// builtin1var fs = require('fs');2var path = require('path');34// vendor5var resv = require('resolve');67// given a path, create an array of node_module paths for it8// borrowed from substack/resolve9function nodeModulesPaths (start, cb) {10var splitRe = process.platform === 'win32' ? /[\/\\]/ : /\/+/;11var parts = start.split(splitRe);1213var dirs = [];14for (var i = parts.length - 1; i >= 0; i--) {15if (parts[i] === 'node_modules') continue;16var dir = path.join.apply(17path, parts.slice(0, i + 1).concat(['node_modules'])18);19if (!parts[0].match(/([A-Za-z]:)/)) {20dir = '/' + dir;21}22dirs.push(dir);23}24return dirs;25}2627function find_shims_in_package(pkgJson, cur_path, shims, browser) {28try {29var info = JSON.parse(pkgJson);30}31catch (err) {32err.message = pkgJson + ' : ' + err.message33throw err;34}3536var replacements = getReplacements(info, browser);3738// no replacements, skip shims39if (!replacements) {40return;41}4243// if browser mapping is a string44// then it just replaces the main entry point45if (typeof replacements === 'string') {46var key = path.resolve(cur_path, info.main || 'index.js');47shims[key] = path.resolve(cur_path, replacements);48return;49}5051// http://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders52Object.keys(replacements).forEach(function(key) {53if (replacements[key] === false) {54return shims[key] = __dirname + '/empty.js';55}5657var val = replacements[key];5859// if target is a relative path, then resolve60// otherwise we assume target is a module61if (val[0] === '.') {62val = path.resolve(cur_path, val);63}6465// if does not begin with / ../ or ./ then it is a module66if (key[0] !== '/' && key[0] !== '.') {67return shims[key] = val;68}6970key = path.resolve(cur_path, key);71shims[key] = val;72});73}7475// paths is mutated76// load shims from first package.json file found77function load_shims(paths, browser, cb) {78// identify if our file should be replaced per the browser field79// original filename|id -> replacement80var shims = {};8182(function next() {83var cur_path = paths.shift();84if (!cur_path) {85return cb(null, shims);86}8788var pkg_path = path.join(cur_path, 'package.json');8990fs.readFile(pkg_path, 'utf8', function(err, data) {91if (err) {92// ignore paths we can't open93// avoids an exists check94if (err.code === 'ENOENT') {95return next();96}9798return cb(err);99}100try {101find_shims_in_package(data, cur_path, shims, browser);102return cb(null, shims);103}104catch (err) {105return cb(err);106}107});108})();109};110111// paths is mutated112// synchronously load shims from first package.json file found113function load_shims_sync(paths, browser) {114// identify if our file should be replaced per the browser field115// original filename|id -> replacement116var shims = {};117var cur_path;118119while (cur_path = paths.shift()) {120var pkg_path = path.join(cur_path, 'package.json');121122try {123var data = fs.readFileSync(pkg_path, 'utf8');124find_shims_in_package(data, cur_path, shims, browser);125return shims;126}127catch (err) {128// ignore paths we can't open129// avoids an exists check130if (err.code === 'ENOENT') {131continue;132}133134throw err;135}136}137return shims;138}139140function build_resolve_opts(opts, base) {141var packageFilter = opts.packageFilter;142var browser = normalizeBrowserFieldName(opts.browser)143144opts.basedir = base;145opts.packageFilter = function (info, pkgdir) {146if (packageFilter) info = packageFilter(info, pkgdir);147148var replacements = getReplacements(info, browser);149150// no browser field, keep info unchanged151if (!replacements) {152return info;153}154155info[browser] = replacements;156157// replace main158if (typeof replacements === 'string') {159info.main = replacements;160return info;161}162163var replace_main = replacements[info.main || './index.js'] ||164replacements['./' + info.main || './index.js'];165166info.main = replace_main || info.main;167return info;168};169170var pathFilter = opts.pathFilter;171opts.pathFilter = function(info, path, relativePath) {172if (relativePath[0] != '.') {173relativePath = './' + relativePath;174}175var mappedPath;176if (pathFilter) {177mappedPath = pathFilter.apply(this, arguments);178}179if (mappedPath) {180return mappedPath;181}182183var replacements = info[browser];184if (!replacements) {185return;186}187188mappedPath = replacements[relativePath];189if (!mappedPath && (relativePath.lastIndexOf('.js') === relativePath.length - 3)) {190mappedPath = replacements[relativePath + '.js'];191}192return mappedPath;193};194195return opts;196}197198function resolve(id, opts, cb) {199200// opts.filename201// opts.paths202// opts.modules203// opts.packageFilter204205opts = opts || {};206207var base = path.dirname(opts.filename);208209if (opts.basedir) {210base = opts.basedir;211}212213var paths = nodeModulesPaths(base);214215if (opts.paths) {216paths.push.apply(paths, opts.paths);217}218219paths = paths.map(function(p) {220return path.dirname(p);221});222223// we must always load shims because the browser field could shim out a module224load_shims(paths, opts.browser, function(err, shims) {225if (err) {226return cb(err);227}228229if (shims[id]) {230// if the shim was is an absolute path, it was fully resolved231if (shims[id][0] === '/') {232return cb(null, shims[id], opts.package);233}234235// module -> alt-module shims236id = shims[id];237}238239var modules = opts.modules || {};240var shim_path = modules[id];241if (shim_path) {242return cb(null, shim_path);243}244245// our browser field resolver246// if browser field is an object tho?247var full = resv(id, build_resolve_opts(opts, base), function(err, full, pkg) {248if (err) {249return cb(err);250}251252var resolved = (shims) ? shims[full] || full : full;253cb(null, resolved, pkg);254});255});256};257258resolve.sync = function (id, opts) {259260// opts.filename261// opts.paths262// opts.modules263// opts.packageFilter264265opts = opts || {};266var base = path.dirname(opts.filename);267268if (opts.basedir) {269base = opts.basedir;270}271272var paths = nodeModulesPaths(base);273274if (opts.paths) {275paths.push.apply(paths, opts.paths);276}277278paths = paths.map(function(p) {279return path.dirname(p);280});281282// we must always load shims because the browser field could shim out a module283var shims = load_shims_sync(paths, opts.browser);284285if (shims[id]) {286// if the shim was is an absolute path, it was fully resolved287if (shims[id][0] === '/') {288return shims[id];289}290291// module -> alt-module shims292id = shims[id];293}294295var modules = opts.modules || {};296var shim_path = modules[id];297if (shim_path) {298return shim_path;299}300301// our browser field resolver302// if browser field is an object tho?303var full = resv.sync(id, build_resolve_opts(opts, base));304305return (shims) ? shims[full] || full : full;306};307308function normalizeBrowserFieldName(browser) {309return browser || 'browser';310}311312function getReplacements(info, browser) {313browser = normalizeBrowserFieldName(browser);314var replacements = info[browser] || info.browser;315316// support legacy browserify field for easier migration from legacy317// many packages used this field historically318if (typeof info.browserify === 'string' && !replacements) {319replacements = info.browserify;320}321322return replacements;323}324325module.exports = resolve;326327328