Skip to content

Commit

Permalink
Merge facebook/create-react-app v2.1.8
Browse files Browse the repository at this point in the history
  • Loading branch information
koistya committed Mar 12, 2019
2 parents 2951c06 + 452ebe7 commit 733ee79
Show file tree
Hide file tree
Showing 13 changed files with 325 additions and 194 deletions.
44 changes: 25 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ entry point for Node.js as demonstrated below:
│ │ ├── api.js # - GraphQL API endpoint
│ │ └── index.js # - Node.js app entry point
│ └── index.js # Client-side app entry point, e.g. ReactDOM.hydrate(<App />, container)
├── config-overrides.js # Configuration overrides for Webpack, etc. (optional)
└── package.json # List of project dependencies and NPM scripts
```

Expand All @@ -41,24 +40,24 @@ entry point for Node.js as demonstrated below:
{
"main": "build/server.js",
"engines": {
"node": "8"
"node": ">=8.10"
},
"dependencies": {
+ "express": "^4.6.13",
"react": "^16.4.2",
"react-dom": "^16.4.2"
+ "express": "^4.6.14",
"react": "^16.8.4",
"react-dom": "^16.8.4"
},
{
- "react-scripts": "^1.1.1"
+ "react-app-tools": "^3.0.5"
+ "react-app-tools": "^3.1.0-preview.7"
},
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app start",
- "build": "react-scripts build",
+ "build": "react-app build",
- "test": "react-scripts test --env=jsdom"
+ "test": "react-app test --env=jsdom"
- "test": "react-scripts test"
+ "test": "react-app test"
}
}
```
Expand Down Expand Up @@ -128,19 +127,26 @@ Join our Telegram chat for support and feature requests - https://t.me/reactapp

## How to Customize

Create `config-overrides.js` file in the root of your project containing with configuration
overrides. Here is an example:
Create `webpack.config.js` file in the root of your project that extends the
default Webpack configuration. For example:

```js
module.exports = {
webpack(config, { target }) {
return {
...config,
plugins: target === 'node'
? config.plugins.concat(new LimitChunkCountPlugin({ maxChunks: 1 })),
: config.plugins
};
}
module.exports = () => {
const [
browserConfig,
serverConfig,
] = require('react-app-tools/config/webpack');
return [
browserConfig,
{
...serverConfig,
plugins: {
...serverConfig.plugins.concat(
new LimitChunkCountPlugin({ maxChunks: 1 })
),
},
},
];
};
```

Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"packages/*"
],
"devDependencies": {
"eslint": "5.12.0",
"husky": "1.0.0-rc.15",
"eslint": "5.15.1",
"husky": "1.3.0",
"lerna": "^2.9.1",
"lint-staged": "^8.0.4",
"prettier": "^1.15.2",
"react-scripts": "2.1.5"
"prettier": "^1.16.4",
"react-scripts": "2.1.8"
},
"lint-staged": {
"*.js": [
Expand Down
116 changes: 96 additions & 20 deletions packages/react-app-tools/WebpackDevServerUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,11 @@ const inquirer = require('inquirer');
const clearConsole = require('react-dev-utils/clearConsole');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const getProcessForPort = require('react-dev-utils/getProcessForPort');
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
const forkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
const paths = require('./config/paths');

const isInteractive = process.stdout.isTTY;
let handleCompile;

// You can safely remove this after ejecting.
// We only use this block for testing of Create React App itself:
const isSmokeTest = process.argv.some(arg => arg.indexOf('--smoke-test') > -1);
if (isSmokeTest) {
handleCompile = (err, stats) => {
if (err || stats.hasErrors() || stats.hasWarnings()) {
process.exit(1);
} else {
process.exit(0);
}
};
}

function prepareUrls(protocol, host, port) {
const formatUrl = hostname =>
Expand Down Expand Up @@ -114,12 +102,20 @@ function printInstructions(appName, urls, useYarn) {
console.log();
}

function createCompiler(webpack, config, appName, urls, useYarn) {
function createCompiler({
appName,
config,
devSocket,
urls,
useYarn,
useTypeScript,
webpack,
}) {
// "Compiler" is a low-level interface to Webpack.
// It lets us listen to some events and provide our own custom messages.
let compiler;
try {
compiler = webpack(config, handleCompile);
compiler = webpack(config);
} catch (err) {
console.log(chalk.red('Failed to compile.'));
console.log();
Expand All @@ -144,14 +140,39 @@ function createCompiler(webpack, config, appName, urls, useYarn) {
});

let isFirstCompile = true;
let tsMessagesPromise;
let tsMessagesResolver;

global.appPromise = new Promise(resolve => {
global.appPromiseResolve = resolve;
});

if (useTypeScript) {
compiler.hooks.beforeCompile.tap('beforeCompile', () => {
tsMessagesPromise = new Promise(resolve => {
tsMessagesResolver = msgs => resolve(msgs);
});
});

forkTsCheckerWebpackPlugin
.getCompilerHooks(compiler)
.receive.tap('afterTypeScriptCheck', (diagnostics, lints) => {
const allMsgs = [...diagnostics, ...lints];
const format = message =>
`${message.file}\n${typescriptFormatter(message, true)}`;

tsMessagesResolver({
errors: allMsgs.filter(msg => msg.severity === 'error').map(format),
warnings: allMsgs
.filter(msg => msg.severity === 'warning')
.map(format),
});
});
}

// "done" event fires when Webpack has finished recompiling the bundle.
// Whether or not you have warnings or errors, you will get this event.
compiler.hooks.done.tap('done', stats => {
compiler.hooks.done.tap('done', async stats => {
if (isInteractive) {
clearConsole();
}
Expand All @@ -161,9 +182,43 @@ function createCompiler(webpack, config, appName, urls, useYarn) {
// them in a readable focused way.
// We only construct the warnings and errors for speed:
// https://github.com/facebook/create-react-app/issues/4492#issuecomment-421959548
const messages = formatWebpackMessages(
stats.toJson({ all: false, warnings: true, errors: true })
);
const statsData = stats.toJson({
all: false,
warnings: true,
errors: true,
});

if (useTypeScript && statsData.errors.length === 0) {
const delayedMsg = setTimeout(() => {
console.log(
chalk.yellow(
'Files successfully emitted, waiting for typecheck results...'
)
);
}, 100);

const messages = await tsMessagesPromise;
clearTimeout(delayedMsg);
statsData.errors.push(...messages.errors);
statsData.warnings.push(...messages.warnings);

// Push errors and warnings into compilation result
// to show them after page refresh triggered by user.
stats.compilation.errors.push(...messages.errors);
stats.compilation.warnings.push(...messages.warnings);

if (messages.errors.length > 0) {
devSocket.errors(messages.errors);
} else if (messages.warnings.length > 0) {
devSocket.warnings(messages.warnings);
}

if (isInteractive) {
clearConsole();
}
}

const messages = formatWebpackMessages(statsData);
const isSuccessful = !messages.errors.length && !messages.warnings.length;
if (isSuccessful) {
console.log(chalk.green('Compiled successfully!'));
Expand Down Expand Up @@ -223,6 +278,27 @@ function createCompiler(webpack, config, appName, urls, useYarn) {
delete require.cache[paths.nodeBuildAppJs];
global.appPromiseResolve();
});

// You can safely remove this after ejecting.
// We only use this block for testing of Create React App itself:
const isSmokeTest = process.argv.some(
arg => arg.indexOf('--smoke-test') > -1
);
if (isSmokeTest) {
compiler.hooks.failed.tap('smokeTest', async () => {
await tsMessagesPromise;
process.exit(1);
});
compiler.hooks.done.tap('smokeTest', async stats => {
await tsMessagesPromise;
if (stats.hasErrors() || stats.hasWarnings()) {
process.exit(1);
} else {
process.exit(0);
}
});
}

return compiler;
}

Expand Down
17 changes: 5 additions & 12 deletions packages/react-app-tools/config/jest/fileTransform.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
// @remove-on-eject-begin
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// @remove-on-eject-end
'use strict';

const path = require('path');
Expand All @@ -18,18 +10,19 @@ module.exports = {
const assetFilename = JSON.stringify(path.basename(filename));

if (filename.match(/\.svg$/)) {
return `module.exports = {
return `const React = require('react');
module.exports = {
__esModule: true,
default: ${assetFilename},
ReactComponent: (props) => ({
ReactComponent: React.forwardRef((props, ref) => ({
$$typeof: Symbol.for('react.element'),
type: 'svg',
ref: null,
ref: ref,
key: null,
props: Object.assign({}, props, {
children: ${assetFilename}
})
}),
})),
};`;
}

Expand Down
Loading

0 comments on commit 733ee79

Please sign in to comment.