Skip to content

Commit d87a148

Browse files
merge master
2 parents da1e331 + 4c0bf03 commit d87a148

36 files changed

+803
-693
lines changed

.travis.yml

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
---
2-
# Use Ubuntu Precise instead of new default Trusty which cause build fail
3-
# with pre installed yarn v0.17.8
4-
# https://github.com/facebookincubator/create-react-app/issues/3054
5-
# TODO: remove after Trusty environment is updated with a lastet version of yarn
6-
dist: precise
2+
dist: trusty
73
language: node_js
84
node_js:
95
- 6
@@ -18,18 +14,13 @@ script:
1814
- 'if [ $TEST_SUITE = "simple" ]; then tasks/e2e-simple.sh; fi'
1915
- 'if [ $TEST_SUITE = "installs" ]; then tasks/e2e-installs.sh; fi'
2016
- 'if [ $TEST_SUITE = "kitchensink" ]; then tasks/e2e-kitchensink.sh; fi'
17+
- 'if [ $TEST_SUITE = "old-node" ]; then tasks/e2e-old-node.sh; fi'
2118
env:
22-
global:
23-
- USE_YARN=no
2419
matrix:
2520
- TEST_SUITE=simple
2621
- TEST_SUITE=installs
2722
- TEST_SUITE=kitchensink
2823
matrix:
2924
include:
3025
- node_js: 0.10
31-
env: TEST_SUITE=simple
32-
# There's a weird Yarn/Lerna bug related to prerelease versions.
33-
# TODO: reenable after we ship 1.0.
34-
# - node_js: 6
35-
# env: USE_YARN=yes TEST_SUITE=simple
26+
env: TEST_SUITE=old-node

CONTRIBUTING.md

+15
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,21 @@ and then run `npm start` or `npm run build`.
9696

9797
More detailed information are in the dedicated [README](/packages/react-scripts/fixtures/kitchensink/README.md).
9898

