Skip to content
This repository has been archived by the owner on May 11, 2018. It is now read-only.

Promote shareable browserslist config #108

Closed
ai opened this issue Dec 23, 2016 · 32 comments
Closed

Promote shareable browserslist config #108

ai opened this issue Dec 23, 2016 · 32 comments

Comments

@ai
Copy link

ai commented Dec 23, 2016

I think we should promote shareable browsers config instead of browsers option. Maybe browserslist key in package.json will be the best way.

I think most of babel-preset-env users also use Autoprefixer. So for better maintainability they should use shareable browsers config to use same browsers list in Autoprefixer and babel-preset-env. But most of developers doesn’t know about this option and benefits of it.

I already removed browsers option from all examples in Autoprefixer docs and focused on sharable configs.

@yavorsky
Copy link
Member

yavorsky commented Dec 23, 2016

Nice! It might be the first step for configs generalization.
Moreover, we already have browserslist as dependency and could parse config with parseConfig.

I come across cases when people (and my projects too) are using it in bundler's config files, something like:

const browsers = ['> 4%', 'ie 11', 'safari 8'];
const envPreset = ["env", {targets: {browsers}}];

...
plugins: [require('autoprefixer')(browsers)]
...
presets:  [envPreset]

And use it depending what build tool you have.

By putting this logic to the separate config file we would decrease config mess. Also, it could be useful for other things that want to know what envs your app is supporting.

@yavorsky yavorsky reopened this Dec 23, 2016
@TuckerWhitehouse
Copy link

Would it be possible to remove the if statement from these lines: https://github.com/babel/babel-preset-env/blob/master/src/index.js#L145-L149.
If the user defines "browsers" in the targets, it will be passed in as before, and if not, browserslist will use it's internal resolution.

@ai
Copy link
Author

ai commented Jan 4, 2017

@yavorsky I found that unfortunately current version of babel-preset-env don’t use Browserlist config at all :(. It doesn’t execute browserslist function if browsers options was not passed.

Could we change it? What do you need to change it?

@ai
Copy link
Author

ai commented Jan 4, 2017

@yavorsky BTW, this solution is not ideal:

const browsers = ['> 4%', 'ie 11', 'safari 8'];

plugins: [require('autoprefixer')(browsers)]

presets:  [
  ["env", {targets: {browsers}}]
]

Not only Autoprefixer and Babel need a browsers list. Stylelint and webpack CSS compression uses (or will use soon) browsers information too. In this case we could not pass browsers to all tools manually.

I agree that config mess is a problem. This is why new Browserslist version supports package.json browsers list. Is it a solution for you?

@yavorsky
Copy link
Member

yavorsky commented Jan 4, 2017

@ai actually, removing single condition will fix it.
But I found that calling browserslist with null/undefined argument will return default browsers ({ chrome: 49, edge: 13, firefox: 45, ie: 10, ios: 10, safari: 9 }) and it could cause confusion.
For example, setting targets to just {"chrome": 55} may call browserslist(undefined) and we can't check if results is generated by browserslist config or just it's default list from browserslist.

@yavorsky
Copy link
Member

yavorsky commented Jan 4, 2017

As I understand, by passing config searching process to browserslist we can't determine original source (config/arguments/defaults).
It's my thoughts after the first sight. Going to dive deeper in the evening.

@ai
Copy link
Author

ai commented Jan 4, 2017

@yavorsky you could convert { chrome: 55 } to browserslist query ;).

var queries = targets.browsers || []
var byName = Object.keys(targets).filter(i => i !== 'browsers').map(i => i + ' ' + browsers[i])
var browsers = browserslist(queries.concat(byName), { path: processedFile })

Note about path option. browserslist config will be looked in processed file path (logic is same with .babelrc).

@yavorsky
Copy link
Member

yavorsky commented Jan 4, 2017

@ai Yes! Also, check for node and it must work perfect! i !== 'browsers' && i !== 'node'. Thanks :)

@ai
Copy link
Author

ai commented Jan 4, 2017

@yavorsky BTW, I could to add node support to Browserslist, but @hzoo ignored my questions about implementation :(.

@yavorsky
Copy link
Member

yavorsky commented Jan 4, 2017

@ai Some time ago I thought to make a PR, but stacked with queries like node > 5%, > 1% in US (No sources to get info about node.js versions usage.) so we could loose consistency by just ignoring it.

@yavorsky
Copy link
Member

yavorsky commented Jan 4, 2017

@ai BTW, whether there any reasons/use cases where defaults with no args is useful?

browserslist('').toString() !== browserslist().toString()

@ai
Copy link
Author

ai commented Jan 4, 2017

@yavorsky the problem is only country based statistics or we have no global statistics sources too?

browserslist('') is equal to browserslist([]), empty selection.

@yavorsky
Copy link
Member

yavorsky commented Jan 4, 2017

@ai I haven't found any global updatable statistics. To determine browser version we just need to read request header, but to get node.js version.. unless, that npm statistics or public opinion polls :)

@hzoo
Copy link
Member

hzoo commented Jan 4, 2017

@ai I wasn't ignoring you in particular, I've been taking a break from OSS over the holiday so didn't really do anything the past 2 weeks

@ai
Copy link
Author

ai commented Jan 4, 2017

@hzoo ouh, great :). Welcome back :).

