postcss / postcss-load-config

Autoload Config for PostCSS
MIT License
642 stars 72 forks source link

Extending one config with another #179

Closed Grawl closed 5 years ago

Grawl commented 5 years ago

Can't find a way to extend config like I do it with .eslintrc https://eslint.org/docs/user-guide/configuring#extending-configuration-files

michael-ciniawsky commented 5 years ago

It's deliberately not supported atm. What's the use case your are having in particular?

Grawl commented 5 years ago

I have a lot of projects and want to use one pack of plugins on each

Grawl commented 5 years ago

As a workaround, I merge configs with deepmerge like this:

postcss.config.js in project:

const extendBaseConfig = require('my-postcss-config')
module.exports = ctx => extendBaseConfig(ctx, ctx => {
    return {
        plugins: {
            'postcss-easing-gradients': {},
        }
    }
})

my-postcss-config/index.js:

const base = require('./postcss.config')
const merge = require('deepmerge')
module.exports = (ctx, config) => merge([ base(ctx), config(ctx) ])

my-postcss-config/postcss.config.js:

module.exports = ctx => {
    return {
        plugins: {
            'postcss-axis': {},
            'postcss-short': {},
            'postcss-position-alt': {},
            'autoprefixer': {},
        },
    }
}
michael-ciniawsky commented 5 years ago

That's one option and likely better to leave it up to the user to 'extend/merge' parts of his/her config in the way it's intended. Another option would be to wrap plugins as a plugin (e.gcssnano or postcss-preset-env) and add that wrapper plugin ('preset') to the config instead. The reason why I decided against adding any kind of extend to postcss-load-config directly is that plugin order matters

Grawl commented 5 years ago

So, I am doing things right or wrong?

michael-ciniawsky commented 5 years ago

Yeah I think so, you have the full spectrum of JS at our disposal :). Using deepmerge could eventually be avioded but that's enterily preference. Every additional require will of course add a bit of overhead, but that's just how it works...

// preset1.js
const preset1 = (ctx) => ({
  a: { option: 1 },
  b: {}
})

// preset2.js
const preset2 = (ctx) => ({
  a: { option: 2 },
  c: {}
})

// $PROJECT/postcss.config.js
const preset1 = require('./preset1.js')
const preset2 = require('./preset2.js')

const config = (ctx) => ({
  plugins: {
    ...preset1(ctx),
    ...preset2(ctx)
  }
})

// Config { plugins: { a: { option: 2 }, b: {}, c: {} } }
Grawl commented 5 years ago

So I can add one config as plugin in another config?

Grawl commented 5 years ago

Answer to my previous question: no. Michael just shows how Object Rest Spread works.

Just checked it out:

image

Look at {c}, where e field from obj1 is missing in {merged}. So, Object Rest Spread is one-level merge.