react-scripts
Version:
Configuration and scripts for Create React App.
229 lines (166 loc) • 5.82 kB
JavaScript
/**
* 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;