Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 82 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ If you use JS styles without the [`postcss-js`][postcss-js] parser, add the `exe
Type: `Boolean|String|Object`
Default: `undefined`

Options specified in the config file are combined with options passed to the loader.
Loader options overwrite options from config.

#### Boolean

Enables/Disables autoloading config.
Expand Down Expand Up @@ -264,21 +267,89 @@ module.exports = ({ file, options, env }) => ({
**`webpack.config.js`**

```js
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: (loader) => [
require('postcss-import')({ root: loader.resourcePath }),
require('postcss-preset-env')(),
require('cssnano')()
]
}
}
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: (loader) => [
require('postcss-import')({ root: loader.resourcePath }),
require('postcss-preset-env')(),
require('cssnano')(),
],
},
},
],
},
};
```

> ⚠️ webpack requires an identifier (`ident`) in `options` when `{Function}/require` is used (Complex Options). The `ident` can be freely named as long as it is unique. It's recommended to name it (`ident: 'postcss'`)

**`webpack.config.js`**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: {
'postcss-import': {},
'postcss-nested': {},
'postcss-short': { prefix: 'x' },
},
},
},
],
},
};
```

It is possible to disable the plugin specified in the config.

**`postcss.config.js`**

```js
module.exports = {
plugins: {
'postcss-short': { prefix: 'x' },
'postcss-import': {},
'postcss-nested': {},
},
};
```

**`webpack.config.js`**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: {
'postcss-import': {},
'postcss-nested': {},
// Turn off the plugin
'postcss-short': false,
},
},
},
],
},
};
```

### `Syntaxes`

| Name | Type | Default | Description |
Expand Down
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ export default async function loader(content, sourceMap, meta = {}) {

let plugins;

const disabledPlugins = [];

try {
plugins = [
...getArrayPlugins(loadedConfig.plugins, file),
...getArrayPlugins(options.plugins, file),
];
...getArrayPlugins(options.plugins, file, disabledPlugins),
].filter((i) => !disabledPlugins.includes(i.postcssPlugin));
} catch (error) {
this.emitError(error);
}
Expand Down
19 changes: 17 additions & 2 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ function getPlugin(pluginEntry) {
return Array.isArray(result) ? result : [result];
}

function getArrayPlugins(plugins, file) {
function getArrayPlugins(plugins, file, disabledPlugins) {
if (Array.isArray(plugins)) {
return plugins.reduce((accumulator, plugin) => {
// eslint-disable-next-line no-param-reassign
Expand All @@ -180,7 +180,22 @@ function getArrayPlugins(plugins, file) {
return [];
}

return getArrayPlugins(loadPlugins(plugins, file), file);
const statePlagins = {
enabled: {},
disabled: disabledPlugins || [],
};

Object.entries(plugins).forEach((plugin) => {
const [name, options] = plugin;

if (options === false) {
statePlagins.disabled.push(name);
} else {
statePlagins.enabled[name] = options;
}
});

return getArrayPlugins(loadPlugins(statePlagins.enabled, file), file);
}

return getPlugin(plugins);
Expand Down
7 changes: 7 additions & 0 deletions test/fixtures/css/plugins.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
plugins: {
'postcss-short': { prefix: 'x' },
'postcss-import': {},
'postcss-nested': {},
}
}
12 changes: 12 additions & 0 deletions test/options/__snapshots__/plugins.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Options Plugins should disables plugin from config: css 1`] = `
"a {
-x-border-color: blue blue *;
-x-color: * #fafafa;
}
"
`;

exports[`Options Plugins should disables plugin from config: errors 1`] = `Array []`;

exports[`Options Plugins should disables plugin from config: warnings 1`] = `Array []`;

exports[`Options Plugins should emit error on load plugin: errors 1`] = `
Array [
"ModuleBuildError: Module build failed (from \`replaced original path\`):
Expand Down
16 changes: 16 additions & 0 deletions test/options/plugins.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,22 @@ describe('Options Plugins', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should disables plugin from config', async () => {
const compiler = getCompiler('./css/index2.js', {
config: 'test/fixtures/css/plugins.config.js',
plugins: {
'postcss-short': false,
},
});
const stats = await compile(compiler);

const codeFromBundle = getCodeFromBundle('style2.css', stats);

expect(codeFromBundle.css).toMatchSnapshot('css');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should emit error on load plugin', async () => {
const compiler = getCompiler('./css/index2.js', {
plugins: {
Expand Down