New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve config documentation and remove 22 dependencies from cssnano #1168
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"preset": "lite" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import process from 'process'; | ||
import postcss from 'postcss'; | ||
import litePreset from 'cssnano-preset-lite'; | ||
import defaultPreset from 'cssnano-preset-default'; | ||
import cssnano from '../..'; | ||
|
||
/* The configuration is loaded relative to the current working directory, | ||
when running the repository tests, the working directory is | ||
the repostiory root, so we need to change it to avoid having to place | ||
the configuration file for this test in the repo root */ | ||
const spy = jest.spyOn(process, 'cwd'); | ||
spy.mockReturnValue(__dirname); | ||
|
||
test('should read the cssnano configuration file', () => { | ||
const processor = postcss([cssnano]); | ||
expect(processor.plugins.length).toBe(litePreset().plugins.length); | ||
}); | ||
|
||
test('PostCSS config should override the cssnano config', () => { | ||
const processor = postcss([cssnano({ preset: 'default' })]); | ||
expect(processor.plugins.length).toBe(defaultPreset().plugins.length); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
import path from 'path'; | ||
import postcss from 'postcss'; | ||
import { cosmiconfigSync } from 'cosmiconfig'; | ||
import yaml from 'yaml'; | ||
import { lilconfigSync } from 'lilconfig'; | ||
import isResolvable from 'is-resolvable'; | ||
|
||
const cssnano = 'cssnano'; | ||
|
@@ -59,7 +60,7 @@ function resolvePreset(preset) { | |
|
||
/* | ||
* cssnano will look for configuration firstly as options passed | ||
* directly to it, and failing this it will use cosmiconfig to | ||
* directly to it, and failing this it will use lilconfig to | ||
* load an external file. | ||
*/ | ||
|
||
|
@@ -76,7 +77,21 @@ function resolveConfig(options) { | |
configPath = path.resolve(process.cwd(), options.configFile); | ||
} | ||
|
||
const configExplorer = cosmiconfigSync(cssnano); | ||
const configExplorer = lilconfigSync(cssnano, { | ||
searchPlaces: [ | ||
'package.json', | ||
'.cssnanorc', | ||
'.cssnanorc.json', | ||
'.cssnanorc.yaml', | ||
'.cssnanorc.yml', | ||
'.cssnanorc.js', | ||
'cssnano.config.js', | ||
], | ||
loaders: { | ||
'.yaml': (filepath, content) => yaml.parse(content), | ||
'.yml': (filepath, content) => yaml.parse(content), | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if you may also need to add something like It seems like lilconfig uses this as basis for merging in the loaders. Ref. #1168 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like a bit of a bug or design weakness on their part There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've updated the code with explicit search places. I did try renaming the file to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed! And perhaps not such a bad thing for it to be explicit anyway 👍 |
||
}); | ||
const config = configPath | ||
? configExplorer.load(configPath) | ||
: configExplorer.search(searchPath); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,46 +21,84 @@ export const ExampleChart = () => { | |
|
||
<ExampleChart/> | ||
|
||
## `cssnano` config files | ||
You can configure cssnano either in the PostCSS configuration file or in a dedicated cssnano configuration file. The PostCSS configuration file takes precedence over the dedicated cssnano configuration. | ||
If you don't pass any configuration, cssnano runs with the `default` preset. | ||
|
||
|
||
## Configure through PostCSS configuration files | ||
|
||
In the [PostCSS configuration file](https://github.com/postcss/postcss#usage), you can pass both the `preset` and `plugins` options when you add `cssnano` to the PostCSS plugins. For example, if you use PostCSS programmatically, the following uses cssnano with the `lite` preset and adds autoprefixer. | ||
|
||
```js | ||
import postcss from 'postcss'; | ||
import cssnano from 'cssnano'; | ||
import litePreset from 'cssnano-preset-lite'; | ||
import autoprefixer from 'autoprefixer'; | ||
const preset = litePreset({ discardComments: false }); | ||
|
||
postcss([cssnano({ preset, plugins: [autoprefixer] })]).process("/* Your CSS here */") | ||
``` | ||
|
||
## Configure through dedicated `cssnano` configuration | ||
|
||
If you cannot configure cssnano in the PostCSS configuration file, you can configure cssnano with a cssnano configuration option in `package.json` or with a dedicated configuration file. This file can be in different formats. | ||
|
||
* `.cssnanorc.config.json` and `.cssnanorc` must contain a JSON object | ||
* `cssnano.config.js` must export the configuration as a JavaScript object | ||
|
||
We use configuration for `cssnano` using file name as `cssnano.config.js` , `cssnano` property in your `package.json`, using `cssnano.config.json` and `.cssnanorc` as well. | ||
We are using `cosmiconfig` in order to load cssnano config. Please read [here](https://github.com/davidtheclark/cosmiconfig) for more details | ||
|
||
## Options | ||
|
||
### `preset` | ||
|
||
- **Type:** `string` | `function` | `[string, Objects<preset options here>]` | `[function(preset options here)]` | ||
|
||
> For `string`, the name should be of type `cssnano-preset-<name>` and you need to use `name` alone eg : `preset : ['default', {}]` | ||
Pass a preset to choose a pre-configured set of optimizations. You can either import the preset package or use the preset name as a string. | ||
|
||
Contains lists of `postcss` plugins where each plugin does their own minification. | ||
With the preset as import: | ||
ludofischer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- **Example:** | ||
|
||
```js | ||
// cssnano.config.js | ||
module.exports = { | ||
preset: [require('cssnano-preset-default')] | ||
|
||
// or | ||
preset: require('cssnano-preset-default') | ||
|
||
// or | ||
preset: ['advanced', { discardComments: false }] | ||
```js | ||
cssnano({ preset: require('cssnano-preset-default') }) | ||
``` | ||
|
||
Using a string is useful if you use a configuration file in the JSON format. | ||
When you use a string, if the preset is called `cssnano-preset-<name>`, use `name` alone: | ||
|
||
```js | ||
cssnano({ preset: 'default' }) | ||
``` | ||
|
||
Presets themselves can take options. | ||
Pass options to the preset by using an array where the first element is the preset and the second is an object with the preset options. | ||
You can specify a preset with the preset name as a string or by passing the result of importing the preset package. | ||
|
||
```js | ||
// cssnano.config.js | ||
module.exports = { | ||
preset: [ require('cssnano-preset-default'), { discardComments: false } ] | ||
}; | ||
``` | ||
|
||
|
||
You can also pass preset options when you use the preset name as a string: | ||
For example, here's how to deactivate the `discardComments` plugin when using the `advanced` preset: | ||
|
||
```js | ||
cssnano({ preset: ['advanced', { discardComments: false }] }) | ||
``` | ||
|
||
// or | ||
preset: [require('cssnano-preset-default'), {discardComments: false}] | ||
} | ||
``` | ||
|
||
### `plugins` | ||
|
||
- **Type:** `Array<'string' | 'function' | ['string' | 'function', Object<Options for the plugin here>]>` | ||
|
||
> If you want to pass config to the plugin, you need to use Array's of array for the plugins i.e `plugins: [ ['autoprefixer', {}] ]` | ||
In addition to the preset, you can pass a list of plugins to cssnano. | ||
This is equivalent to adding the plugins after cssnano in the PostCSS plugins array. | ||
If you want to configure the individual plugins, use an array of arrays: | ||
|
||
These plugins will run after once all presets operations are complete. | ||
```js | ||
cssnano({ plugins: [['autoprefixer', {}]] }) | ||
``` | ||
|
||
- **Example:** | ||
|
||
|
@@ -84,8 +122,3 @@ These plugins will run after once all presets operations are complete. | |
] | ||
} | ||
``` | ||
|
||
## Alternatives | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The section about the PostCSS config file has been moved to the top as that is what most people will use and the PostCSS config overrides the config in the cssnano files. |
||
|
||
You can use the `postcss` config file and both `preset` and `plugins` will be passed as the options for `cssnano`. | ||
Refer [here](https://github.com/postcss/postcss#usage) for more details. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was uncertain whether to keep YAML config parsing since it was never documented explicitly, but removing would be a breaking change in theory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like a good call to keep it for now, even if the chance of it being used is remote 👍
Question:
Since the tests you added were paired with a
.cssnanorc.json
and you mentioned keeping YAML support, I decided to attempt running the test suite with a.cssnanorc.yaml
and a few other variations (replacing.cssnanorc.json
in theconfig_loading
dir) for the sake of diligence. And it doesn't appear to be picked up.It's entirely possible I'm having some form of "brainfart" and doing something wrong here - but shouldn't that work?
(Out of curiosity I had a look at the
searchItems
found by lilconfig inlilconfigSync.search()
and it only appears to look forpackage.json
,cssnanorc.json
,cssnano.config.js
, andcssnanorc.js
,.cssnanorc.cjs
, andcssnano.config.cjs
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My inner conviction is nobody is really using the YAML format, so I did not bother checking whether it works, I have just copied the instructions on the lilconfig repo. Looking at the
lilconfig
code, it seems it does not even load.rc
(with no extension) by default.