Skip to content

Commit e7a2d61

Browse files
robertvansteeniansumrmckebJack Zhao
committed
Set baseUrl from jsconfig.json/tsconfig.json (#6656)
* Set baseUrl from jsconfig.json/tsconfig.json * Resolve the path for loading modules * Add tests for jsconfig.json * Add jsconfig.json * Update packages/react-scripts/scripts/start.js * Move baseUrl test to config folder * Remove alias test * Use chalk from react-dev-utils * Add lost absolute file for typescript baseUrl test * Update packages/react-scripts/config/modules.js * Update other references of useTypeScript to hasTsConfig * Fix casing of TypeScript * Keep respecting NODE_PATH for now to support multiple module paths. * Add test for NODE_PATH * Add fallback if NODE_PATH is not set. * Fix node path behavior tests * Remove debugging code from behavior test suite * Remove more debugging code * Show NODE_PATH deprecation warning during build Co-authored-by: Ian Sutherland <[email protected]> Co-authored-by: Brody McKee <[email protected]> Co-authored-by: Jack Zhao <[email protected]>
1 parent ced3fd4 commit e7a2d61

File tree

29 files changed

+290
-28
lines changed

29 files changed

+290
-28
lines changed

docusaurus/docs/deployment.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ The AWS Amplify Console provides continuous deployment and hosting for modern we
167167
1. Login to the Amplify Console [here](https://console.aws.amazon.com/amplify/home).
168168
1. Connect your Create React App repo and pick a branch. If you're looking for a Create React App+Amplify starter, try the [create-react-app-auth-amplify starter](https://github.com/swaminator/create-react-app-auth-amplify) that demonstrates setting up auth in 10 minutes with Create React App.
169169
1. The Amplify Console automatically detects the build settings. Choose Next.
170-
1. Choose *Save and deploy*.
170+
1. Choose _Save and deploy_.
171171

172-
If the build succeeds, the app is deployed and hosted on a global CDN with an amplifyapp.com domain. You can now continuously deploy changes to your frontend or backend. Continuous deployment allows developers to deploy updates to their frontend and backend on every code commit to their Git repository.
172+
If the build succeeds, the app is deployed and hosted on a global CDN with an amplifyapp.com domain. You can now continuously deploy changes to your frontend or backend. Continuous deployment allows developers to deploy updates to their frontend and backend on every code commit to their Git repository.
173173

174174
## [Azure](https://azure.microsoft.com/)
175175

docusaurus/docs/getting-started.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ yarn create react-app my-app
6262

6363
_`yarn create` is available in Yarn 0.25+_
6464

65-
6665
### Creating a TypeScript app
6766

6867
Follow our [Adding TypeScript](adding-typescript.md) documentation to create a TypeScript app.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
11+
const fs = require('fs');
12+
const path = require('path');
13+
const paths = require('./paths');
14+
const chalk = require('react-dev-utils/chalk');
15+
16+
/**
17+
* Get the baseUrl of a compilerOptions object.
18+
*
19+
* @param {Object} options
20+
*/
21+
function getAdditionalModulePaths(options = {}) {
22+
const baseUrl = options.baseUrl;
23+
24+
// We need to explicitly check for null and undefined (and not a falsy value) because
25+
// TypeScript treats an empty string as `.`.
26+
if (baseUrl == null) {
27+
// If there's no baseUrl set we respect NODE_PATH
28+
// Note that NODE_PATH is deprecated and will be removed
29+
// in the next major release of create-react-app.
30+
31+
const nodePath = process.env.NODE_PATH || '';
32+
return nodePath.split(path.delimiter).filter(Boolean);
33+
}
34+
35+
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
36+
37+
// We don't need to do anything if `baseUrl` is set to `node_modules`. This is
38+
// the default behavior.
39+
if (path.relative(paths.appNodeModules, baseUrlResolved) === '') {
40+
return null;
41+
}
42+
43+
// Allow the user set the `baseUrl` to `appSrc`.
44+
if (path.relative(paths.appSrc, baseUrlResolved) === '') {
45+
return [paths.appSrc];
46+
}
47+
48+
// Otherwise, throw an error.
49+
throw new Error(
50+
chalk.red.bold(
51+
"Your project's `baseUrl` can only be set to `src` or `node_modules`." +
52+
' Create React App does not support other values at this time.'
53+
)
54+
);
55+
}
56+
57+
function getModules() {
58+
// Check if TypeScript is setup
59+
const hasTsConfig = fs.existsSync(paths.appTsConfig);
60+
const hasJsConfig = fs.existsSync(paths.appJsConfig);
61+
62+
if (hasTsConfig && hasJsConfig) {
63+
throw new Error(
64+
'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.'
65+
);
66+
}
67+
68+
let config;
69+
70+
// If there's a tsconfig.json we assume it's a
71+
// TypeScript project and set up the config
72+
// based on tsconfig.json
73+
if (hasTsConfig) {
74+
config = require(paths.appTsConfig);
75+
// Otherwise we'll check if there is jsconfig.json
76+
// for non TS projects.
77+
} else if (hasJsConfig) {
78+
config = require(paths.appJsConfig);
79+
}
80+
81+
config = config || {};
82+
const options = config.compilerOptions || {};
83+
84+
const additionalModulePaths = getAdditionalModulePaths(options);
85+
86+
return {
87+
additionalModulePaths: additionalModulePaths,
88+
hasTsConfig,
89+
};
90+
}
91+
92+
module.exports = getModules();

packages/react-scripts/config/paths.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ module.exports = {
8484
appPackageJson: resolveApp('package.json'),
8585
appSrc: resolveApp('src'),
8686
appTsConfig: resolveApp('tsconfig.json'),
87+
appJsConfig: resolveApp('jsconfig.json'),
8788
yarnLockFile: resolveApp('yarn.lock'),
8889
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
8990
proxySetup: resolveApp('src/setupProxy.js'),
@@ -106,6 +107,7 @@ module.exports = {
106107
appPackageJson: resolveApp('package.json'),
107108
appSrc: resolveApp('src'),
108109
appTsConfig: resolveApp('tsconfig.json'),
110+
appJsConfig: resolveApp('jsconfig.json'),
109111
yarnLockFile: resolveApp('yarn.lock'),
110112
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
111113
proxySetup: resolveApp('src/setupProxy.js'),
@@ -140,6 +142,7 @@ if (
140142
appPackageJson: resolveOwn('package.json'),
141143
appSrc: resolveOwn('template/src'),
142144
appTsConfig: resolveOwn('template/tsconfig.json'),
145+
appJsConfig: resolveOwn('template/jsconfig.json'),
143146
yarnLockFile: resolveOwn('template/yarn.lock'),
144147
testsSetup: resolveModule(resolveOwn, 'template/src/setupTests'),
145148
proxySetup: resolveOwn('template/src/setupProxy.js'),

packages/react-scripts/config/webpack.config.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeM
2828
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
2929
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
3030
const paths = require('./paths');
31+
const modules = require('./modules');
3132
const getClientEnvironment = require('./env');
3233
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
3334
const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
@@ -268,10 +269,7 @@ module.exports = function(webpackEnv) {
268269
// We placed these paths second because we want `node_modules` to "win"
269270
// if there are any conflicts. This matches Node resolution mechanism.
270271
// https://github.com/facebook/create-react-app/issues/253
271-
modules: ['node_modules', paths.appNodeModules].concat(
272-
// It is guaranteed to exist because we tweak it in `env.js`
273-
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
274-
),
272+
modules: ['node_modules', paths.appNodeModules].concat(modules.additionalModulePaths || []),
275273
// These are the reasonable defaults supported by the Node ecosystem.
276274
// We also include JSX as a common component filename extension to support
277275
// some tools, although we do not recommend using it, see:
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import initDOM from './initDOM';
9+
10+
describe('Integration', () => {
11+
describe('jsconfig.json/tsconfig.json', () => {
12+
it('Supports setting baseUrl to src', async () => {
13+
const doc = await initDOM('base-url');
14+
15+
expect(doc.getElementById('feature-base-url').childElementCount).toBe(4);
16+
doc.defaultView.close();
17+
});
18+
});
19+
});

packages/react-scripts/fixtures/kitchensink/integration/env.test.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@ describe('Integration', () => {
4343
}
4444
});
4545

46-
it('NODE_PATH', async () => {
47-
doc = await initDOM('node-path');
48-
49-
expect(doc.getElementById('feature-node-path').childElementCount).toBe(4);
50-
});
51-
5246
it('PUBLIC_URL', async () => {
5347
doc = await initDOM('public-url');
5448

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": "src"
4+
}
5+
}

packages/react-scripts/fixtures/kitchensink/src/App.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,6 @@ class App extends Component {
166166
this.setFeature(f.default)
167167
);
168168
break;
169-
case 'node-path':
170-
import('./features/env/NodePath').then(f => this.setFeature(f.default));
171-
break;
172169
case 'no-ext-inclusion':
173170
import('./features/webpack/NoExtInclusion').then(f =>
174171
this.setFeature(f.default)
@@ -239,6 +236,11 @@ class App extends Component {
239236
this.setFeature(f.default)
240237
);
241238
break;
239+
case 'base-url':
240+
import('./features/config/BaseUrl').then(f =>
241+
this.setFeature(f.default)
242+
);
243+
break;
242244
default:
243245
this.setState({ error: `Missing feature "${feature}"` });
244246
}

packages/react-scripts/fixtures/kitchensink/src/features/env/NodePath.js renamed to packages/react-scripts/fixtures/kitchensink/src/features/config/BaseUrl.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default class extends Component {
3030

3131
render() {
3232
return (
33-
<div id="feature-node-path">
33+
<div id="feature-base-url">
3434
{this.state.users.map(user => (
3535
<div key={user.id}>{user.name}</div>
3636
))}

0 commit comments

Comments
 (0)