UNPKG

react-scripts

Version:
229 lines (166 loc) 5.82 kB
/** * Copyright (c) 2014, Facebook, Inc. All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * */ 'use strict'; const nodeModulesPaths = require('resolve/lib/node-modules-paths'); const path = require('path'); const resolve = require('resolve'); const browserResolve = require('browser-resolve'); const NATIVE_PLATFORM = 'native'; const nodePaths = process.env.NODE_PATH ? process.env.NODE_PATH.split(path.delimiter) : null; class Resolver { constructor(moduleMap, options) { this._options = { browser: options.browser, defaultPlatform: options.defaultPlatform, extensions: options.extensions, hasCoreModules: options.hasCoreModules === undefined ? true : options.hasCoreModules, moduleDirectories: options.moduleDirectories || ['node_modules'], moduleNameMapper: options.moduleNameMapper, modulePaths: options.modulePaths, platforms: options.platforms }; this._moduleMap = moduleMap; this._moduleNameCache = Object.create(null); this._modulePathCache = Object.create(null); } static findNodeModule(path, options) { const paths = options.paths; try { const resv = options.browser ? browserResolve : resolve; return resv.sync( path, { basedir: options.basedir, extensions: options.extensions, moduleDirectory: options.moduleDirectory, paths: paths ? (nodePaths || []).concat(paths) : nodePaths }); } catch (e) {} return null; } resolveModule( from, moduleName, options) { const dirname = path.dirname(from); const paths = this._options.modulePaths; const extensions = this._options.extensions; const moduleDirectory = this._options.moduleDirectories; const key = dirname + path.delimiter + moduleName; // 0. If we have already resolved this module for this directory name, // return a value from the cache. if (this._moduleNameCache[key]) { return this._moduleNameCache[key]; } // 1. Check if the module is a haste module. let module = this.getModule(moduleName); if (module) { return this._moduleNameCache[key] = module; } // 2. Check if the module is a node module and resolve it based on // the node module resolution algorithm. if (!options || !options.skipNodeResolution) { module = Resolver.findNodeModule(moduleName, { basedir: dirname, browser: this._options.browser, extensions, moduleDirectory, paths }); if (module) { return this._moduleNameCache[key] = module; } } // 3. Resolve "haste packages" which are `package.json` files outside of // `node_modules` folders anywhere in the file system. const parts = moduleName.split('/'); module = this.getPackage(parts.shift()); if (module) { try { return this._moduleNameCache[key] = require.resolve( path.join.apply(path, [path.dirname(module)].concat(parts))); } catch (ignoredError) {} } // 4. Throw an error if the module could not be found. `resolve.sync` // only produces an error based on the dirname but we have the actual // current module name available. const relativePath = path.relative(dirname, from); const err = new Error( `Cannot find module '${ moduleName }' from '${ relativePath || '.' }'`); err.code = 'MODULE_NOT_FOUND'; throw err; } isCoreModule(moduleName) { return this._options.hasCoreModules && resolve.isCore(moduleName); } getModule(name) { return this._moduleMap.getModule( name, this._options.defaultPlatform, this._supportsNativePlatform()); } getPackage(name) { return this._moduleMap.getPackage( name, this._options.defaultPlatform, this._supportsNativePlatform()); } getMockModule(from, name) { const mock = this._moduleMap.getMockModule(name); if (mock) { return mock; } else { const moduleName = this._resolveStubModuleName(from, name); if (moduleName) { return this.getModule(moduleName) || moduleName; } } return null; } getModulePaths(from) { if (!this._modulePathCache[from]) { const moduleDirectory = this._options.moduleDirectories; const paths = nodeModulesPaths(from, { moduleDirectory }); if (paths[paths.length - 1] === undefined) { // circumvent node-resolve bug that adds `undefined` as last item. paths.pop(); } this._modulePathCache[from] = paths; } return this._modulePathCache[from]; } _resolveStubModuleName(from, moduleName) { const dirname = path.dirname(from); const paths = this._options.modulePaths; const extensions = this._options.extensions; const moduleDirectory = this._options.moduleDirectories; const moduleNameMapper = this._options.moduleNameMapper; if (moduleNameMapper) { for (const mappedModuleName in moduleNameMapper) { const regex = moduleNameMapper[mappedModuleName]; if (regex.test(moduleName)) { moduleName = moduleName.replace(regex, mappedModuleName); return this.getModule(moduleName) || Resolver.findNodeModule( moduleName, { basedir: dirname, browser: this._options.browser, extensions, moduleDirectory, paths }); } } } return null; } _supportsNativePlatform() { return (this._options.platforms || []).indexOf(NATIVE_PLATFORM) !== -1; }} module.exports = Resolver;