99+
## Tips for contributors using Windows
100+
101+
The scripts in tasks folder and other scripts in `package.json` will not work in Windows out of the box. However, using [Bash on windows](https://msdn.microsoft.com/en-us/commandline/wsl/about) makes it easier to use those scripts without any workarounds. The steps to do so are detailed below:
102+
103+
### Install Bash on Ubuntu on Windows
104+
105+
A good step by step guide can be found [here](https://www.howtogeek.com/249966/how-to-install-and-use-the-linux-bash-shell-on-windows-10/)
106+
107+
### Install Node.js and npm
108+
Even if you have node and npm installed on your windows, it would not be accessible from the bash shell. You would have to install it again. Installing via [`nvm`](https://github.com/creationix/nvm#install-script) is recommended.
109+
110+
### Line endings
111+
112+
By default git would use `CRLF` line endings which would cause the scripts to fail. You can change it for this repo only by setting `autocrlf` to false by running `git config core.autocrlf false`. You can also enable it for all your repos by using the `--global` flag if you wish to do so.
113+
99114
## Cutting a Release
100115

101116
1. Tag all merged pull requests that go into the release with the relevant milestone. Each merged PR should also be labeled with one of the [labels](https://github.com/facebookincubator/create-react-app/labels) named `tag: ...` to indicate what kind of change it is.

README.md

+46-82
Large diffs are not rendered by default.

package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
"scripts": {
44
"build": "node packages/react-scripts/scripts/build.js",
55
"changelog": "lerna-changelog",
6-
"create-react-app": "tasks/cra.sh",
6+
"create-react-app": "node tasks/cra.js",
77
"e2e": "tasks/e2e-simple.sh",
88
"e2e:docker": "tasks/local-test.sh",
99
"postinstall": "node bootstrap.js && cd packages/react-error-overlay/ && npm run build:prod",
1010
"publish": "tasks/release.sh",
1111
"start": "node packages/react-scripts/scripts/start.js",
12+
"screencast": "svg-term --cast hItN7sl5yfCPTHxvFg5glhhfp --out screencast.svg --window",
1213
"test": "node packages/react-scripts/scripts/test.js --env=jsdom",
1314
"format": "prettier --trailing-comma es5 --single-quote --write 'packages/*/*.js' 'packages/*/!(node_modules)/**/*.js'",
1415
"precommit": "lint-staged"
@@ -19,7 +20,8 @@
1920
"lerna": "^2.0.0",
2021
"lerna-changelog": "^0.6.0",
2122
"lint-staged": "^3.3.1",
22-
"prettier": "1.6.1"
23+
"prettier": "1.6.1",
24+
"svg-term-cli": "^2.0.3"
2325
},
2426
"lint-staged": {
2527
"*.js": [

packages/babel-preset-react-app/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ If you want to use this Babel preset in a project not built with Create React Ap
1616

1717
First, [install Babel](https://babeljs.io/docs/setup/).
1818

19+
Then install babel-preset-react-app.
20+
21+
```sh
22+
npm install babel-preset-react-app --save-dev
23+
```
24+
1925
Then create a file named `.babelrc` with following contents in the root folder of your project:
2026

2127
```js

packages/create-react-app/createReactApp.js

+55-6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const tmp = require('tmp');
4747
const unpack = require('tar-pack').unpack;
4848
const url = require('url');
4949
const hyperquest = require('hyperquest');
50+
const envinfo = require('envinfo');
5051

5152
const packageJson = require('./package.json');
5253

@@ -60,6 +61,7 @@ const program = new commander.Command(packageJson.name)
6061
projectName = name;
6162
})
6263
.option('--verbose', 'print additional logs')
64+
.option('--info', 'print environment debug info')
6365
.option(
6466
'--scripts-version <alternative-package>',
6567
'use a non-standard version of react-scripts'
@@ -83,6 +85,11 @@ const program = new commander.Command(packageJson.name)
8385
'https://mysite.com/my-react-scripts-0.8.2.tgz'
8486
)}`
8587
);
88+
console.log(
89+
` - a .tar.gz archive: ${chalk.green(
90+
'https://mysite.com/my-react-scripts-0.8.2.tar.gz'
91+
)}`
92+
);
8693
console.log(
8794
` It is not needed unless you specifically want to use a fork.`
8895
);
@@ -100,6 +107,14 @@ const program = new commander.Command(packageJson.name)
100107
.parse(process.argv);
101108

102109
if (typeof projectName === 'undefined') {
110+
if (program.info) {
111+
envinfo.print({
112+
packages: ['react', 'react-dom', 'react-scripts'],
113+
noNativeIDE: true,
114+
duplicates: true,
115+
});
116+
process.exit(0);
117+
}
103118
console.error('Please specify the project directory:');
104119
console.log(
105120
` ${chalk.cyan(program.name())} ${chalk.green('<project-directory>')}`
@@ -268,7 +283,7 @@ function run(
268283
template,
269284
useYarn
270285
) {
271-
const packageToInstall = getInstallPackage(version);
286+
const packageToInstall = getInstallPackage(version, originalDirectory);
272287
const allDependencies = ['react', 'react-dom', packageToInstall];
273288

274289
console.log('Installing packages. This might take a couple of minutes.');
@@ -365,11 +380,16 @@ function run(
365380
});
366381
}
367382

368-
function getInstallPackage(version) {
383+
function getInstallPackage(version, originalDirectory) {
369384
let packageToInstall = 'react-scripts';
370385
const validSemver = semver.valid(version);
371386
if (validSemver) {
372387
packageToInstall += `@${validSemver}`;
388+
} else if (version && version.match(/^file:/)) {
389+
packageToInstall = `file:${path.resolve(
390+
originalDirectory,
391+
version.match(/^file:(.*)?$/)[1]
392+
)}`;
373393
} else if (version) {
374394
// for tar.gz or alternative paths
375395
packageToInstall = version;
@@ -417,7 +437,7 @@ function extractStream(stream, dest) {
417437

418438
// Extract package name from tarball url or path.
419439
function getPackageName(installPackage) {
420-
if (installPackage.indexOf('.tgz') > -1) {
440+
if (installPackage.match(/^.+\.(tgz|tar\.gz)$/)) {
421441
return getTemporaryDirectory()
422442
.then(obj => {
423443
let stream;
@@ -440,7 +460,7 @@ function getPackageName(installPackage) {
440460
`Could not extract the package name from the archive: ${err.message}`
441461
);
442462
const assumedProjectName = installPackage.match(
443-
/^.+\/(.+?)(?:-\d+.+)?\.tgz$/
463+
/^.+\/(.+?)(?:-\d+.+)?\.(tgz|tar\.gz)$/
444464
)[1];
445465
console.log(
446466
`Based on the filename, assuming it is "${chalk.cyan(
@@ -459,6 +479,13 @@ function getPackageName(installPackage) {
459479
return Promise.resolve(
460480
installPackage.charAt(0) + installPackage.substr(1).split('@')[0]
461481
);
482+
} else if (installPackage.match(/^file:/)) {
483+
const installPackagePath = installPackage.match(/^file:(.*)?$/)[1];
484+
const installPackageJson = require(path.join(
485+
installPackagePath,
486+
'package.json'
487+
));
488+
return Promise.resolve(installPackageJson.name);
462489
}
463490
return Promise.resolve(installPackage);
464491
}
@@ -595,6 +622,12 @@ function isSafeToCreateProjectIn(root, name) {
595622
'.hg',
596623
'.hgignore',
597624
'.hgcheck',
625+
'.npmignore',
626+
'mkdocs.yml',
627+
'docs',
628+
'.travis.yml',
629+
'.gitlab-ci.yml',
630+
'.gitattributes',
598631
];
599632
console.log();
600633

@@ -620,6 +653,21 @@ function isSafeToCreateProjectIn(root, name) {
620653
return false;
621654
}
622655

656+
function getProxy() {
657+
if (process.env.https_proxy) {
658+
return process.env.https_proxy;
659+
} else {
660+
try {
661+
// Trying to read https-proxy from .npmrc
662+
let httpsProxy = execSync('npm config get https-proxy')
663+
.toString()
664+
.trim();
665+
return httpsProxy !== 'null' ? httpsProxy : undefined;
666+
} catch (e) {
667+
return;
668+
}
669+
}
670+
}
623671
function checkThatNpmCanReadCwd() {
624672
const cwd = process.cwd();
625673
let childOutput = null;
@@ -690,10 +738,11 @@ function checkIfOnline(useYarn) {
690738

691739
return new Promise(resolve => {
692740
dns.lookup('registry.yarnpkg.com', err => {
693-
if (err != null && process.env.https_proxy) {
741+
let proxy;
742+
if (err != null && (proxy = getProxy())) {
694743
// If a proxy is defined, we likely can't resolve external hostnames.
695744
// Try to resolve the proxy name as an indication of a connection.
696-
dns.lookup(url.parse(process.env.https_proxy).hostname, proxyErr => {
745+
dns.lookup(url.parse(proxy).hostname, proxyErr => {
697746
resolve(proxyErr == null);
698747
});
699748
} else {

packages/create-react-app/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"chalk": "^1.1.1",
2525
"commander": "^2.9.0",
2626
"cross-spawn": "^4.0.0",
27+
"envinfo": "^3.8.0",
2728
"fs-extra": "^1.0.0",
2829
"hyperquest": "^2.1.2",
2930
"semver": "^5.0.3",

packages/eslint-config-react-app/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ module.exports = {
116116
'new-parens': 'warn',
117117
'no-array-constructor': 'warn',
118118
'no-caller': 'warn',
119-
'no-cond-assign': ['warn', 'always'],
119+
'no-cond-assign': ['warn', 'except-parens'],
120120
'no-const-assign': 'warn',
121121
'no-control-regex': 'warn',
122122
'no-delete-var': 'warn',

packages/react-dev-utils/FileSizeReporter.js

+23-15
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,29 @@ function printFileSizesAfterBuild(
2525
) {
2626
var root = previousSizeMap.root;
2727
var sizes = previousSizeMap.sizes;
28-
var assets = webpackStats
29-
.toJson()
30-
.assets.filter(asset => /\.(js|css)$/.test(asset.name))
31-
.map(asset => {
32-
var fileContents = fs.readFileSync(path.join(root, asset.name));
33-
var size = gzipSize(fileContents);
34-
var previousSize = sizes[removeFileNameHash(root, asset.name)];
35-
var difference = getDifferenceLabel(size, previousSize);
36-
return {
37-
folder: path.join(path.basename(buildFolder), path.dirname(asset.name)),
38-
name: path.basename(asset.name),
39-
size: size,
40-
sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : ''),
41-
};
42-
});
28+
var assets = (webpackStats.stats || [webpackStats])
29+
.map(stats =>
30+
stats
31+
.toJson()
32+
.assets.filter(asset => /\.(js|css)$/.test(asset.name))
33+
.map(asset => {
34+
var fileContents = fs.readFileSync(path.join(root, asset.name));
35+
var size = gzipSize(fileContents);
36+
var previousSize = sizes[removeFileNameHash(root, asset.name)];
37+
var difference = getDifferenceLabel(size, previousSize);
38+
return {
39+
folder: path.join(
40+
path.basename(buildFolder),
41+
path.dirname(asset.name)
42+
),
43+
name: path.basename(asset.name),
44+
size: size,
45+
sizeLabel:
46+
filesize(size) + (difference ? ' (' + difference + ')' : ''),
47+
};
48+
})
49+
)
50+
.reduce((single, all) => all.concat(single), []);
4351
assets.sort((a, b) => b.size - a.size);
4452
var longestSizeLabelLength = Math.max.apply(
4553
null,

packages/react-dev-utils/WebpackDevServerUtils.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -317,15 +317,19 @@ function prepareProxy(proxy, appPublicFolder) {
317317
// For single page apps, we generally want to fallback to /index.html.
318318
// However we also want to respect `proxy` for API calls.
319319
// So if `proxy` is specified as a string, we need to decide which fallback to use.
320-
// We use a heuristic: if request `accept`s text/html, we pick /index.html.
320+
// We use a heuristic: We want to proxy all the requests that are not meant
321+
// for static assets and as all the requests for static assets will be using
322+
// `GET` method, we can proxy all non-`GET` requests.
323+
// For `GET` requests, if request `accept`s text/html, we pick /index.html.
321324
// Modern browsers include text/html into `accept` header when navigating.
322325
// However API calls like `fetch()` won’t generally accept text/html.
323326
// If this heuristic doesn’t work well for you, use a custom `proxy` object.
324327
context: function(pathname, req) {
325328
return (
326-
mayProxy(pathname) &&
327-
req.headers.accept &&
328-
req.headers.accept.indexOf('text/html') === -1
329+
req.method !== 'GET' ||
330+
(mayProxy(pathname) &&
331+
req.headers.accept &&
332+
req.headers.accept.indexOf('text/html') === -1)
329333
);
330334
},
331335
onProxyReq: proxyReq => {

packages/react-dev-utils/clearConsole.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
function clearConsole() {
1111
process.stdout.write(
12-
process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H'
12+
process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H'
1313
);
1414
}
1515

packages/react-dev-utils/errorOverlayMiddleware.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ const launchEditorEndpoint = require('./launchEditorEndpoint');
1212
module.exports = function createLaunchEditorMiddleware(servedPathPathname) {
1313
return function launchEditorMiddleware(req, res, next) {
1414
if (req.url.startsWith(`${servedPathPathname}${launchEditorEndpoint}`)) {
15-
launchEditor(req.query.fileName, req.query.lineNumber);
15+
const lineNumber = parseInt(req.query.lineNumber, 10) || 1;
16+
const colNumber = parseInt(req.query.colNumber, 10) || 1;
17+
launchEditor(req.query.fileName, lineNumber, colNumber);
1618
res.end();
1719
} else {
1820
next();

packages/react-dev-utils/getProcessForPort.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ function getProcessCommand(processId, processDirectory) {
5858

5959
function getDirectoryOfProcessById(processId) {
6060
return execSync(
61-
'lsof -p ' + processId + ' | awk \'$4=="cwd" {print $9}\'',
61+
'lsof -p ' +
62+
processId +
63+
' | awk \'$4=="cwd" {for (i=9; i<=NF; i++) printf "%s ", $i}\'',
6264
execOptions
6365
).trim();
6466
}

packages/react-dev-utils/ignoredFiles.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
'use strict';
99

1010
const path = require('path');
11+
const escape = require('escape-string-regexp');
1112

1213
module.exports = function ignoredFiles(appSrc) {
1314
return new RegExp(
14-
`^(?!${path
15-
.normalize(appSrc + '/')
16-
.replace(/[\\]+/g, '/')}).+/node_modules/`,
15+
`^(?!${escape(
16+
path.normalize(appSrc + '/').replace(/[\\]+/g, '/')
17+
)}).+/node_modules/`,
1718
'g'
1819
);
1920
};

0 commit comments

Comments
 (0)