Skip to content
This repository was archived by the owner on Feb 15, 2025. It is now read-only.

Commit c8e9dbf

Browse files
committed
Added top-level browsers config for configuring browser support with a browserslist query
Breaking: configuring webpack.autoprefixer as a browserslist query is deprecated and won't do anything Breaking: default browser support for CSS prefixes when building changed from '>1%, last 4 versions, Firefox ESR, not ie < 9' to '>0.2%, not dead, not op_mini all' #550
1 parent bf05318 commit c8e9dbf

File tree

8 files changed

+115
-37
lines changed

8 files changed

+115
-37
lines changed

CHANGES.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,18 @@
77
- Removed default polyfills for `Promise`, `fetch()` and `Object.assign()` and deprecated `polyfill` config.
88
- If you need to support older browsers, you will need to provide the necessary polyfills yourself.
99
- The [react-app-polyfill](https://github.com/facebook/create-react-app/tree/master/packages/react-app-polyfill#react-app-polyfill) module provides polyfills for IE 9-11, and for stable language features - its instructions also work for apps using nwb.
10+
- Deprecated using a string for [`webpack.autoprefixer` config](https://github.com/insin/nwb/blob/master/docs/Configuration.md#autoprefixer-object) to configure supported browsers - this will no longer do anything and should be moved to the new [`browsers` config](https://github.com/insin/nwb/blob/master/docs/Configuration.md#browsers-string--arraystring--object).
11+
- Default browser configuration for Autoprefixer when building an app has changed from [`>1%, last 4 versions, Firefox ESR, not ie < 9`](https://browserl.ist/?q=%3E1%25%2C+last+4+versions%2C+Firefox+ESR%2C+not+ie+%3C+9) to [`>0.2%, not dead, not op_mini all`](https://browserl.ist/?q=%3E0.2%25%2C+not+dead%2C+not+op_mini+all).
1012
- file-loader v6.0.0 [changed its default hashing algorithm](https://github.com/webpack-contrib/file-loader/blob/master/CHANGELOG.md#600-2020-03-17).
1113

14+
## Added
15+
16+
- Added top-level [`browsers` config](https://github.com/insin/nwb/blob/master/docs/Configuration.md#browsers-string--arraystring--object) to configure supported browsers. This supports using separate browserslist configuration for development and production.
17+
18+
## Changed
19+
20+
- Default browser configuration for Autoprefixer when running the development server for an app has changed from [`>1%, last 4 versions, Firefox ESR, not ie < 9`](https://browserl.ist/?q=%3E1%25%2C+last+4+versions%2C+Firefox+ESR%2C+not+ie+%3C+9) to [`last 1 chrome version, last 1 firefox version, last 1 safari version`](https://browserl.ist/?q=last+1+chrome+version%2C+last+1+firefox+version%2C+last+1+safari+version).
21+
1222
## Dependencies
1323

1424
- chalk: v3.0.0 → [v4.0.0](https://github.com/chalk/chalk/releases/tag/v4.0.0)

docs/Configuration.md

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ module.exports = {
2727
...or a function which returns a configuration object when called:
2828

2929
```js
30-
module.exports = function(args) {
30+
module.exports = function(nwb) {
3131
return {
3232
// ...
3333
}
@@ -68,6 +68,7 @@ The configuration object can include the following properties:
6868

6969
- nwb Configuration
7070
- [`type`](#type-string-required-for-generic-build-commands)
71+
- [`browsers`](#browsers-string--arraystring--object) - browserslist queries for the browsers your app supports
7172
- [Babel Configuration](#babel-configuration)
7273
- [`babel`](#babel-object)
7374
- [`babel.cherryPick`](#cherrypick-string--arraystring) - enable cherry-picking for destructured `import` statements
@@ -85,7 +86,7 @@ The configuration object can include the following properties:
8586
- [Webpack Configuration](#webpack-configuration)
8687
- [`webpack`](#webpack-object)
8788
- [`webpack.aliases`](#aliases-object) - rewrite certain import paths
88-
- [`webpack.autoprefixer`](#autoprefixer-string--object) - options for Autoprefixer
89+
- [`webpack.autoprefixer`](#autoprefixer-object) - options for Autoprefixer
8990
- [`webpack.compat`](#compat-object) - enable Webpack compatibility tweaks for commonly-used modules
9091
- [`webpack.copy`](#copy-array--object) - patterns and options for `CopyWebpackPlugin`
9192
- [`webpack.debug`](#debug-boolean) - create a more debuggable production build
@@ -139,6 +140,40 @@ If configured, it must be one of the following:
139140
- `'web-app'`
140141
- `'web-module'`
141142

143+
#### `browsers`: `String | Array<String> | Object`
144+
145+
Configures [Browserslist](https://github.com/browserslist/browserslist#browserslist-) queries specifying the range of browsers your app supports.
146+
147+
If you don't configure this, nwb's default configuration is:
148+
149+
- `'last 1 chrome version, last 1 firefox version, last 1 safari version'` for development (when running a development server with `nwb serve`)
150+
- `'>0.2%, not dead, not op_mini all'` for production (when building your app with `nwb build`)
151+
152+
To override the defaults individually, configure an object with `development` or `production` properties:
153+
154+
```js
155+
module.exports = {
156+
browsers: {
157+
production: '>0.5%, not IE 11'
158+
}
159+
}
160+
```
161+
162+
If you configure a string or a list of strings, it will be used for both development and production:
163+
164+
```js
165+
module.exports = {
166+
browsers: [
167+
'last 2 chrome versions',
168+
'last 2 firefox versions',
169+
'last 2 safari versions',
170+
'IE 11'
171+
]
172+
}
173+
```
174+
175+
You can check which browsers your query will target using the [browserl.ist](http://browserl.ist) service.
176+
142177
### Babel Configuration
143178

144179
#### `babel`: `Object`
@@ -413,36 +448,26 @@ module.exports = {
413448

414449
You should be careful to avoid creating aliases which conflict with the names of Node.js built-ins or npm packages, as you will then be unable to import them.
415450

416-
##### `autoprefixer`: `String | Object`
451+
##### `autoprefixer`: `Object`
417452

418453
Configures [Autoprefixer options](https://github.com/postcss/autoprefixer#options) for nwb's default PostCSS configuration.
419454

420-
If you just need to configure the range of browsers prefix addition/removal is based on (nwb's default is `>1%, last 4 versions, Firefox ESR, not ie < 9`), you can use a String:
455+
If you want to configure the range of browsers prefix management is based on, the top-level [`browsers` config](#browsers-string--arraystring--object) is passed to Autoprefixer by default for its `overrideBrowserslist` option.
421456

422-
```js
423-
module.exports = {
424-
webpack: {
425-
autoprefixer: '> 1%, last 2 versions, Firefox ESR, ios >= 8'
426-
}
427-
}
428-
```
429-
430-
Use an Object if you need to set any of Autoprefixer's other options.
457+
Provide an Object to configure any of Autoprefixer's other options.
431458

432-
e.g. if you also want to disable removal of prefixes which aren't required for the configured range of browsers:
459+
e.g. if you want to enable grid prefixes for IE 10 and IE 11:
433460

434461
```js
435462
module.exports = {
436463
webpack: {
437464
autoprefixer: {
438-
remove: false,
465+
grid: 'autoplace'
439466
}
440467
}
441468
}
442469
```
443470

444-
You can check which browsers your Autoprefixer configuration will target using the [browserl.ist](http://browserl.ist) service.
445-
446471
##### `compat`: `Object`
447472

448473
Certain libraries require specific configuration to play nicely with Webpack - nwb can take care of the details for you if you use a `compat` object to tell it when you're using them.

src/config/user.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ export function processUserConfig({
143143
let report = new UserConfigReport({configFileExists, configPath})
144144

145145
let {
146-
type, polyfill,
146+
type, browsers,
147+
// TODO Deprecated - remove
148+
polyfill,
147149
babel, devServer, karma, npm, webpack: _webpack, // eslint-disable-line no-unused-vars
148150
...unexpectedConfig
149151
} = userConfig
@@ -162,6 +164,30 @@ export function processUserConfig({
162164
report.error('type', userConfig.type, `Must be one of: ${joinAnd(Array.from(PROJECT_TYPES), 'or')}`)
163165
}
164166

167+
if ('browsers' in userConfig) {
168+
if (typeOf(browsers) === 'string' || typeOf(browsers) === 'array') {
169+
userConfig.browsers = {
170+
development: browsers,
171+
production: browsers
172+
}
173+
}
174+
else if (typeOf(browsers) === 'object') {
175+
if (!browsers.hasOwnProperty('development') && !browsers.hasOwnProperty('production')) {
176+
report.hint(
177+
'browsers',
178+
`You provided ${chalk.cyan('browsers')} config but didn't provide ${chalk.cyan('development')} or ${chalk.cyan('production')} settings`
179+
)
180+
}
181+
}
182+
else {
183+
report.error(
184+
'browsers',
185+
`type: ${typeOf(browsers)}`,
186+
`Must be a ${chalk.cyan('String')}, ${chalk.cyan('Array')} or ${chalk.cyan('Object')}`
187+
)
188+
}
189+
}
190+
165191
// TODO Deprecated - remove
166192
if ('polyfill' in userConfig) {
167193
if (!warnedAboutPolyfillConfig) {

src/config/webpack.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {joinAnd, pluralise as s, typeOf} from '../utils'
66

77
const DEFAULT_STYLE_LOADERS = new Set(['css', 'postcss'])
88

9+
let warnedAboutAutoPrefixerString = false
10+
911
export function processWebpackConfig({pluginConfig, report, userConfig}) {
1012
let {
1113
aliases,
@@ -58,16 +60,22 @@ export function processWebpackConfig({pluginConfig, report, userConfig}) {
5860

5961
// autoprefixer
6062
if ('autoprefixer' in userConfig.webpack) {
61-
// Convenience: allow Autoprefixer browsers config to be configured as a String
63+
// TODO Deprecated - remove
6264
if (typeOf(autoprefixer) === 'string') {
63-
userConfig.webpack.autoprefixer = {overrideBrowserslist: autoprefixer}
65+
if (!warnedAboutAutoPrefixerString) {
66+
report.deprecated(
67+
'webpack.autoprefixer as a String',
68+
'Replaced by top-level "browsers" config in nwb v0.25.0 - webpack.autoprefixer can no longer be a String',
69+
)
70+
warnedAboutAutoPrefixerString = true
71+
}
72+
userConfig.webpack.autoprefixer = {}
6473
}
6574
else if (typeOf(autoprefixer) !== 'object') {
6675
report.error(
6776
'webpack.autoprefixer',
6877
`type: ${typeOf(autoprefixer)}`,
69-
`Must be a ${chalk.cyan('String')} (for ${chalk.cyan('browsers')} config only) ` +
70-
`or an ${chalk.cyan('Object')} (for any Autoprefixer options)`
78+
`Must be an ${chalk.cyan('Object')}`
7179
)
7280
}
7381
}

src/constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ export const PROJECT_TYPES = new Set([
1717
WEB_APP,
1818
WEB_MODULE,
1919
])
20+
21+
export const DEFAULT_BROWSERS_DEV = 'last 1 chrome version, last 1 firefox version, last 1 safari version'
22+
export const DEFAULT_BROWSERS_PROD = '>0.2%, not dead, not op_mini all'

src/createWebpackConfig.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import webpack from 'webpack'
1212
import merge from 'webpack-merge'
1313

1414
import createBabelConfig from './createBabelConfig'
15+
import {DEFAULT_BROWSERS_DEV, DEFAULT_BROWSERS_PROD} from './constants'
1516
import debug from './debug'
1617
import {UserError} from './errors'
1718
import {deepToString, replaceArrayMerge, typeOf} from './utils'
@@ -590,14 +591,14 @@ export function createPlugins(
590591
}
591592

592593
function createDefaultPostCSSPlugins(userWebpackConfig) {
594+
let overrideBrowserslist = process.env.NODE_ENV === 'production'
595+
? (userWebpackConfig.browsers && userWebpackConfig.browsers.production) ||
596+
DEFAULT_BROWSERS_PROD
597+
: (userWebpackConfig.browsers && userWebpackConfig.browsers.development) ||
598+
DEFAULT_BROWSERS_DEV
593599
return [
594600
autoprefixer({
595-
overrideBrowserslist: [
596-
'>1%',
597-
'last 4 versions',
598-
'Firefox ESR',
599-
'not ie < 9',
600-
],
601+
overrideBrowserslist,
601602
...userWebpackConfig.autoprefixer
602603
})
603604
]

tests/config-test.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,12 @@ function process(config) {
6464

6565
describe('processUserConfig()', () => {
6666
describe('validation', () => {
67-
it('config file has an invalid type', () => {
67+
it('type is not a string', () => {
6868
check({type: 'invalid'}, 'type', /Must be/)
6969
})
70+
it('browsers is an invalid type', () => {
71+
check({browsers: /invalid/}, 'browsers', /Must be/)
72+
})
7073
it('babel.plugins is not an array', () => {
7174
check({babel: {plugins: {}}}, 'babel.plugins', /Must be/)
7275
})
@@ -76,10 +79,7 @@ describe('processUserConfig()', () => {
7679
it('babel.proposals is not an object or false', () => {
7780
check({babel: {proposals: /invalid/}}, 'babel.proposals', /Must be/)
7881
})
79-
it('babel.react is not an string or an object', () => {
80-
check({babel: {react: /invalid/}}, 'babel.react', /Must be/)
81-
})
82-
it('babel.react is not an string or an object', () => {
82+
it('babel.react is not a string or an object', () => {
8383
check({babel: {react: /invalid/}}, 'babel.react', /Must be/)
8484
})
8585
it('babel.reactConstantElements is not a boolean', () => {
@@ -200,6 +200,14 @@ describe('processUserConfig()', () => {
200200
})
201201

202202
describe('convenience shorthand', () => {
203+
it('allows browsers to be a string', () => {
204+
let config = process({browsers: 'test'})
205+
expect(config.browsers).toEqual({development: 'test', production: 'test'})
206+
})
207+
it('allows browsers to be an array', () => {
208+
let config = process({browsers: ['test']})
209+
expect(config.browsers).toEqual({development: ['test'], production: ['test']})
210+
})
203211
it('allows babel.react to be a string', () => {
204212
let config = process({babel: {react: 'test'}})
205213
expect(config.babel.react).toEqual({runtime: 'test'})
@@ -208,10 +216,6 @@ describe('processUserConfig()', () => {
208216
let config = process({npm: {umd: 'test'}})
209217
expect(config.npm.umd).toEqual({global: 'test'})
210218
})
211-
it('allows webpack.autoprefixer to be a browser string', () => {
212-
let config = process({webpack: {autoprefixer: 'test'}})
213-
expect(config.webpack.autoprefixer).toEqual({overrideBrowserslist: 'test'})
214-
})
215219
it('allows webpack.copy to be an array', () => {
216220
let config = process({webpack: {copy: ['test']}})
217221
expect(config.webpack.copy).toEqual({patterns: ['test']})

tests/fixtures/worst-config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// A config file in which everything is wrong
22
module.exports = {
33
type: 'invalid',
4+
browsers: 45,
45
polyfill: 45,
56
invalidTopLevelConfig: true,
67
moreInvalidTopLevelConfig: true,

0 commit comments

Comments
 (0)