postcss/postcss-load-config

Extending one config with another

Grawl opened this issue · 8 comments

Grawl commented

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

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

Grawl commented

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

Grawl commented

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': {},
		},
	}
}

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

So, I am doing things right or wrong?

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

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

Grawl commented

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.