1. 'use strict';
    
  2. 
    
  3. const fs = require('fs');
    
  4. const path = require('path');
    
  5. const paths = require('./paths');
    
  6. const chalk = require('chalk');
    
  7. const resolve = require('resolve');
    
  8. 
    
  9. /**
    
  10.  * Get additional module paths based on the baseUrl of a compilerOptions object.
    
  11.  *
    
  12.  * @param {Object} options
    
  13.  */
    
  14. function getAdditionalModulePaths(options = {}) {
    
  15.   const baseUrl = options.baseUrl;
    
  16. 
    
  17.   if (!baseUrl) {
    
  18.     return '';
    
  19.   }
    
  20. 
    
  21.   const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
    
  22. 
    
  23.   // We don't need to do anything if `baseUrl` is set to `node_modules`. This is
    
  24.   // the default behavior.
    
  25.   if (path.relative(paths.appNodeModules, baseUrlResolved) === '') {
    
  26.     return null;
    
  27.   }
    
  28. 
    
  29.   // Allow the user set the `baseUrl` to `appSrc`.
    
  30.   if (path.relative(paths.appSrc, baseUrlResolved) === '') {
    
  31.     return [paths.appSrc];
    
  32.   }
    
  33. 
    
  34.   // If the path is equal to the root directory we ignore it here.
    
  35.   // We don't want to allow importing from the root directly as source files are
    
  36.   // not transpiled outside of `src`. We do allow importing them with the
    
  37.   // absolute path (e.g. `src/Components/Button.js`) but we set that up with
    
  38.   // an alias.
    
  39.   if (path.relative(paths.appPath, baseUrlResolved) === '') {
    
  40.     return null;
    
  41.   }
    
  42. 
    
  43.   // Otherwise, throw an error.
    
  44.   throw new Error(
    
  45.     chalk.red.bold(
    
  46.       "Your project's `baseUrl` can only be set to `src` or `node_modules`." +
    
  47.         ' Create React App does not support other values at this time.'
    
  48.     )
    
  49.   );
    
  50. }
    
  51. 
    
  52. /**
    
  53.  * Get webpack aliases based on the baseUrl of a compilerOptions object.
    
  54.  *
    
  55.  * @param {*} options
    
  56.  */
    
  57. function getWebpackAliases(options = {}) {
    
  58.   const baseUrl = options.baseUrl;
    
  59. 
    
  60.   if (!baseUrl) {
    
  61.     return {};
    
  62.   }
    
  63. 
    
  64.   const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
    
  65. 
    
  66.   if (path.relative(paths.appPath, baseUrlResolved) === '') {
    
  67.     return {
    
  68.       src: paths.appSrc,
    
  69.     };
    
  70.   }
    
  71. }
    
  72. 
    
  73. /**
    
  74.  * Get jest aliases based on the baseUrl of a compilerOptions object.
    
  75.  *
    
  76.  * @param {*} options
    
  77.  */
    
  78. function getJestAliases(options = {}) {
    
  79.   const baseUrl = options.baseUrl;
    
  80. 
    
  81.   if (!baseUrl) {
    
  82.     return {};
    
  83.   }
    
  84. 
    
  85.   const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
    
  86. 
    
  87.   if (path.relative(paths.appPath, baseUrlResolved) === '') {
    
  88.     return {
    
  89.       '^src/(.*)$': '<rootDir>/src/$1',
    
  90.     };
    
  91.   }
    
  92. }
    
  93. 
    
  94. function getModules() {
    
  95.   // Check if TypeScript is setup
    
  96.   const hasTsConfig = fs.existsSync(paths.appTsConfig);
    
  97.   const hasJsConfig = fs.existsSync(paths.appJsConfig);
    
  98. 
    
  99.   if (hasTsConfig && hasJsConfig) {
    
  100.     throw new Error(
    
  101.       'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.'
    
  102.     );
    
  103.   }
    
  104. 
    
  105.   let config;
    
  106. 
    
  107.   // If there's a tsconfig.json we assume it's a
    
  108.   // TypeScript project and set up the config
    
  109.   // based on tsconfig.json
    
  110.   if (hasTsConfig) {
    
  111.     const ts = require(
    
  112.       resolve.sync('typescript', {
    
  113.         basedir: paths.appNodeModules,
    
  114.       })
    
  115.     );
    
  116.     config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config;
    
  117.     // Otherwise we'll check if there is jsconfig.json
    
  118.     // for non TS projects.
    
  119.   } else if (hasJsConfig) {
    
  120.     config = require(paths.appJsConfig);
    
  121.   }
    
  122. 
    
  123.   config = config || {};
    
  124.   const options = config.compilerOptions || {};
    
  125. 
    
  126.   const additionalModulePaths = getAdditionalModulePaths(options);
    
  127. 
    
  128.   return {
    
  129.     additionalModulePaths: additionalModulePaths,
    
  130.     webpackAliases: getWebpackAliases(options),
    
  131.     jestAliases: getJestAliases(options),
    
  132.     hasTsConfig,
    
  133.   };
    
  134. }
    
  135. 
    
  136. module.exports = getModules();