@yavorsky maybe we could ask npm to give us some statistics? Babel + Autoprefixer request is a big power :D.

@yavorsky
Copy link
Member

yavorsky commented Jan 4, 2017

@ai I'm sure we could gather more OSS giants :)
But I'm afraid info might be too blurry. Unless they are sending hidden requests to their servers in background 🕵🏻(I'm hope no), all we could receive is node.js downloads(not usage) stats. But it could be a good start.

@ai
Copy link
Author

ai commented Jan 4, 2017

@yavorsky but do we need 100% accurate statistics? I am OK with mistakes around 10%.

@amilajack
Copy link

How does babel import the browsers config section from package.json?

@yavorsky
Copy link
Member

yavorsky commented Jan 7, 2017

@amilajack browserslist is searching config by itself
babel imports only babelrc and babel field from package.json.

@pavel06081991
Copy link

Hi, guys. Are there any updates?

@okorz001
Copy link

okorz001 commented Apr 8, 2017

I am requiring package.json into webpack config as a workaround:

targets: { browsers: require('./package.json').browserslist },

@jimblue
Copy link

jimblue commented Apr 14, 2017

Hi there!

Just wondering if you have any plan to make babel-preset-env compatible with browserlist trough package.json so we could finally have a universal shared configuration?

@existentialism
Copy link
Member

@jmbelloteau yes, that is absolutely our plan... and we will be landing it in 2.0 via #161.

@jimblue
Copy link

jimblue commented Apr 14, 2017

@existentialism great! thanks a lot 😄
I didn't see there is also a pre-release.
Is it stable enough to use it in production or you suggest to be patient haha...

@existentialism
Copy link
Member

It's very much an alpha... but I do know some brave souls running it already :)

@jimblue
Copy link

jimblue commented Apr 14, 2017

I'll be brave on a test project then 😃 ! Thanks 👍

@skleeschulte
Copy link

If someone is interested in a workaround that uses browserslist's own configuration loading logic while using babel-loader in webpack, here it is: I pass an options object to the babel-loader in webpack instead of relying on a .babelrc file ({ loader: 'babel-loader', options: babelConfig }).

babelConfig looks like this:

const babelConfig = {
    // Do not use .babelrc file
    babelrc: false,

    presets: [
        ['env', {
            targets: {
                browsers: targetBrowsers
            },
            // Webpack understands the native import syntax, and uses it for tree shaking
            // --> do not transform modules
            modules: false
        }],
        ...
}

And this is the code to get targetBrowsers:

const browserslist = require('browserslist');

// pickEnv is adopted from
// https://github.com/ai/browserslist/blob/bc78b5d635344796c77a7e23b66f311ad0d9ab5e/index.js#L99-L114
function pickEnv(config) {
    if ( typeof config !== 'object' ) return config;

    let env;
    if ( typeof process.env.BROWSERSLIST_ENV === 'string' ) {
        env = process.env.BROWSERSLIST_ENV;
    } else if ( typeof process.env.NODE_ENV === 'string' ) {
        env = process.env.NODE_ENV;
    } else {
        env = 'development';
    }

    return config[env] || config.defaults;
}

const browserslistConfig = pickEnv(browserslist.findConfig('.'));
const targetBrowsers = Array.isArray(browserslistConfig) ? browserslistConfig : [browserslistConfig];

This has browserslist as a package dependency:

npm install browserslist --save-dev

@damianobarbati
Copy link

I'm currently defining babel config in a babel entry in my package.json and using env target option: how can I tell babel to use the browserslist entry of the very same package.json config file? Without repeating it?

@LimeWub
Copy link

LimeWub commented Sep 5, 2017

+1

Would be nice if it'd pick up the "browserlist" property as a default :)

@damianobarbati
Copy link

@LimeWub it does now: upgrade to latest babel-preset-env 😉

https://github.com/damianobarbati/react-app/blob/master/package.json#L183
https://github.com/damianobarbati/react-app/blob/master/package.json#L182

@jan-dh
Copy link

jan-dh commented Sep 5, 2017

@damianobarbati any timing on 2.0 out of alpha? 😎
Seems bit tricky for a live app

@hzoo
Copy link
Member

hzoo commented Sep 5, 2017

It's used at behance (where I work), and babel itself and it's a good time to try it. Ok closing since this is done in 2.0

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests