UNPKG

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