diff --git a/packages/react-dev-utils/README.md b/packages/react-dev-utils/README.md
index 166e1bfaea3..eb8f48b68c9 100644
--- a/packages/react-dev-utils/README.md
+++ b/packages/react-dev-utils/README.md
@@ -220,6 +220,20 @@ compiler.plugin('done', function(stats) {
});
```
+#### `printBuildError(error: Object): void`
+
+Prettify some known build errors.
+Pass an Error object to log a prettified error message in the console.
+
+```
+ const printBuildError = require('react-dev-utils/printBuildError')
+ try {
+ build()
+ } catch(e) {
+ printBuildError(e) // logs prettified message
+ }
+```
+
#### `getProcessForPort(port: number): string`
Finds the currently running process on `port`.
diff --git a/packages/react-dev-utils/package.json b/packages/react-dev-utils/package.json
index 6fa6c4117a3..7054912d759 100644
--- a/packages/react-dev-utils/package.json
+++ b/packages/react-dev-utils/package.json
@@ -18,13 +18,14 @@
"crossSpawn.js",
"eslintFormatter.js",
"FileSizeReporter.js",
+ "printBuildError.js",
"formatWebpackMessages.js",
"getProcessForPort.js",
"inquirer.js",
"InterpolateHtmlPlugin.js",
"launchEditor.js",
- "noopServiceWorkerMiddleware.js",
"ModuleScopePlugin.js",
+ "noopServiceWorkerMiddleware.js",
"openBrowser.js",
"openChrome.applescript",
"printHostingInstructions.js",
diff --git a/packages/react-dev-utils/printBuildError.js b/packages/react-dev-utils/printBuildError.js
new file mode 100644
index 00000000000..5efbaa97d43
--- /dev/null
+++ b/packages/react-dev-utils/printBuildError.js
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
+const get = require('lodash/get');
+const chalk = require('chalk');
+
+module.exports = function printBuildError(err) {
+ const message = get(err, 'message');
+ const stack = get(err, 'stack');
+
+ // Add more helpful message for UglifyJs error
+ if (
+ stack &&
+ typeof message === 'string' &&
+ message.indexOf('from UglifyJs') !== -1
+ ) {
+ try {
+ const matched = /Unexpected token:(.+)\[(.+)\:(.+)\,(.+)\]\[.+\]/.exec(
+ stack
+ );
+ if (!matched) {
+ throw new Error(
+ "The regex pattern is not matched. Maybe UglifyJs changed it's message?"
+ );
+ }
+ const problemPath = matched[2];
+ const line = matched[3];
+ const column = matched[4];
+ console.log(
+ 'Failed to minify the code from this file: \n\n',
+ chalk.yellow(`${problemPath} line ${line}:${column}`),
+ '\n'
+ );
+ } catch (ignored) {
+ console.log('Failed to minify the code.', err);
+ }
+ console.log('Read more here: http://bit.ly/2tRViJ9');
+ } else {
+ console.log((message || err) + '\n');
+ }
+ console.log();
+};
diff --git a/packages/react-scripts/scripts/build.js b/packages/react-scripts/scripts/build.js
index 2e4bc21ee5b..232edf3ed80 100644
--- a/packages/react-scripts/scripts/build.js
+++ b/packages/react-scripts/scripts/build.js
@@ -34,8 +34,10 @@ const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
+const printBuildError = require('react-dev-utils/printBuildError');
-const measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild;
+const measureFileSizesBeforeBuild =
+ FileSizeReporter.measureFileSizesBeforeBuild;
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
const useYarn = fs.existsSync(paths.yarnLockFile);
@@ -93,7 +95,7 @@ measureFileSizesBeforeBuild(paths.appBuild)
},
err => {
console.log(chalk.red('Failed to compile.\n'));
- console.log((err.message || err) + '\n');
+ printBuildError(err);
process.exit(1);
}
);
diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md
index c54858b03f1..1e9a50572da 100644
--- a/packages/react-scripts/template/README.md
+++ b/packages/react-scripts/template/README.md
@@ -87,6 +87,7 @@ You can find the most recent version of this guide [here](https://github.com/fac
- [`npm test` hangs on macOS Sierra](#npm-test-hangs-on-macos-sierra)
- [`npm run build` exits too early](#npm-run-build-exits-too-early)
- [`npm run build` fails on Heroku](#npm-run-build-fails-on-heroku)
+ - [`npm run build` fails to minify](#npm-run-build-fails-to-minify)
- [Moment.js locales are missing](#momentjs-locales-are-missing)
- [Something Missing?](#something-missing)
@@ -1998,6 +1999,16 @@ moment.locale('fr');
This will only work for locales that have been explicitly imported before.
+### `npm run build` fails to minify
+
+You may occasionally find a package you depend on needs compiled or ships code for a non-browser environment.
+This is considered poor practice in the ecosystem and does not have an escape hatch in Create React App.
+
+To resolve this:
+1. Open an issue on the dependency's issue tracker and ask that the package be published pre-compiled (retaining ES6 Modules).
+2. Fork the package and publish a corrected version yourself.
+3. If the dependency is small enough, copy it to your `src/` folder and treat it as application code.
+
## Something Missing?
If you have ideas for more “How To” recipes that should be on this page, [let us know](https://github.com/facebookincubator/create-react-app/issues) or [contribute some!](https://github.com/facebookincubator/create-react-app/edit/master/packages/react-scripts/template/README.md)