├── .gitignore ├── .npmrc ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── empty.js ├── example ├── builtin.js ├── custom-chromeapp.js ├── custom.js ├── custom │ ├── custom-chromeapp.js │ ├── custom.js │ ├── main.js │ └── package.json ├── resolve.js ├── skip.js └── skip │ ├── main.js │ └── package.json ├── index.js ├── package.json ├── scripts └── setup-symlinks.js └── test ├── core-sync.js ├── core.js ├── ext.js ├── false-sync.js ├── false.js ├── fixtures-coffee ├── foo.coffee └── node_modules │ ├── module-a │ └── index.coffee │ ├── module-b │ ├── main.coffee │ └── package.json │ ├── module-c │ ├── bar.coffee │ ├── browser.coffee │ ├── main.coffee │ └── package.json │ ├── module-d │ ├── browser.coffee │ ├── main.coffee │ └── package.json │ ├── module-e │ ├── browser.coffee │ ├── foo.coffee │ ├── main.coffee │ └── package.json │ ├── module-f │ ├── lib │ │ ├── browser.coffee │ │ ├── foo.coffee │ │ └── main.coffee │ └── package.json │ └── module-g │ ├── foobar-browser.coffee │ ├── index.coffee │ └── package.json ├── fixtures ├── foo.js ├── linked │ └── index.js └── node_modules │ ├── alt-browser-field │ ├── chromeapp-direct.js │ ├── chromeapp.js │ ├── direct.js │ ├── foo.js │ ├── index.js │ ├── package.json │ ├── url-browser.js │ └── url-chromeapp.js │ ├── false │ ├── fake.js │ ├── node_modules │ │ └── ignore-me │ │ │ └── index.js │ └── package.json │ ├── linker │ └── index.js │ ├── module-a │ └── index.js │ ├── module-b │ ├── main.js │ └── package.json │ ├── module-c │ ├── bar.js │ ├── browser.js │ ├── chromeapp.js │ ├── foo.js │ ├── main.js │ └── package.json │ ├── module-d │ ├── browser.js │ ├── main.js │ └── package.json │ ├── module-e │ ├── browser.js │ ├── foo.js │ ├── main.js │ └── package.json │ ├── module-f │ ├── lib │ │ ├── browser.js │ │ ├── foo.js │ │ └── main.js │ └── package.json │ ├── module-g │ ├── foobar-browser.js │ ├── index.js │ └── package.json │ ├── module-h │ ├── index.js │ └── package.json │ ├── module-i │ ├── index.js │ └── package.json │ ├── module-j │ ├── index.js │ └── package.json │ ├── module-k │ ├── browser.js │ ├── index.js │ └── package.json │ ├── module-l │ ├── browser-direct.js │ ├── browser.js │ ├── index.js │ └── package.json │ ├── module-m │ ├── lib │ │ ├── hide.js │ │ └── index.js │ └── package.json │ ├── module-n │ ├── browser-bar.json │ ├── browser-foo.js │ ├── index.js │ └── package.json │ ├── module-o │ ├── main.js │ ├── package.json │ └── x.js │ ├── module-p │ ├── package.json │ └── x.js │ ├── module-q │ ├── package.json │ └── x.js │ ├── module-r │ ├── package.json │ └── x.js │ ├── module-s │ ├── package.json │ └── x.js │ ├── module-t │ ├── package.json │ ├── x.js │ └── y.js │ ├── override-engine-shim │ ├── index.js │ ├── package.json │ └── url-browser.js │ └── toString ├── local-coffee.js ├── local-sync.js ├── local.js ├── mocha.opts ├── modules-coffee.js ├── modules-sync.js └── modules.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | !test/fixtures/node_modules 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | os: linux 3 | dist: xenial 4 | node_js: 5 | - "14" 6 | - "13" 7 | - "12" 8 | - "11" 9 | - "10" 10 | - "9" 11 | - "8" 12 | - "6" 13 | - "4" 14 | - "iojs" 15 | - "0.12" 16 | - "0.10" 17 | - "0.8" 18 | before_install: 19 | # Old npm certs are untrusted https://github.com/npm/npm/issues/20191 20 | - 'if [ "${TRAVIS_NODE_VERSION}" = "0.8" ]; then export NPM_CONFIG_STRICT_SSL=false; fi' 21 | - 'nvm install-latest-npm' 22 | install: 23 | - 'if [ "${TRAVIS_NODE_VERSION}" = "0.9" ]; then nvm install --latest-npm 0.8 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;' 24 | matrix: 25 | fast_finish: true 26 | allow_failures: 27 | - node_js: "0.6" 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # browser-resolve Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | ## 2.0.0 - 2020-08-03 6 | * Update `resolve` to 1.17.0+. 7 | 8 | Technically, this is a bugfix and feature update. However, older browserify versions rely on a `resolve` bug, and would break if this was published as a minor version update. 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2015 Roman Shtylman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # browser-resolve [![Build Status](https://travis-ci.org/browserify/browser-resolve.png?branch=master)](https://travis-ci.org/browserify/browser-resolve) 2 | 3 | node.js resolve algorithm with [browser field](https://github.com/defunctzombie/package-browser-field-spec) support. 4 | 5 | ## api 6 | 7 | ### bresolve(id, opts={}, cb) 8 | 9 | Resolve a module path and call `cb(err, path [, pkg])` 10 | 11 | Options: 12 | 13 | * `basedir` - directory to begin resolving from 14 | * `browser` - the 'browser' property to use from package.json (defaults to 'browser') 15 | * `filename` - the calling filename where the `require()` call originated (in the source) 16 | * `modules` - object with module id/name -> path mappings to consult before doing manual resolution (use to provide core modules) 17 | * `packageFilter` - transform the parsed `package.json` contents before looking at the `main` field 18 | * `paths` - `require.paths` array to use if nothing is found on the normal `node_modules` recursive walk 19 | 20 | Additionally, options supported by [node-resolve](https://github.com/browserify/resolve#resolveid-opts-cb) can be used. 21 | 22 | ### bresolve.sync(id, opts={}) 23 | 24 | Same as the async resolve, just uses sync methods. 25 | 26 | Additionally, options supported by [node-resolve](https://github.com/browserify/resolve#resolvesyncid-opts-cb) can be used. 27 | 28 | ## basic usage 29 | 30 | you can resolve files like `require.resolve()`: 31 | ``` js 32 | var bresolve = require('browser-resolve'); 33 | bresolve('../', { filename: __filename }, function(err, path) { 34 | console.log(path); 35 | }); 36 | ``` 37 | 38 | ``` 39 | $ node example/resolve.js 40 | /home/substack/projects/browser-resolve/index.js 41 | ``` 42 | 43 | ## core modules 44 | 45 | By default, core modules (http, dgram, etc) will return their same name as the path. If you want to have specific paths returned, specify a `modules` property in the options object. 46 | 47 | ``` js 48 | var shims = { 49 | http: '/your/path/to/http.js' 50 | }; 51 | 52 | var bresolve = require('browser-resolve'); 53 | bresolve('http', { modules: shims }, function(err, path) { 54 | console.log(path); 55 | }); 56 | ``` 57 | 58 | ``` 59 | $ node example/builtin.js 60 | /home/substack/projects/browser-resolve/builtin/http.js 61 | ``` 62 | 63 | ## browser field 64 | browser-specific versions of modules 65 | 66 | ``` json 67 | { 68 | "name": "custom", 69 | "version": "0.0.0", 70 | "browser": { 71 | "./main.js": "custom.js" 72 | } 73 | } 74 | ``` 75 | 76 | ``` js 77 | var bresolve = require('browser-resolve'); 78 | var parent = { filename: __dirname + '/custom/file.js' }; 79 | bresolve('./main.js', parent, function(err, path) { 80 | console.log(path); 81 | }); 82 | ``` 83 | 84 | ``` 85 | $ node example/custom.js 86 | /home/substack/projects/browser-resolve/example/custom/custom.js 87 | ``` 88 | 89 | You can use different package.json properties for the resolution, if you want to allow packages to target different environments for example: 90 | 91 | ``` json 92 | { 93 | "browser": { "./main.js": "custom.js" }, 94 | "chromeapp": { "./main.js": "custom-chromeapp.js" } 95 | } 96 | ``` 97 | 98 | ``` js 99 | var bresolve = require('browser-resolve'); 100 | var parent = { filename: __dirname + '/custom/file.js', browser: 'chromeapp' }; 101 | bresolve('./main.js', parent, function(err, path) { 102 | console.log(path); 103 | }); 104 | ``` 105 | 106 | ``` 107 | $ node example/custom.js 108 | /home/substack/projects/browser-resolve/example/custom/custom-chromeapp.js 109 | ``` 110 | 111 | ## skip 112 | 113 | You can skip over dependencies by setting a 114 | [browser field](https://gist.github.com/defunctzombie/4339901) 115 | value to `false`: 116 | 117 | ``` json 118 | { 119 | "name": "skip", 120 | "version": "0.0.0", 121 | "browser": { 122 | "tar": false 123 | } 124 | } 125 | ``` 126 | 127 | This is handy if you have code like: 128 | 129 | ``` js 130 | var tar = require('tar'); 131 | 132 | exports.add = function (a, b) { 133 | return a + b; 134 | }; 135 | 136 | exports.parse = function () { 137 | return tar.Parse(); 138 | }; 139 | ``` 140 | 141 | so that `require('tar')` will just return `{}` in the browser because you don't 142 | intend to support the `.parse()` export in a browser environment. 143 | 144 | ``` js 145 | var bresolve = require('browser-resolve'); 146 | var parent = { filename: __dirname + '/skip/main.js' }; 147 | bresolve('tar', parent, function(err, path) { 148 | console.log(path); 149 | }); 150 | ``` 151 | 152 | ``` 153 | $ node example/skip.js 154 | /home/substack/projects/browser-resolve/empty.js 155 | ``` 156 | 157 | # license 158 | 159 | MIT 160 | 161 | # upgrade notes 162 | 163 | Prior to v1.x this library provided shims for node core modules. These have since been removed. If you want to have alternative core modules provided, use the `modules` option when calling `bresolve()`. 164 | 165 | This was done to allow package managers to choose which shims they want to use without browser-resolve being the central point of update. 166 | -------------------------------------------------------------------------------- /empty.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserify/browser-resolve/21b46454ae772bce1b894a63f9cdabe0953a6712/empty.js -------------------------------------------------------------------------------- /example/builtin.js: -------------------------------------------------------------------------------- 1 | var resolve = require('../'); 2 | resolve('fs', null, function(err, path) { 3 | console.log(path); 4 | }); 5 | -------------------------------------------------------------------------------- /example/custom-chromeapp.js: -------------------------------------------------------------------------------- 1 | var resolve = require('../'); 2 | var parent = { filename: __dirname + '/custom/file.js', browser: 'chromeapp' }; 3 | resolve('./main.js', parent, function(err, path) { 4 | console.log(path); 5 | }); 6 | -------------------------------------------------------------------------------- /example/custom.js: -------------------------------------------------------------------------------- 1 | var resolve = require('../'); 2 | var parent = { filename: __dirname + '/custom/file.js' }; 3 | resolve('./main.js', parent, function(err, path) { 4 | console.log(path); 5 | }); 6 | -------------------------------------------------------------------------------- /example/custom/custom-chromeapp.js: -------------------------------------------------------------------------------- 1 | console.log('chromeapp version'); 2 | -------------------------------------------------------------------------------- /example/custom/custom.js: -------------------------------------------------------------------------------- 1 | console.log('browser version'); 2 | -------------------------------------------------------------------------------- /example/custom/main.js: -------------------------------------------------------------------------------- 1 | console.log('server version'); 2 | -------------------------------------------------------------------------------- /example/custom/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom", 3 | "version": "0.0.0", 4 | "chromeapp": { 5 | "./main.js": "custom-chromeapp.js" 6 | }, 7 | "browser": { 8 | "./main.js": "custom.js" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /example/resolve.js: -------------------------------------------------------------------------------- 1 | var resolve = require('../'); 2 | resolve('../', { filename: __filename }, function(err, path) { 3 | console.log(path); 4 | }); 5 | -------------------------------------------------------------------------------- /example/skip.js: -------------------------------------------------------------------------------- 1 | var resolve = require('../'); 2 | var parent = { filename: __dirname + '/skip/main.js' }; 3 | resolve('tar', parent, function(err, path) { 4 | console.log(path); 5 | }); 6 | -------------------------------------------------------------------------------- /example/skip/main.js: -------------------------------------------------------------------------------- 1 | var tar = require('tar'); 2 | 3 | exports.add = function (a, b) { 4 | return a + b; 5 | }; 6 | 7 | exports.parse = function () { 8 | return tar.Parse(); 9 | }; 10 | -------------------------------------------------------------------------------- /example/skip/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "skip", 3 | "version": "0.0.0", 4 | "browser": { 5 | "tar": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // builtin 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | 5 | // vendor 6 | var resv = require('resolve'); 7 | 8 | // given a path, create an array of node_module paths for it 9 | // borrowed from substack/resolve 10 | function nodeModulesPaths (start, cb) { 11 | var splitRe = process.platform === 'win32' ? /[\/\\]/ : /\/+/; 12 | var parts = start.split(splitRe); 13 | 14 | var dirs = []; 15 | for (var i = parts.length - 1; i >= 0; i--) { 16 | if (parts[i] === 'node_modules') continue; 17 | var dir = path.join.apply( 18 | path, parts.slice(0, i + 1).concat(['node_modules']) 19 | ); 20 | if (!parts[0].match(/([A-Za-z]:)/)) { 21 | dir = '/' + dir; 22 | } 23 | dirs.push(dir); 24 | } 25 | return dirs; 26 | } 27 | 28 | function find_shims_in_package(pkgJson, cur_path, shims, browser) { 29 | try { 30 | var info = JSON.parse(pkgJson); 31 | } 32 | catch (err) { 33 | err.message = pkgJson + ' : ' + err.message 34 | throw err; 35 | } 36 | 37 | var replacements = getReplacements(info, browser); 38 | 39 | // no replacements, skip shims 40 | if (!replacements) { 41 | return; 42 | } 43 | 44 | // if browser mapping is a string 45 | // then it just replaces the main entry point 46 | if (typeof replacements === 'string') { 47 | var key = path.resolve(cur_path, info.main || 'index.js'); 48 | shims[key] = path.resolve(cur_path, replacements); 49 | return; 50 | } 51 | 52 | // http://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders 53 | Object.keys(replacements).forEach(function(key) { 54 | var val; 55 | if (replacements[key] === false) { 56 | val = path.normalize(__dirname + '/empty.js'); 57 | } 58 | else { 59 | val = replacements[key]; 60 | // if target is a relative path, then resolve 61 | // otherwise we assume target is a module 62 | if (val[0] === '.') { 63 | val = path.resolve(cur_path, val); 64 | } 65 | } 66 | 67 | if (key[0] === '/' || key[0] === '.') { 68 | // if begins with / ../ or ./ then we must resolve to a full path 69 | key = path.resolve(cur_path, key); 70 | } 71 | shims[key] = val; 72 | }); 73 | 74 | [ '.js', '.json' ].forEach(function (ext) { 75 | Object.keys(shims).forEach(function (key) { 76 | if (!shims[key + ext]) { 77 | shims[key + ext] = shims[key]; 78 | } 79 | }); 80 | }); 81 | } 82 | 83 | // paths is mutated 84 | // load shims from first package.json file found 85 | function load_shims(paths, browser, cb) { 86 | // identify if our file should be replaced per the browser field 87 | // original filename|id -> replacement 88 | var shims = Object.create(null); 89 | 90 | (function next() { 91 | var cur_path = paths.shift(); 92 | if (!cur_path) { 93 | return cb(null, shims); 94 | } 95 | 96 | var pkg_path = path.join(cur_path, 'package.json'); 97 | 98 | fs.readFile(pkg_path, 'utf8', function(err, data) { 99 | if (err) { 100 | // ignore paths we can't open 101 | // avoids an exists check 102 | if (err.code === 'ENOENT') { 103 | return next(); 104 | } 105 | 106 | return cb(err); 107 | } 108 | try { 109 | find_shims_in_package(data, cur_path, shims, browser); 110 | return cb(null, shims); 111 | } 112 | catch (err) { 113 | return cb(err); 114 | } 115 | }); 116 | })(); 117 | }; 118 | 119 | // paths is mutated 120 | // synchronously load shims from first package.json file found 121 | function load_shims_sync(paths, browser) { 122 | // identify if our file should be replaced per the browser field 123 | // original filename|id -> replacement 124 | var shims = Object.create(null); 125 | var cur_path; 126 | 127 | while (cur_path = paths.shift()) { 128 | var pkg_path = path.join(cur_path, 'package.json'); 129 | 130 | try { 131 | var data = fs.readFileSync(pkg_path, 'utf8'); 132 | find_shims_in_package(data, cur_path, shims, browser); 133 | return shims; 134 | } 135 | catch (err) { 136 | // ignore paths we can't open 137 | // avoids an exists check 138 | if (err.code === 'ENOENT') { 139 | continue; 140 | } 141 | 142 | throw err; 143 | } 144 | } 145 | return shims; 146 | } 147 | 148 | function build_resolve_opts(opts, base) { 149 | var packageFilter = opts.packageFilter; 150 | var browser = normalizeBrowserFieldName(opts.browser) 151 | 152 | opts.basedir = base; 153 | opts.packageFilter = function (info, pkgdir) { 154 | if (packageFilter) info = packageFilter(info, pkgdir); 155 | 156 | var replacements = getReplacements(info, browser); 157 | 158 | // no browser field, keep info unchanged 159 | if (!replacements) { 160 | return info; 161 | } 162 | 163 | info[browser] = replacements; 164 | 165 | // replace main 166 | if (typeof replacements === 'string') { 167 | info.main = replacements; 168 | return info; 169 | } 170 | 171 | var replace_main = replacements[info.main || './index.js'] || 172 | replacements['./' + info.main || './index.js']; 173 | 174 | info.main = replace_main || info.main; 175 | return info; 176 | }; 177 | 178 | var pathFilter = opts.pathFilter; 179 | opts.pathFilter = function(info, resvPath, relativePath) { 180 | if (relativePath[0] != '.') { 181 | relativePath = './' + relativePath; 182 | } 183 | var mappedPath; 184 | if (pathFilter) { 185 | mappedPath = pathFilter.apply(this, arguments); 186 | } 187 | if (mappedPath) { 188 | return mappedPath; 189 | } 190 | 191 | var replacements = info[browser]; 192 | if (!replacements) { 193 | return; 194 | } 195 | 196 | mappedPath = replacements[relativePath]; 197 | if (!mappedPath && path.extname(relativePath) === '') { 198 | mappedPath = replacements[relativePath + '.js']; 199 | if (!mappedPath) { 200 | mappedPath = replacements[relativePath + '.json']; 201 | } 202 | } 203 | return mappedPath; 204 | }; 205 | 206 | return opts; 207 | } 208 | 209 | function resolve(id, opts, cb) { 210 | 211 | // opts.filename 212 | // opts.paths 213 | // opts.modules 214 | // opts.packageFilter 215 | 216 | opts = opts || {}; 217 | opts.filename = opts.filename || ''; 218 | 219 | var base = path.dirname(opts.filename); 220 | 221 | if (opts.basedir) { 222 | base = opts.basedir; 223 | } 224 | 225 | var paths = nodeModulesPaths(base); 226 | 227 | if (opts.paths) { 228 | paths.push.apply(paths, opts.paths); 229 | } 230 | 231 | paths = paths.map(function(p) { 232 | return path.dirname(p); 233 | }); 234 | 235 | // we must always load shims because the browser field could shim out a module 236 | load_shims(paths, opts.browser, function(err, shims) { 237 | if (err) { 238 | return cb(err); 239 | } 240 | 241 | var resid = path.resolve(opts.basedir || path.dirname(opts.filename), id); 242 | if (shims[id] || shims[resid]) { 243 | var xid = shims[id] ? id : resid; 244 | // if the shim was is an absolute path, it was fully resolved 245 | if (shims[xid][0] === '/') { 246 | return resv(shims[xid], build_resolve_opts(opts, base), function(err, full, pkg) { 247 | cb(null, full, pkg); 248 | }); 249 | } 250 | 251 | // module -> alt-module shims 252 | id = shims[xid]; 253 | } 254 | 255 | var modules = opts.modules || Object.create(null); 256 | var shim_path = modules[id]; 257 | if (shim_path) { 258 | return cb(null, shim_path); 259 | } 260 | 261 | // our browser field resolver 262 | // if browser field is an object tho? 263 | var full = resv(id, build_resolve_opts(opts, base), function(err, full, pkg) { 264 | if (err) { 265 | return cb(err); 266 | } 267 | 268 | var resolved = (shims) ? shims[full] || full : full; 269 | cb(null, resolved, pkg); 270 | }); 271 | }); 272 | }; 273 | 274 | resolve.sync = function (id, opts) { 275 | 276 | // opts.filename 277 | // opts.paths 278 | // opts.modules 279 | // opts.packageFilter 280 | 281 | opts = opts || {}; 282 | opts.filename = opts.filename || ''; 283 | 284 | var base = path.dirname(opts.filename); 285 | 286 | if (opts.basedir) { 287 | base = opts.basedir; 288 | } 289 | 290 | var paths = nodeModulesPaths(base); 291 | 292 | if (opts.paths) { 293 | paths.push.apply(paths, opts.paths); 294 | } 295 | 296 | paths = paths.map(function(p) { 297 | return path.dirname(p); 298 | }); 299 | 300 | // we must always load shims because the browser field could shim out a module 301 | var shims = load_shims_sync(paths, opts.browser); 302 | var resid = path.resolve(opts.basedir || path.dirname(opts.filename), id); 303 | 304 | if (shims[id] || shims[resid]) { 305 | var xid = shims[id] ? id : resid; 306 | // if the shim was is an absolute path, it was fully resolved 307 | if (shims[xid][0] === '/') { 308 | return resv.sync(shims[xid], build_resolve_opts(opts, base)); 309 | } 310 | 311 | // module -> alt-module shims 312 | id = shims[xid]; 313 | } 314 | 315 | var modules = opts.modules || Object.create(null); 316 | var shim_path = modules[id]; 317 | if (shim_path) { 318 | return shim_path; 319 | } 320 | 321 | // our browser field resolver 322 | // if browser field is an object tho? 323 | var full = resv.sync(id, build_resolve_opts(opts, base)); 324 | 325 | return (shims) ? shims[full] || full : full; 326 | }; 327 | 328 | function normalizeBrowserFieldName(browser) { 329 | return browser || 'browser'; 330 | } 331 | 332 | function getReplacements(info, browser) { 333 | browser = normalizeBrowserFieldName(browser); 334 | var replacements = info[browser] || info.browser; 335 | 336 | // support legacy browserify field for easier migration from legacy 337 | // many packages used this field historically 338 | if (typeof info.browserify === 'string' && !replacements) { 339 | replacements = info.browserify; 340 | } 341 | 342 | return replacements; 343 | } 344 | 345 | module.exports = resolve; 346 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-resolve", 3 | "version": "2.0.0", 4 | "description": "resolve which handles browser field support in package.json", 5 | "main": "index.js", 6 | "files": [ 7 | "index.js", 8 | "empty.js" 9 | ], 10 | "scripts": { 11 | "test": "node scripts/setup-symlinks.js && mocha --reporter list test/*.js" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git://github.com/browserify/browser-resolve.git" 16 | }, 17 | "keywords": [ 18 | "resolve", 19 | "browser" 20 | ], 21 | "author": "Roman Shtylman ", 22 | "license": "MIT", 23 | "dependencies": { 24 | "resolve": "^1.17.0" 25 | }, 26 | "devDependencies": { 27 | "mocha": "^2.5.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scripts/setup-symlinks.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | 3 | try { 4 | fs.mkdirSync(__dirname + '/../test/fixtures/node_modules/linker/node_modules'); 5 | } catch (e) {} 6 | process.chdir(__dirname + '/../test/fixtures/node_modules/linker/node_modules'); 7 | try { 8 | fs.unlinkSync('linked'); 9 | } catch (e) {} 10 | fs.symlinkSync('../../../linked', 'linked', 'dir'); -------------------------------------------------------------------------------- /test/core-sync.js: -------------------------------------------------------------------------------- 1 | // test loading core modules 2 | var assert = require('assert'); 3 | var resolve = require('../'); 4 | 5 | var shims = { 6 | events: 'foo' 7 | }; 8 | 9 | test('shim found', function() { 10 | var path = resolve.sync('events', { modules: shims }); 11 | assert.equal(path, 'foo'); 12 | }); 13 | 14 | test('core shim not found', function() { 15 | var path = resolve.sync('http', {}); 16 | assert.equal(path, 'http'); 17 | }); 18 | -------------------------------------------------------------------------------- /test/core.js: -------------------------------------------------------------------------------- 1 | // test loading core modules 2 | var assert = require('assert'); 3 | var resolve = require('../'); 4 | 5 | var shims = { 6 | events: 'foo' 7 | }; 8 | 9 | test('shim found', function(done) { 10 | resolve('events', { modules: shims }, function(err, path) { 11 | assert.ifError(err); 12 | assert.equal(path, 'foo'); 13 | done(); 14 | }); 15 | }); 16 | 17 | test('core shim not found', function(done) { 18 | resolve('http', {}, function(err, path) { 19 | assert.ifError(err); 20 | assert.equal(path, 'http'); 21 | done(); 22 | }); 23 | }); 24 | 25 | -------------------------------------------------------------------------------- /test/ext.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var resolve = require('../'); 3 | 4 | var fixtures_dir = __dirname + '/fixtures'; 5 | 6 | test('module to implicit extension', function(done) { 7 | var opts = { filename: fixtures_dir + '/node_modules/module-o/main.js' } 8 | resolve('module-a', opts, function(err, path) { 9 | assert.ifError(err); 10 | assert.equal(path, require.resolve('./fixtures/node_modules/module-o/x.js')); 11 | done(); 12 | }); 13 | }); 14 | 15 | test('implicit extension to implicit extension', function(done) { 16 | var opts = { filename: fixtures_dir + '/node_modules/module-p/main.js' } 17 | resolve('./z.js', opts, function(err, path) { 18 | assert.ifError(err); 19 | assert.equal(path, require.resolve('./fixtures/node_modules/module-p/x.js')); 20 | done(); 21 | }); 22 | }); 23 | 24 | test('implicit extension to implicit extension', function(done) { 25 | var opts = { filename: fixtures_dir + '/node_modules/module-p/main.js' } 26 | resolve('./z', opts, function(err, path) { 27 | assert.ifError(err); 28 | assert.equal(path, require.resolve('./fixtures/node_modules/module-p/x.js')); 29 | done(); 30 | }); 31 | }); 32 | 33 | test('explicit extension to explicit extension', function(done) { 34 | var opts = { filename: fixtures_dir + '/node_modules/module-q/main.js' } 35 | resolve('./z.js', opts, function(err, path) { 36 | assert.ifError(err); 37 | assert.equal(path, require.resolve('./fixtures/node_modules/module-q/x.js')); 38 | done(); 39 | }); 40 | }); 41 | 42 | test('implicit extension to explicit extension', function(done) { 43 | var opts = { filename: fixtures_dir + '/node_modules/module-r/main.js' } 44 | resolve('./z.js', opts, function(err, path) { 45 | assert.ifError(err); 46 | assert.equal(path, require.resolve('./fixtures/node_modules/module-r/x.js')); 47 | done(); 48 | }); 49 | }); 50 | 51 | test('module implicit extension to explicit extension', function(done) { 52 | var opts = { filename: fixtures_dir + '/node_modules/module-s/main.js' } 53 | resolve('whatever/z.js', opts, function(err, path) { 54 | assert.ifError(err); 55 | assert.equal(path, require.resolve('./fixtures/node_modules/module-s/x.js')); 56 | done(); 57 | }); 58 | }); 59 | 60 | test('module implicit extension to explicit extension', function(done) { 61 | var opts = { filename: fixtures_dir + '/node_modules/module-s/main.js' } 62 | resolve('whatever/z', opts, function(err, path) { 63 | assert.ifError(err); 64 | assert.equal(path, require.resolve('./fixtures/node_modules/module-s/x.js')); 65 | done(); 66 | }); 67 | }); 68 | 69 | -------------------------------------------------------------------------------- /test/false-sync.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var path = require('path'); 3 | var resolve = require('../'); 4 | 5 | var fixtures_dir = __dirname + '/fixtures'; 6 | 7 | test('false file', function() { 8 | var parent_file = fixtures_dir + '/node_modules/false/index.js'; 9 | var p = resolve.sync('./fake.js', { filename: parent_file }); 10 | assert.equal(p, path.normalize(__dirname + '/../empty.js')); 11 | }); 12 | 13 | test('false module', function() { 14 | var parent_file = fixtures_dir + '/node_modules/false/index.js'; 15 | var p = resolve.sync('ignore-me', { filename: parent_file }); 16 | assert.equal(p, path.normalize(__dirname + '/../empty.js')); 17 | }); 18 | -------------------------------------------------------------------------------- /test/false.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var path = require('path'); 3 | var resolve = require('../'); 4 | 5 | var fixtures_dir = __dirname + '/fixtures'; 6 | 7 | test('false file', function(done) { 8 | var parent_file = fixtures_dir + '/node_modules/false/index.js'; 9 | resolve('./fake.js', { filename: parent_file }, function(err, p) { 10 | assert.ifError(err); 11 | assert.equal(p, path.normalize(__dirname + '/../empty.js')); 12 | done(); 13 | }); 14 | }); 15 | 16 | test('false module', function(done) { 17 | var parent_file = fixtures_dir + '/node_modules/false/index.js'; 18 | resolve('ignore-me', { filename: parent_file }, function(err, p) { 19 | assert.ifError(err); 20 | assert.equal(p, path.normalize(__dirname + '/../empty.js')); 21 | done(); 22 | }); 23 | }); 24 | 25 | test('false expand path', function(done) { 26 | var parent = { 27 | filename: fixtures_dir + '/node_modules/module-m/lib/index.js' 28 | }; 29 | 30 | resolve('./hide', parent, function(err, p, pkg) { 31 | assert.ifError(err); 32 | assert.equal(p, path.normalize(__dirname + '/../empty.js')); 33 | done(); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/fixtures-coffee/foo.coffee: -------------------------------------------------------------------------------- 1 | // blank file 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-a/index.coffee: -------------------------------------------------------------------------------- 1 | // dummy 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-b/main.coffee: -------------------------------------------------------------------------------- 1 | // entry 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-b/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.coffee" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-c/bar.coffee: -------------------------------------------------------------------------------- 1 | // required by browser.js only 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-c/browser.coffee: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | require('./bar'); 3 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-c/main.coffee: -------------------------------------------------------------------------------- 1 | // entry 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-c/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.coffee", 3 | "browser": "./browser.coffee" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-d/browser.coffee: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-d/main.coffee: -------------------------------------------------------------------------------- 1 | // entry 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-d/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.coffee", 3 | "browser": { 4 | "./main.coffee": "./browser.coffee" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-e/browser.coffee: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-e/foo.coffee: -------------------------------------------------------------------------------- 1 | // won't be used 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-e/main.coffee: -------------------------------------------------------------------------------- 1 | // entry 2 | require('./foo'); 3 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.coffee", 3 | "browser": { 4 | "./foo.coffee": "./browser.coffee" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-f/lib/browser.coffee: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-f/lib/foo.coffee: -------------------------------------------------------------------------------- 1 | // won't be used 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-f/lib/main.coffee: -------------------------------------------------------------------------------- 1 | // entry 2 | require('./foo'); 3 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-f/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./lib/main.coffee", 3 | "browser": { 4 | "./lib/foo.coffee": "./lib/browser.coffee" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-g/foobar-browser.coffee: -------------------------------------------------------------------------------- 1 | // foobar browser 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-g/index.coffee: -------------------------------------------------------------------------------- 1 | require('foobar'); 2 | -------------------------------------------------------------------------------- /test/fixtures-coffee/node_modules/module-g/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./index.js", 3 | "browser": { 4 | "foobar": "./foobar-browser.coffee" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/foo.js: -------------------------------------------------------------------------------- 1 | // blank file 2 | -------------------------------------------------------------------------------- /test/fixtures/linked/index.js: -------------------------------------------------------------------------------- 1 | // dummy -------------------------------------------------------------------------------- /test/fixtures/node_modules/alt-browser-field/chromeapp-direct.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserify/browser-resolve/21b46454ae772bce1b894a63f9cdabe0953a6712/test/fixtures/node_modules/alt-browser-field/chromeapp-direct.js -------------------------------------------------------------------------------- /test/fixtures/node_modules/alt-browser-field/chromeapp.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserify/browser-resolve/21b46454ae772bce1b894a63f9cdabe0953a6712/test/fixtures/node_modules/alt-browser-field/chromeapp.js -------------------------------------------------------------------------------- /test/fixtures/node_modules/alt-browser-field/direct.js: -------------------------------------------------------------------------------- 1 | // node empty file 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/alt-browser-field/foo.js: -------------------------------------------------------------------------------- 1 | require('foobar'); 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/alt-browser-field/index.js: -------------------------------------------------------------------------------- 1 | var URL = require("url"); 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/alt-browser-field/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./index.js", 3 | "browser": { 4 | "url": "./url-browser.js" 5 | }, 6 | "chromeapp": { 7 | "url": "./url-chromeapp.js", 8 | "./index.js": "./chromeapp.js", 9 | "./direct": "./chromeapp-direct.js", 10 | "foobar": "module-k" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/alt-browser-field/url-browser.js: -------------------------------------------------------------------------------- 1 | // empty 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/alt-browser-field/url-chromeapp.js: -------------------------------------------------------------------------------- 1 | // empty 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/false/fake.js: -------------------------------------------------------------------------------- 1 | module.exports = 'fake'; 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/false/node_modules/ignore-me/index.js: -------------------------------------------------------------------------------- 1 | module.exports = 'failure'; 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/false/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.js", 3 | "browser": { 4 | "ignore-me": false, 5 | "./fake.js": false 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/linker/index.js: -------------------------------------------------------------------------------- 1 | require('linked'); -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-a/index.js: -------------------------------------------------------------------------------- 1 | // dummy 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-b/main.js: -------------------------------------------------------------------------------- 1 | // entry 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-b/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.js" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-c/bar.js: -------------------------------------------------------------------------------- 1 | // required by browser.js only 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-c/browser.js: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | require('./bar'); 3 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-c/chromeapp.js: -------------------------------------------------------------------------------- 1 | // chromeapp entry file 2 | require('./foo'); 3 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-c/foo.js: -------------------------------------------------------------------------------- 1 | // required by chromeapp.js only 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-c/main.js: -------------------------------------------------------------------------------- 1 | // entry 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-c/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.js", 3 | "browser": "./browser.js", 4 | "chromeapp": "./chromeapp.js" 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-d/browser.js: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-d/main.js: -------------------------------------------------------------------------------- 1 | // entry 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-d/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.js", 3 | "browser": { 4 | "./main.js": "./browser.js" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-e/browser.js: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-e/foo.js: -------------------------------------------------------------------------------- 1 | // won't be used 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-e/main.js: -------------------------------------------------------------------------------- 1 | // entry 2 | require('./foo'); 3 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./main.js", 3 | "browser": { 4 | "./foo.js": "./browser.js" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-f/lib/browser.js: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-f/lib/foo.js: -------------------------------------------------------------------------------- 1 | // won't be used 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-f/lib/main.js: -------------------------------------------------------------------------------- 1 | // entry 2 | require('./foo'); 3 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-f/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./lib/main.js", 3 | "browser": { 4 | "./lib/foo.js": "./lib/browser.js" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-g/foobar-browser.js: -------------------------------------------------------------------------------- 1 | // foobar browser 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-g/index.js: -------------------------------------------------------------------------------- 1 | require('foobar'); 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-g/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./index.js", 3 | "browser": { 4 | "foobar": "./foobar-browser.js" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-h/index.js: -------------------------------------------------------------------------------- 1 | require('foobar'); 2 | require('querystring'); 3 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-h/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./index.js", 3 | "browser": { 4 | "foobar": "module-b", 5 | "querystring": "module-c" 6 | }, 7 | "chromeapp": { 8 | "foobar": "module-b", 9 | "querystring": "module-c" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-i/index.js: -------------------------------------------------------------------------------- 1 | require('foobar'); 2 | require('querystring'); 3 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-i/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./index.js", 3 | "browser": { 4 | "foobar": "module-b", 5 | "querystring": "module-c" 6 | }, 7 | "browserify": { 8 | "transform": "deamdify" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-j/index.js: -------------------------------------------------------------------------------- 1 | require('foobar'); 2 | require('querystring'); 3 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-j/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./index.js", 3 | "browser": { 4 | "foobar": "module-i", 5 | "querystring": "module-c" 6 | }, 7 | "browserify": { 8 | "transform": "deamdify" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-k/browser.js: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-k/index.js: -------------------------------------------------------------------------------- 1 | // node empty file 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-k/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "index.js", 3 | "browser": { 4 | "./index.js": "./browser.js" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-l/browser-direct.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserify/browser-resolve/21b46454ae772bce1b894a63f9cdabe0953a6712/test/fixtures/node_modules/module-l/browser-direct.js -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-l/browser.js: -------------------------------------------------------------------------------- 1 | // browser entry file 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-l/index.js: -------------------------------------------------------------------------------- 1 | // node empty file 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-l/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "index.js", 3 | "browser": { 4 | "./index.js": "./browser.js", 5 | "./direct": "./browser-direct.js" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-m/lib/hide.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserify/browser-resolve/21b46454ae772bce1b894a63f9cdabe0953a6712/test/fixtures/node_modules/module-m/lib/hide.js -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-m/lib/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserify/browser-resolve/21b46454ae772bce1b894a63f9cdabe0953a6712/test/fixtures/node_modules/module-m/lib/index.js -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-m/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": { 3 | "./lib/hide.js": false 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-n/browser-bar.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-n/browser-foo.js: -------------------------------------------------------------------------------- 1 | // browser -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-n/index.js: -------------------------------------------------------------------------------- 1 | // main 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-n/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./index.js", 3 | "browser": { 4 | "./foo.js": "./browser-foo.js", 5 | "./bar.json": "./browser-bar.json" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-o/main.js: -------------------------------------------------------------------------------- 1 | // entry 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-o/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": { 3 | "module-a": "./x" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-o/x.js: -------------------------------------------------------------------------------- 1 | // x 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-p/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": { 3 | "./z": "./x" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-p/x.js: -------------------------------------------------------------------------------- 1 | // x 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-q/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": { 3 | "./z.js": "./x.js" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-q/x.js: -------------------------------------------------------------------------------- 1 | // x 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-r/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": { 3 | "./z": "./x.js" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-r/x.js: -------------------------------------------------------------------------------- 1 | // x 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-s/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": { 3 | "whatever/z": "./x.js" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-s/x.js: -------------------------------------------------------------------------------- 1 | // x 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-t/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "browser": { 3 | "./x": "./y" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-t/x.js: -------------------------------------------------------------------------------- 1 | // x -------------------------------------------------------------------------------- /test/fixtures/node_modules/module-t/y.js: -------------------------------------------------------------------------------- 1 | // y 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/override-engine-shim/index.js: -------------------------------------------------------------------------------- 1 | var URL = require("url"); 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/override-engine-shim/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": "./index.js", 3 | "browser": { 4 | "url": "./url-browser.js" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/override-engine-shim/url-browser.js: -------------------------------------------------------------------------------- 1 | // empty 2 | -------------------------------------------------------------------------------- /test/fixtures/node_modules/toString/index.js: -------------------------------------------------------------------------------- 1 | // dummy 2 | -------------------------------------------------------------------------------- /test/local-coffee.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var resolve = require('../'); 3 | 4 | var fixtures_dir = __dirname + '/fixtures-coffee'; 5 | 6 | test('local', function(done) { 7 | // resolve needs a parent filename or paths to be able to lookup files 8 | // we provide a phony parent file 9 | var parent = { 10 | filename: fixtures_dir + '/phony.js', 11 | extensions: ['.js', '.coffee'] 12 | }; 13 | resolve('./foo', parent, function(err, path) { 14 | assert.ifError(err); 15 | assert.equal(path, require.resolve('./fixtures-coffee/foo.coffee')); 16 | done(); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/local-sync.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var resolve = require('../'); 3 | 4 | var fixtures_dir = __dirname + '/fixtures'; 5 | 6 | test('local', function() { 7 | // resolve needs a parent filename or paths to be able to lookup files 8 | // we provide a phony parent file 9 | var path = resolve.sync('./foo', { filename: fixtures_dir + '/phony.js' }); 10 | assert.equal(path, require.resolve('./fixtures/foo')); 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /test/local.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var resolve = require('../'); 3 | 4 | var fixtures_dir = __dirname + '/fixtures'; 5 | 6 | test('local', function(done) { 7 | // resolve needs a parent filename or paths to be able to lookup files 8 | // we provide a phony parent file 9 | resolve('./foo', { filename: fixtures_dir + '/phony.js' }, function(err, path) { 10 | assert.ifError(err); 11 | assert.equal(path, require.resolve('./fixtures/foo')); 12 | done(); 13 | }); 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --ui qunit 2 | -------------------------------------------------------------------------------- /test/modules-coffee.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var resolve = require('../'); 3 | 4 | var fixtures_dir = __dirname + '/fixtures-coffee/node_modules'; 5 | 6 | // no package.json, load index.js 7 | test('index.js of module dir', function(done) { 8 | var parent = { 9 | paths: [ fixtures_dir ], 10 | extensions: ['.js', '.coffee'] 11 | }; 12 | resolve('module-a', parent, function(err, path) { 13 | assert.ifError(err); 14 | assert.equal(path, require.resolve('./fixtures-coffee/node_modules/module-a/index.coffee')); 15 | done(); 16 | }); 17 | }); 18 | 19 | // package.json main field specifies other location 20 | test('alternate main', function(done) { 21 | var parent = { 22 | paths: [ fixtures_dir ], 23 | extensions: ['.js', '.coffee'] 24 | }; 25 | resolve('module-b', parent, function(err, path) { 26 | assert.ifError(err); 27 | assert.equal(path, require.resolve('./fixtures-coffee/node_modules/module-b/main.coffee')); 28 | done(); 29 | }, {extensions: ['.js', '.coffee']}); 30 | }); 31 | 32 | // package.json has 'browser' field which is a string 33 | test('string browser field as main', function(done) { 34 | var parent = { 35 | paths: [ fixtures_dir ], 36 | extensions: ['.js', '.coffee'] 37 | }; 38 | resolve('module-c', parent, function(err, path) { 39 | assert.ifError(err); 40 | assert.equal(path, require.resolve('./fixtures-coffee/node_modules/module-c/browser.coffee')); 41 | done(); 42 | }, {extensions: ['.js', '.coffee']}); 43 | }); 44 | 45 | // package.json has 'browser' field which is a string 46 | test('string browser field as main - require subfile', function(done) { 47 | var parent = { 48 | filename: fixtures_dir + '/module-c/browser.js', 49 | paths: [ fixtures_dir + '/module-c/node_modules' ], 50 | extensions: ['.js', '.coffee'] 51 | }; 52 | 53 | resolve('./bar', parent, function(err, path) { 54 | assert.ifError(err); 55 | assert.equal(path, require.resolve('./fixtures-coffee/node_modules/module-c/bar.coffee')); 56 | done(); 57 | }); 58 | }); 59 | 60 | // package.json has browser field as object 61 | // one of the keys replaces the main file 62 | // this would be done if the user needed to replace main and some other module 63 | test('object browser field as main', function(done) { 64 | var parent = { 65 | paths: [ fixtures_dir ], 66 | extensions: ['.js', '.coffee'] 67 | }; 68 | resolve('module-d', parent, function(err, path) { 69 | assert.ifError(err); 70 | assert.equal(path, require.resolve('./fixtures-coffee/node_modules/module-d/browser.coffee')); 71 | done(); 72 | }); 73 | }); 74 | 75 | // browser field in package.json maps ./foo.js -> ./browser.js 76 | // when we resolve ./foo while in module-e, this mapping should take effect 77 | // the result is that ./foo resolves to ./browser 78 | test('object browser field replace file', function(done) { 79 | var parent = { 80 | filename: fixtures_dir + '/module-e/main.coffee', 81 | extensions: ['.js', '.coffee'] 82 | }; 83 | 84 | resolve('./foo', parent, function(err, path) { 85 | assert.ifError(err); 86 | assert.equal(path, require.resolve('./fixtures-coffee/node_modules/module-e/browser.coffee')); 87 | done(); 88 | }); 89 | }); 90 | 91 | // same as above, but without a paths field in parent 92 | // should still checks paths on the filename of parent 93 | test('object browser field replace file - no paths', function(done) { 94 | var parent = { 95 | filename: fixtures_dir + '/module-f/lib/main.coffee', 96 | extensions: ['.js', '.coffee'] 97 | }; 98 | 99 | resolve('./foo', parent, function(err, path) { 100 | assert.ifError(err); 101 | assert.equal(path, require.resolve('./fixtures-coffee/node_modules/module-f/lib/browser.coffee')); 102 | done(); 103 | }); 104 | }); 105 | 106 | test('replace module in browser field object', function(done) { 107 | var parent = { 108 | filename: fixtures_dir + '/module-g/index.js', 109 | extensions: ['.js', '.coffee'] 110 | }; 111 | 112 | resolve('foobar', parent, function(err, path) { 113 | assert.ifError(err); 114 | assert.equal(path, require.resolve('./fixtures-coffee/node_modules/module-g/foobar-browser.coffee')); 115 | done(); 116 | }); 117 | }); 118 | -------------------------------------------------------------------------------- /test/modules-sync.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var resolve = require('../'); 3 | 4 | var fixtures_dir = __dirname + '/fixtures/node_modules'; 5 | 6 | // no package.json, load index.js 7 | test('index.js of module dir', function() { 8 | var path = resolve.sync('module-a', { paths: [ fixtures_dir ], package: { main: 'fixtures' } }); 9 | assert.equal(path, require.resolve('./fixtures/node_modules/module-a/index')); 10 | }); 11 | 12 | // package.json main field specifies other location 13 | test('alternate main', function() { 14 | var path = resolve.sync('module-b', { paths: [ fixtures_dir ], package: { main: 'fixtures' } }); 15 | assert.equal(path, require.resolve('./fixtures/node_modules/module-b/main')); 16 | }); 17 | 18 | // package.json has 'browser' field which is a string 19 | test('string browser field as main', function() { 20 | var path = resolve.sync('module-c', { paths: [ fixtures_dir ], package: { main: 'fixtures' } }); 21 | assert.equal(path, require.resolve('./fixtures/node_modules/module-c/browser')); 22 | }); 23 | 24 | // package.json has 'browser' field which is a string 25 | test('string browser field as main - require subfile', function() { 26 | var parent = { 27 | filename: fixtures_dir + '/module-c/browser.js', 28 | paths: [ fixtures_dir + '/module-c/node_modules' ], 29 | package: { main: './browser.js' } 30 | }; 31 | 32 | var path = resolve.sync('./bar', parent); 33 | assert.equal(path, require.resolve('./fixtures/node_modules/module-c/bar')); 34 | }); 35 | 36 | // package.json has browser field as object 37 | // one of the keys replaces the main file 38 | // this would be done if the user needed to replace main and some other module 39 | test('object browser field as main', function() { 40 | var path = resolve.sync('module-d', { paths: [ fixtures_dir ], package: { main: 'fixtures' } }); 41 | assert.equal(path, require.resolve('./fixtures/node_modules/module-d/browser')); 42 | }); 43 | 44 | // package.json has browser field as object 45 | // one of the keys replaces the main file 46 | // however the main has no prefix and browser uses ./ prefix for the same file 47 | test('object browser field as main', function() { 48 | var path = resolve.sync('module-k', { paths: [ fixtures_dir ], package: { main: 'fixtures' } }); 49 | assert.equal(path, require.resolve('./fixtures/node_modules/module-k/browser')); 50 | }); 51 | 52 | // browser field in package.json maps ./foo.js -> ./browser.js 53 | // when we resolve ./foo while in module-e, this mapping should take effect 54 | // the result is that ./foo resolves to ./browser 55 | test('object browser field replace file', function() { 56 | var parent = { 57 | filename: fixtures_dir + '/module-e/main.js', 58 | package: { main: './main.js' } 59 | }; 60 | 61 | var path = resolve.sync('./foo', parent); 62 | assert.equal(path, require.resolve('./fixtures/node_modules/module-e/browser')); 63 | }); 64 | 65 | // browser field in package.json maps "module" -> "alternate module" 66 | test('test foobar -> module-b replacement', function() { 67 | var parent = { 68 | filename: fixtures_dir + '/module-h/index.js', 69 | package: { main: './index.js' } 70 | }; 71 | 72 | var path = resolve.sync('foobar', parent); 73 | assert.equal(path, require.resolve('./fixtures/node_modules/module-b/main')); 74 | }); 75 | 76 | // browser field in package.json maps "relative file" -> "relative file" with no extension 77 | test('test ./x -> ./y replacement', function() { 78 | var parent = { 79 | filename: fixtures_dir + '/module-t/index.js', 80 | package: { main: './index.js' } 81 | }; 82 | 83 | var path = resolve.sync('./x', parent); 84 | assert.equal(path, require.resolve('./fixtures/node_modules/module-t/y.js')); 85 | }); 86 | 87 | // same as above but replacing core 88 | test('test core -> module-c replacement', function() { 89 | var parent = { 90 | filename: fixtures_dir + '/module-h/index.js', 91 | package: { main: './index.js' } 92 | }; 93 | 94 | var path = resolve.sync('querystring', parent); 95 | assert.equal(path, require.resolve('./fixtures/node_modules/module-c/browser')); 96 | }); 97 | 98 | // browser field in package.json maps "module" -> "alternate module" 99 | test('test foobar -> module-b replacement with transform', function() { 100 | var parent = { 101 | filename: fixtures_dir + '/module-i/index.js', 102 | package: { main: './index.js' } 103 | }; 104 | 105 | var path = resolve.sync('foobar', parent); 106 | assert.equal(path, require.resolve('./fixtures/node_modules/module-b/main')); 107 | }); 108 | 109 | test('test foobar -> module-i replacement with transform in replacement', function() { 110 | var parent = { 111 | filename: fixtures_dir + '/module-j/index.js', 112 | package: { main: './index.js' } 113 | }; 114 | 115 | var path = resolve.sync('foobar', parent); 116 | assert.equal(path, require.resolve('./fixtures/node_modules/module-i/index')); 117 | }); 118 | 119 | // same as above, but without a paths field in parent 120 | // should still checks paths on the filename of parent 121 | test('object browser field replace file - no paths', function() { 122 | var parent = { 123 | filename: fixtures_dir + '/module-f/lib/main.js', 124 | package: { main: './lib/main.js' } 125 | }; 126 | 127 | var path = resolve.sync('./foo', parent); 128 | assert.equal(path, require.resolve('./fixtures/node_modules/module-f/lib/browser')); 129 | }); 130 | 131 | test('replace module in browser field object', function() { 132 | var parent = { 133 | filename: fixtures_dir + '/module-g/index.js', 134 | package: { main: './index.js' } 135 | }; 136 | 137 | var path = resolve.sync('foobar', parent); 138 | assert.equal(path, require.resolve('./fixtures/node_modules/module-g/foobar-browser')); 139 | }); 140 | 141 | test('override engine shim', function() { 142 | var parent = { 143 | filename: fixtures_dir + '/override-engine-shim/index.js', 144 | package: { main: './index.js' }, 145 | modules: { url: "wonderland" } 146 | }; 147 | var path = resolve.sync('url', parent); 148 | assert.equal(path, require.resolve('./fixtures/node_modules/override-engine-shim/url-browser')); 149 | }); 150 | 151 | test('alt-browser field', function() { 152 | var parent = { 153 | filename: fixtures_dir + '/alt-browser-field/index.js', 154 | package: { main: './index.js' }, 155 | browser: 'chromeapp' 156 | }; 157 | 158 | var path = resolve.sync('url', parent); 159 | assert.equal(path, require.resolve('./fixtures/node_modules/alt-browser-field/url-chromeapp')); 160 | }); 161 | -------------------------------------------------------------------------------- /test/modules.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var resolve = require('../'); 3 | 4 | var fixtures_dir = __dirname + '/fixtures/node_modules'; 5 | 6 | // no package.json, load index.js 7 | test('index.js of module dir', function(done) { 8 | resolve('module-a', { paths: [ fixtures_dir ], package: { main: 'fixtures' } }, function(err, path, pkg) { 9 | assert.ifError(err); 10 | assert.equal(path, require.resolve('./fixtures/node_modules/module-a/index')); 11 | assert.strictEqual(pkg.main, 'fixtures'); 12 | done(); 13 | }); 14 | }); 15 | 16 | // package.json main field specifies other location 17 | test('alternate main', function(done) { 18 | resolve('module-b', { paths: [ fixtures_dir ], package: { main: 'fixtures' } }, function(err, path, pkg) { 19 | assert.ifError(err); 20 | assert.equal(path, require.resolve('./fixtures/node_modules/module-b/main')); 21 | assert.strictEqual(pkg.main, './main.js'); 22 | done(); 23 | }); 24 | }); 25 | 26 | // package.json has 'browser' field which is a string 27 | test('string browser field as main', function(done) { 28 | resolve('module-c', { paths: [ fixtures_dir ], package: { main: 'fixtures' } }, function(err, path, pkg) { 29 | assert.ifError(err); 30 | assert.equal(path, require.resolve('./fixtures/node_modules/module-c/browser')); 31 | assert.equal(pkg.main, './browser.js'); 32 | done(); 33 | }); 34 | }); 35 | 36 | // package.json has 'browser' field which is a string 37 | test('string browser field as main - require subfile', function(done) { 38 | var parent = { 39 | filename: fixtures_dir + '/module-c/browser.js', 40 | paths: [ fixtures_dir + '/module-c/node_modules' ], 41 | package: { main: './browser.js' } 42 | }; 43 | 44 | resolve('./bar', parent, function(err, path, pkg) { 45 | assert.ifError(err); 46 | assert.equal(path, require.resolve('./fixtures/node_modules/module-c/bar')); 47 | assert.equal(pkg.main, './browser.js'); 48 | done(); 49 | }); 50 | }); 51 | 52 | // package.json has an alternative 'browser' field which is a string 53 | test('string alt browser field as main - require subfile', function(done) { 54 | var parent = { 55 | filename: fixtures_dir + '/module-c/chromeapp.js', 56 | paths: [ fixtures_dir + '/module-c/node_modules' ], 57 | package: { main: './chromeapp.js' }, 58 | browser: 'chromeapp' 59 | }; 60 | 61 | resolve('./foo', parent, function(err, path, pkg) { 62 | assert.ifError(err); 63 | assert.equal(path, require.resolve('./fixtures/node_modules/module-c/foo')); 64 | assert.equal(pkg.main, './chromeapp.js'); 65 | done(); 66 | }); 67 | }); 68 | 69 | // package.json has browser field as object 70 | // one of the keys replaces the main file 71 | // this would be done if the user needed to replace main and some other module 72 | test('object browser field as main', function(done) { 73 | resolve('module-d', { paths: [ fixtures_dir ] }, function(err, path, pkg) { 74 | assert.ifError(err); 75 | assert.equal(path, require.resolve('./fixtures/node_modules/module-d/browser')); 76 | assert.equal(pkg.main, './browser.js'); 77 | done(); 78 | }); 79 | }); 80 | 81 | // package.json has browser field as object 82 | // one of the keys replaces the main file 83 | // however the main has no prefix and browser uses ./ prefix for the same file 84 | test('object browser field as main', function(done) { 85 | resolve('module-k', { paths: [ fixtures_dir ] }, function(err, path, pkg) { 86 | assert.ifError(err); 87 | assert.equal(path, require.resolve('./fixtures/node_modules/module-k/browser')); 88 | assert.equal(pkg.main, './browser.js'); 89 | done(); 90 | }); 91 | }); 92 | 93 | test('deep module reference mapping', function(done) { 94 | resolve('module-l/direct', { basedir: __dirname + '/fixtures' }, function(err, path, pkg) { 95 | assert.ifError(err); 96 | assert.equal(path, require.resolve('./fixtures/node_modules/module-l/browser-direct')); 97 | assert.equal(pkg.main, './browser.js'); 98 | done(); 99 | }); 100 | }); 101 | 102 | // package.json has browser field as object 103 | // test that file resolves even though the file extension is omitted 104 | test('deep module reference mapping without file extension - .js', function(done) { 105 | resolve('module-n/foo', { basedir: __dirname + '/fixtures' }, function(err, path, pkg) { 106 | assert.ifError(err); 107 | assert.equal(path, require.resolve('./fixtures/node_modules/module-n/browser-foo')); 108 | done(); 109 | }); 110 | }); 111 | test('deep module reference mapping without file extension - .json', function(done) { 112 | resolve('module-n/bar', { basedir: __dirname + '/fixtures' }, function(err, path, pkg) { 113 | assert.ifError(err); 114 | assert.equal(path, require.resolve('./fixtures/node_modules/module-n/browser-bar')); 115 | done(); 116 | }); 117 | }); 118 | 119 | // browser field in package.json maps ./foo.js -> ./browser.js 120 | // when we resolve ./foo while in module-e, this mapping should take effect 121 | // the result is that ./foo resolves to ./browser 122 | test('object browser field replace file', function(done) { 123 | var parent = { 124 | filename: fixtures_dir + '/module-e/main.js', 125 | package: { main: './main.js' } 126 | }; 127 | 128 | resolve('./foo', parent, function(err, path, pkg) { 129 | assert.ifError(err); 130 | assert.equal(path, require.resolve('./fixtures/node_modules/module-e/browser')); 131 | assert.equal(pkg.main, './main.js'); 132 | done(); 133 | }); 134 | }); 135 | 136 | // browser field in package.json maps "module" -> "alternate module" 137 | test('test foobar -> module-b replacement', function(done) { 138 | var parent = { 139 | filename: fixtures_dir + '/module-h/index.js', 140 | package: { main: './index.js' } 141 | }; 142 | 143 | resolve('foobar', parent, function(err, path, pkg) { 144 | assert.ifError(err); 145 | assert.equal(path, require.resolve('./fixtures/node_modules/module-b/main')); 146 | assert.equal(pkg.main, './main.js'); 147 | done(); 148 | }); 149 | }); 150 | 151 | // same as above but replacing core 152 | test('test core -> module-c replacement', function(done) { 153 | var parent = { 154 | filename: fixtures_dir + '/module-h/index.js', 155 | package: { main: './index.js' } 156 | }; 157 | 158 | resolve('querystring', parent, function(err, path, pkg) { 159 | assert.ifError(err); 160 | assert.equal(path, require.resolve('./fixtures/node_modules/module-c/browser')); 161 | assert.equal(pkg.main, './browser.js'); 162 | done(); 163 | }); 164 | }); 165 | 166 | // same as above but with alt browser 167 | test('test core -> module-c replacement with alt browser', function(done) { 168 | var parent = { 169 | filename: fixtures_dir + '/module-h/index.js', 170 | package: { main: './index.js' }, 171 | browser: 'chromeapp' 172 | }; 173 | 174 | resolve('querystring', parent, function(err, path, pkg) { 175 | assert.ifError(err); 176 | assert.equal(path, require.resolve('./fixtures/node_modules/module-c/chromeapp')); 177 | assert.equal(pkg.main, './chromeapp.js'); 178 | done(); 179 | }); 180 | }); 181 | 182 | // browser field in package.json maps "module" -> "alternate module" 183 | test('test foobar -> module-b replacement with transform', function(done) { 184 | var parent = { 185 | filename: fixtures_dir + '/module-i/index.js', 186 | package: { main: './index.js' } 187 | }; 188 | 189 | resolve('foobar', parent, function(err, path, pkg) { 190 | assert.ifError(err); 191 | assert.equal(path, require.resolve('./fixtures/node_modules/module-b/main')); 192 | assert.equal(pkg.main, './main.js'); 193 | done(); 194 | }); 195 | }); 196 | 197 | // browser field in package.json maps "relative file" -> "relative file" with no extension 198 | test('test ./x -> ./y replacement', function(done) { 199 | var parent = { 200 | filename: fixtures_dir + '/module-t/index.js', 201 | package: { main: './index.js' } 202 | }; 203 | 204 | resolve('./x', parent, function(err, path, pkg) { 205 | assert.ifError(err); 206 | assert.equal(path, require.resolve('./fixtures/node_modules/module-t/y.js')); 207 | done(); 208 | }); 209 | }); 210 | 211 | test('test foobar -> module-i replacement with transform in replacement', function(done) { 212 | var parent = { 213 | filename: fixtures_dir + '/module-j/index.js', 214 | package: { main: './index.js' } 215 | }; 216 | 217 | resolve('foobar', parent, function(err, path, pkg) { 218 | assert.ifError(err); 219 | assert.equal(path, require.resolve('./fixtures/node_modules/module-i/index')); 220 | assert.equal(pkg.main, './index.js'); 221 | assert.equal(pkg.browser['foobar'], 'module-b'); 222 | assert.equal(pkg.browserify.transform, 'deamdify'); 223 | done(); 224 | }); 225 | }); 226 | 227 | // same as above, but without a paths field in parent 228 | // should still checks paths on the filename of parent 229 | test('object browser field replace file - no paths', function(done) { 230 | var parent = { 231 | filename: fixtures_dir + '/module-f/lib/main.js', 232 | package: { main: './lib/main.js' } 233 | }; 234 | 235 | resolve('./foo', parent, function(err, path, pkg) { 236 | assert.ifError(err); 237 | assert.equal(path, require.resolve('./fixtures/node_modules/module-f/lib/browser')); 238 | assert.equal(pkg.main, './lib/main.js'); 239 | done(); 240 | }); 241 | }); 242 | 243 | test('replace module in browser field object', function(done) { 244 | var parent = { 245 | filename: fixtures_dir + '/module-g/index.js', 246 | package: { main: './index.js' } 247 | }; 248 | 249 | resolve('foobar', parent, function(err, path, pkg) { 250 | assert.ifError(err); 251 | assert.equal(path, require.resolve('./fixtures/node_modules/module-g/foobar-browser')); 252 | assert.equal(pkg.main, './index.js'); 253 | done(); 254 | }); 255 | }); 256 | 257 | test('override engine shim', function(done) { 258 | var parent = { 259 | filename: fixtures_dir + '/override-engine-shim/index.js', 260 | package: { main: './index.js' }, 261 | modules: { url: 'wonderland' } 262 | }; 263 | resolve('url', parent, function(err, path, pkg) { 264 | assert.ifError(err); 265 | assert.equal(path, require.resolve('./fixtures/node_modules/override-engine-shim/url-browser')); 266 | done(); 267 | }); 268 | }); 269 | 270 | test('alt-browser field', function(done) { 271 | var parent = { 272 | filename: fixtures_dir + '/alt-browser-field/index.js', 273 | package: { main: './index.js' }, 274 | browser: 'chromeapp' 275 | }; 276 | 277 | resolve('url', parent, function(err, path, pkg) { 278 | assert.ifError(err); 279 | assert.equal(path, require.resolve('./fixtures/node_modules/alt-browser-field/url-chromeapp')); 280 | assert.equal(pkg.main, './index.js'); 281 | done(); 282 | }); 283 | }); 284 | 285 | test('alt-browser deep module reference mapping', function(done) { 286 | resolve('alt-browser-field/direct', { 287 | basedir: __dirname + '/fixtures', 288 | browser: 'chromeapp' 289 | }, function(err, path, pkg) { 290 | assert.ifError(err); 291 | assert.equal(path, require.resolve('./fixtures/node_modules/alt-browser-field/chromeapp-direct')); 292 | assert.equal(pkg.main, './chromeapp.js'); 293 | done(); 294 | }); 295 | }); 296 | 297 | test('alt-browser fallback to "browser" on deps of deps', function(done) { 298 | var parent = { 299 | filename: fixtures_dir + '/alt-browser-field/foo.js', 300 | package: { main: './index.js' }, 301 | browser: 'chromeapp' 302 | }; 303 | 304 | resolve('foobar', parent, function(err, path, pkg) { 305 | assert.ifError(err); 306 | assert.equal(path, require.resolve('./fixtures/node_modules/module-k/browser')); 307 | assert.equal(pkg.main, './browser.js'); 308 | assert.equal(pkg.browser['./index.js'], './browser.js'); 309 | done(); 310 | }); 311 | }); 312 | 313 | test('not fail on accessing path name defined in Object.prototype', function (done) { 314 | resolve('toString', { paths: [ fixtures_dir ] }, function(err, path, pkg) { 315 | assert.ifError(err); 316 | assert.equal(path, require.resolve('./fixtures/node_modules/toString/index')); 317 | done(); 318 | }); 319 | }); 320 | 321 | test('respect symlinks', function (done) { 322 | // some systems (e.g. rush, pnpm) use symlinks to create a recursive dependency graph 323 | // instead of relying on the hoisting aspect of the node module resolution algorithm (like npm and yarn do) 324 | // in these cases, we want to resolve to the real path of a module, so that the tree structure below 325 | // only ever tries to run the `x` module once (rather than once on each module that depends on it) 326 | // 327 | // - node_modules 328 | // - a 329 | // - node_modules 330 | // - symlink to x 331 | // - b 332 | // - node_modules 333 | // - symlink to x 334 | // 335 | resolve('linked', { paths: [ fixtures_dir + '/linker/node_modules' ], preserveSymlinks: false }, function(err, path, pkg) { 336 | assert.ifError(err); 337 | assert.equal(path, require.resolve('./fixtures/linked/index')); 338 | done(); 339 | }); 340 | }); 341 | --------------------------------------------------------------------------------