Skip to content

Commit

Permalink
feat: added the implementation option (#511)
Browse files Browse the repository at this point in the history
  • Loading branch information
phated authored Jan 21, 2021
1 parent d7657e5 commit deac978
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 1 deletion.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,37 @@ module.exports = {
};
```

### `implementation`

Type: `Function`

The special `implementation` option determines which implementation of PostCSS to use. Overrides the locally installed `peerDependency` version of `postcss`.

**This option is only really useful for downstream tooling authors to ease the PostCSS 7-to-8 transition.**

**webpack.config.js**

```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{
loader: "postcss-loader",
options: { implementation: require("postcss") },
},
{ loader: "sass-loader" },
],
},
],
},
};
```

## Examples

### SugarSS
Expand Down
7 changes: 6 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export default async function loader(content, sourceMap, meta) {
? true
: options.postcssOptions.config;

const postcssFactory = options.implementation || postcss;

let loadedConfig;

if (configOption) {
Expand Down Expand Up @@ -105,7 +107,10 @@ export default async function loader(content, sourceMap, meta) {
let result;

try {
result = await postcss(plugins).process(root || content, processOptions);
result = await postcssFactory(plugins).process(
root || content,
processOptions
);
} catch (error) {
if (error.file) {
this.addDependency(error.file);
Expand Down
4 changes: 4 additions & 0 deletions src/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
"sourceMap": {
"description": "Enables/Disables generation of source maps (https://github.com/postcss/postcss-loader#sourcemap)",
"type": "boolean"
},
"implementation": {
"description": "The implementation of postcss to use, instead of the locally installed version (https://github.com/postcss/postcss-loader#implementation)",
"instanceof": "Function"
}
},
"additionalProperties": false
Expand Down
52 changes: 52 additions & 0 deletions test/__snapshots__/implementation.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`"implementation" option should work with a custom instance of PostCSS: css 1`] = `
"a {
color: black;
}
a {
color: red;
}
a {
color: green;
}
a {
color: blue;
}
.class {
-x-border-color: blue blue *;
-x-color: * #fafafa;
}
.class-foo {
-z-border-color: blue blue *;
-z-color: * #fafafa;
}
.phone {
&_title {
width: 500px;
@media (max-width: 500px) {
width: auto;
}
body.is_dark & {
color: white;
}
}
img {
display: block;
}
}
"
`;

exports[`"implementation" option should work with a custom instance of PostCSS: errors 1`] = `Array []`;

exports[`"implementation" option should work with a custom instance of PostCSS: warnings 1`] = `Array []`;
30 changes: 30 additions & 0 deletions test/__snapshots__/validate-options.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,36 @@ exports[`validate options should throw an error on the "execute" option with "te
-> Enables/Disables PostCSS parser support in 'CSS-in-JS' (https://github.com/postcss/postcss-loader#execute)"
`;

exports[`validate options should throw an error on the "implementation" option with "/test/" value 1`] = `
"Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.
- options.implementation should be an instance of function.
-> The implementation of postcss to use, instead of the locally installed version (https://github.com/postcss/postcss-loader#implementation)"
`;

exports[`validate options should throw an error on the "implementation" option with "[]" value 1`] = `
"Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.
- options.implementation should be an instance of function.
-> The implementation of postcss to use, instead of the locally installed version (https://github.com/postcss/postcss-loader#implementation)"
`;

exports[`validate options should throw an error on the "implementation" option with "{}" value 1`] = `
"Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.
- options.implementation should be an instance of function.
-> The implementation of postcss to use, instead of the locally installed version (https://github.com/postcss/postcss-loader#implementation)"
`;

exports[`validate options should throw an error on the "implementation" option with "1" value 1`] = `
"Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.
- options.implementation should be an instance of function.
-> The implementation of postcss to use, instead of the locally installed version (https://github.com/postcss/postcss-loader#implementation)"
`;

exports[`validate options should throw an error on the "implementation" option with "something" value 1`] = `
"Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.
- options.implementation should be an instance of function.
-> The implementation of postcss to use, instead of the locally installed version (https://github.com/postcss/postcss-loader#implementation)"
`;

exports[`validate options should throw an error on the "postcssOptions" option with "{"config":[]}" value 1`] = `
"Invalid options object. PostCSS Loader has been initialized using an options object that does not match the API schema.
- options.postcssOptions should be one of these:
Expand Down
26 changes: 26 additions & 0 deletions test/implementation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import postcss from "postcss";

import {
compile,
getCompiler,
getErrors,
getCodeFromBundle,
getWarnings,
} from "./helpers";

describe('"implementation" option', () => {
it("should work with a custom instance of PostCSS", async () => {
const spy = jest.fn(postcss);
const compiler = getCompiler("./css/index.js", {
// Wrap the spy so it is an instanceof Function
implementation: (...args) => spy(...args),
});
const stats = await compile(compiler);
const codeFromBundle = getCodeFromBundle("style.css", stats);

expect(spy).toHaveBeenCalledTimes(1);
expect(codeFromBundle.css).toMatchSnapshot("css");
expect(getWarnings(stats)).toMatchSnapshot("warnings");
expect(getErrors(stats)).toMatchSnapshot("errors");
});
});
4 changes: 4 additions & 0 deletions test/validate-options.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ describe("validate options", () => {
success: [true, false],
failure: [1, /test/, [], {}, "something"],
},
implementation: {
success: [require("postcss")],
failure: [1, /test/, [], {}, "something"],
},
};

function stringifyValue(value) {
Expand Down

0 comments on commit deac978

Please sign in to comment.