UNPKG

6.21 kBJavaScriptView Raw
1// @remove-on-eject-begin
2/**
3 * Copyright (c) 2015-present, Facebook, Inc.
4 * All rights reserved.
5 *
6 * This source code is licensed under the BSD-style license found in the
7 * LICENSE file in the root directory of this source tree. An additional grant
8 * of patent rights can be found in the PATENTS file in the same directory.
9 */
10// @remove-on-eject-end
11
12var path = require('path');
13var fs = require('fs');
14var url = require('url');
15
16// Make sure any symlinks in the project folder are resolved:
17// https://github.com/facebookincubator/create-react-app/issues/637
18var appDirectory = fs.realpathSync(process.cwd());
19function resolveApp(relativePath) {
20 return path.resolve(appDirectory, relativePath);
21}
22
23function resolveAppIndex() {
24 var jsIndex = resolveApp('src/index.js');
25
26 if (fs.existsSync(jsIndex)) {
27 return jsIndex;
28 } else {
29 return resolveApp('src/index.tsx');
30 }
31}
32
33function resolveSetupTests() {
34 var jsIndex = resolveApp('src/setupTests.js');
35 var tsIndex = resolveApp('src/setupTests.ts');
36 var tsxIndex = resolveApp('src/setupTests.tsx');
37
38 if (fs.existsSync(tsxIndex)) {
39 return tsxIndex;
40 } else if (fs.existsSync(tsIndex)) {
41 return tsIndex;
42 } else {
43 return jsIndex;
44 }
45}
46
47// We support resolving modules according to `NODE_PATH`.
48// This lets you use absolute paths in imports inside large monorepos:
49// https://github.com/facebookincubator/create-react-app/issues/253.
50
51// It works similar to `NODE_PATH` in Node itself:
52// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
53
54// We will export `nodePaths` as an array of absolute paths.
55// It will then be used by Webpack configs.
56// Jest doesn’t need this because it already handles `NODE_PATH` out of the box.
57
58// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
59// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
60// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
61
62var nodePaths = (process.env.NODE_PATH || '')
63 .split(process.platform === 'win32' ? ';' : ':')
64 .filter(Boolean)
65 .filter(folder => !path.isAbsolute(folder))
66 .map(resolveApp);
67
68var envPublicUrl = process.env.PUBLIC_URL;
69
70function ensureSlash(path, needsSlash) {
71 var hasSlash = path.endsWith('/');
72 if (hasSlash && !needsSlash) {
73 return path.substr(path, path.length - 1);
74 } else if (!hasSlash && needsSlash) {
75 return path + '/';
76 } else {
77 return path;
78 }
79}
80
81function getPublicUrl(appPackageJson) {
82 return envPublicUrl || require(appPackageJson).homepage;
83}
84
85// We use `PUBLIC_URL` environment variable or "homepage" field to infer
86// "public path" at which the app is served.
87// Webpack needs to know it to put the right <script> hrefs into HTML even in
88// single-page apps that may serve index.html for nested URLs like /todos/42.
89// We can't use a relative path in HTML because we don't want to load something
90// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
91function getServedPath(appPackageJson) {
92 var publicUrl = getPublicUrl(appPackageJson);
93 var servedUrl = envPublicUrl || (
94 publicUrl ? url.parse(publicUrl).pathname : '/'
95 );
96 return ensureSlash(servedUrl, true);
97}
98
99// config after eject: we're in ./config/
100module.exports = {
101 appBuild: resolveApp('build'),
102 appPublic: resolveApp('public'),
103 appHtml: resolveApp('public/index.html'),
104 appIndexJs: resolveAppIndex(),
105 appPackageJson: resolveApp('package.json'),
106 appSrc: resolveApp('src'),
107 yarnLockFile: resolveApp('yarn.lock'),
108 testsSetup: resolveSetupTests(),
109 appNodeModules: resolveApp('node_modules'),
110 ownNodeModules: resolveApp('node_modules'),
111 nodePaths: nodePaths,
112 publicUrl: getPublicUrl(resolveApp('package.json')),
113 servedPath: getServedPath(resolveApp('package.json')),
114 appTsconfigJson: resolveApp('tsconfig.json')
115};
116
117// @remove-on-eject-begin
118function resolveOwn(relativePath) {
119 return path.resolve(__dirname, relativePath);
120}
121
122function resolveOwnAppIndex() {
123 var jsIndex = resolveOwn('../template/src/index.js');
124
125 if (fs.existsSync(jsIndex)) {
126 return jsIndex;
127 } else {
128 return resolveOwn('../template/src/index.tsx');
129 }
130}
131
132function resolveOwnSetupTests() {
133 var jsIndex = resolveOwn('../template/src/setupTests.js');
134 var tsIndex = resolveOwn('../template/src/setupTests.ts');
135 var tsxIndex = resolveOwn('../template/src/setupTests.tsx');
136
137 if (fs.existsSync(tsxIndex)) {
138 return tsxIndex;
139 } else if (fs.existsSync(tsIndex)) {
140 return tsIndex;
141 } else {
142 return jsIndex;
143 }
144}
145
146// config before eject: we're in ./node_modules/react-scripts/config/
147module.exports = {
148 appBuild: resolveApp('build'),
149 appPublic: resolveApp('public'),
150 appHtml: resolveApp('public/index.html'),
151 appIndexJs: resolveAppIndex(),
152 appPackageJson: resolveApp('package.json'),
153 appSrc: resolveApp('src'),
154 yarnLockFile: resolveApp('yarn.lock'),
155 testsSetup: resolveSetupTests(),
156 appNodeModules: resolveApp('node_modules'),
157 // this is empty with npm3 but node resolution searches higher anyway:
158 ownNodeModules: resolveOwn('../node_modules'),
159 nodePaths: nodePaths,
160 publicUrl: getPublicUrl(resolveApp('package.json')),
161 servedPath: getServedPath(resolveApp('package.json')),
162 appTsconfigJson: resolveApp('tsconfig.json')
163};
164
165// config before publish: we're in ./packages/react-scripts/config/
166if (__dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1) {
167 module.exports = {
168 appBuild: resolveOwn('../../../build'),
169 appPublic: resolveOwn('../template/public'),
170 appHtml: resolveOwn('../template/public/index.html'),
171 appIndexJs: resolveOwnAppIndex(),
172 appPackageJson: resolveOwn('../package.json'),
173 appSrc: resolveOwn('../template/src'),
174 yarnLockFile: resolveOwn('../template/yarn.lock'),
175 testsSetup: resolveOwnSetupTests(),
176 appNodeModules: resolveOwn('../node_modules'),
177 ownNodeModules: resolveOwn('../node_modules'),
178 nodePaths: nodePaths,
179 publicUrl: getPublicUrl(resolveOwn('../package.json')),
180 servedPath: getServedPath(resolveOwn('../package.json')),
181 appTsconfigJson: resolveOwn('../template/tsconfig.json')
182 };
183}
184// @remove-on-eject-end