Offer to set default browsers (#3792)

* Offer to set browser defaults

* Catch error on no

* Add ending newlines

* Ensure we re-check to prevent defaults from leaking

* Reduce nesting

* Add defaults message

* More explicit
This commit is contained in:
Joe Haddad
2018-01-14 13:54:01 -05:00
parent 0ff234949f
commit 2e59c5412c
9 changed files with 139 additions and 60 deletions

View File

@@ -318,7 +318,7 @@ function prepareProxy(proxy, appPublicFolder) {
// However we also want to respect `proxy` for API calls.
// So if `proxy` is specified as a string, we need to decide which fallback to use.
// We use a heuristic: We want to proxy all the requests that are not meant
// for static assets and as all the requests for static assets will be using
// for static assets and as all the requests for static assets will be using
// `GET` method, we can proxy all non-`GET` requests.
// For `GET` requests, if request `accept`s text/html, we pick /index.html.
// Modern browsers include text/html into `accept` header when navigating.

View File

@@ -9,36 +9,99 @@
const browserslist = require('browserslist');
const chalk = require('chalk');
const os = require('os');
const inquirer = require('inquirer');
const pkgUp = require('pkg-up');
const fs = require('fs');
function checkBrowsers(dir) {
const found = browserslist.findConfig(dir);
const defaultBrowsers = {
development: ['chrome', 'firefox', 'edge'].map(
browser => `last 2 ${browser} versions`
),
production: ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 11'],
};
if (found == null) {
console.log(
chalk.red('As of react-scripts >=2 you must specify targeted browsers.') +
os.EOL +
`Please add a ${chalk.underline(
'browserslist'
)} key to your ${chalk.bold('package.json')}.`
);
return null;
function checkBrowsers(dir, retry = true) {
const current = browserslist.findConfig(dir);
if (current != null) {
return Promise.resolve(current);
}
return found;
if (!retry) {
return Promise.reject(
new Error(
chalk.red(
'As of react-scripts >=2 you must specify targeted browsers.'
) +
os.EOL +
`Please add a ${chalk.underline(
'browserslist'
)} key to your ${chalk.bold('package.json')}.`
)
);
}
const question = {
type: 'confirm',
name: 'shouldSetBrowsers',
message:
chalk.yellow("We're unable to detect target browsers.") +
`\n\nWould you like to add the defaults to your ${chalk.bold(
'package.json'
)}?`,
default: true,
};
return inquirer.prompt(question).then(answer => {
if (answer.shouldSetBrowsers) {
return (
pkgUp(dir)
.then(filePath => {
if (filePath == null) {
return Promise.reject();
}
const pkg = JSON.parse(fs.readFileSync(filePath));
pkg['browserslist'] = defaultBrowsers;
fs.writeFileSync(filePath, JSON.stringify(pkg, null, 2) + os.EOL);
browserslist.clearCaches();
console.log();
console.log(chalk.green('Set target browsers:'));
console.log();
console.log(
`\t${chalk.bold('Production')}: ${chalk.cyan(
defaultBrowsers.production.join(', ')
)}`
);
console.log(
`\t${chalk.bold('Development')}: ${chalk.cyan(
defaultBrowsers.development.join(', ')
)}`
);
console.log();
})
// Swallow any error
.catch(() => {})
.then(() => checkBrowsers(dir, false))
);
} else {
return checkBrowsers(dir, false);
}
});
}
function printBrowsers(dir) {
let browsers = checkBrowsers(dir);
if (browsers == null) {
console.log('Built the bundle with default browser support.');
return;
}
browsers = browsers[process.env.NODE_ENV] || browsers;
if (Array.isArray(browsers)) {
browsers = browsers.join(', ');
}
console.log(
`Built the bundle with browser support for ${chalk.cyan(browsers)}.`
);
return checkBrowsers(dir).then(browsers => {
if (browsers == null) {
console.log('Built the bundle with default browser support.');
return;
}
browsers = browsers[process.env.NODE_ENV] || browsers;
if (Array.isArray(browsers)) {
browsers = browsers.join(', ');
}
console.log(
`Built the bundle with browser support for ${chalk.cyan(browsers)}.`
);
});
}
module.exports = { checkBrowsers, printBrowsers };
module.exports = { defaultBrowsers, checkBrowsers, printBrowsers };

View File

@@ -50,6 +50,7 @@
"inquirer": "5.0.0",
"is-root": "1.0.0",
"opn": "5.2.0",
"pkg-up": "2.0.0",
"react-error-overlay": "^4.0.0",
"recursive-readdir": "2.2.1",
"shell-quote": "1.6.1",