modules.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // @remove-on-eject-begin
  2. /**
  3. * Copyright (c) 2015-present, Facebook, Inc.
  4. *
  5. * This source code is licensed under the MIT license found in the
  6. * LICENSE file in the root directory of this source tree.
  7. */
  8. // @remove-on-eject-end
  9. 'use strict';
  10. const fs = require('fs');
  11. const path = require('path');
  12. const paths = require('./paths');
  13. const chalk = require('react-dev-utils/chalk');
  14. const resolve = require('resolve');
  15. /**
  16. * Get additional module paths based on the baseUrl of a compilerOptions object.
  17. *
  18. * @param {Object} options
  19. */
  20. function getAdditionalModulePaths(options = {}) {
  21. const baseUrl = options.baseUrl;
  22. if (!baseUrl) {
  23. return '';
  24. }
  25. const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
  26. // We don't need to do anything if `baseUrl` is set to `node_modules`. This is
  27. // the default behavior.
  28. if (path.relative(paths.appNodeModules, baseUrlResolved) === '') {
  29. return null;
  30. }
  31. // Allow the user set the `baseUrl` to `appSrc`.
  32. if (path.relative(paths.appSrc, baseUrlResolved) === '') {
  33. return [paths.appSrc];
  34. }
  35. // If the path is equal to the root directory we ignore it here.
  36. // We don't want to allow importing from the root directly as source files are
  37. // not transpiled outside of `src`. We do allow importing them with the
  38. // absolute path (e.g. `src/Components/Button.js`) but we set that up with
  39. // an alias.
  40. if (path.relative(paths.appPath, baseUrlResolved) === '') {
  41. return null;
  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. * Get webpack aliases based on the baseUrl of a compilerOptions object.
  53. *
  54. * @param {*} options
  55. */
  56. function getWebpackAliases(options = {}) {
  57. const baseUrl = options.baseUrl;
  58. if (!baseUrl) {
  59. return {};
  60. }
  61. const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
  62. if (path.relative(paths.appPath, baseUrlResolved) === '') {
  63. return {
  64. src: paths.appSrc,
  65. };
  66. }
  67. }
  68. /**
  69. * Get jest aliases based on the baseUrl of a compilerOptions object.
  70. *
  71. * @param {*} options
  72. */
  73. function getJestAliases(options = {}) {
  74. const baseUrl = options.baseUrl;
  75. if (!baseUrl) {
  76. return {};
  77. }
  78. const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
  79. if (path.relative(paths.appPath, baseUrlResolved) === '') {
  80. return {
  81. '^src/(.*)$': '<rootDir>/src/$1',
  82. };
  83. }
  84. }
  85. function getModules() {
  86. // Check if TypeScript is setup
  87. const hasTsConfig = fs.existsSync(paths.appTsConfig);
  88. const hasJsConfig = fs.existsSync(paths.appJsConfig);
  89. if (hasTsConfig && hasJsConfig) {
  90. throw new Error(
  91. 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.'
  92. );
  93. }
  94. let config;
  95. // If there's a tsconfig.json we assume it's a
  96. // TypeScript project and set up the config
  97. // based on tsconfig.json
  98. if (hasTsConfig) {
  99. const ts = require(resolve.sync('typescript', {
  100. basedir: paths.appNodeModules,
  101. }));
  102. config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config;
  103. // Otherwise we'll check if there is jsconfig.json
  104. // for non TS projects.
  105. } else if (hasJsConfig) {
  106. config = require(paths.appJsConfig);
  107. }
  108. config = config || {};
  109. const options = config.compilerOptions || {};
  110. const additionalModulePaths = getAdditionalModulePaths(options);
  111. return {
  112. additionalModulePaths: additionalModulePaths,
  113. webpackAliases: getWebpackAliases(options),
  114. jestAliases: getJestAliases(options),
  115. hasTsConfig,
  116. };
  117. }
  118. module.exports = getModules();