From b29a8f5a5430a086ade5432b9c77cfad3267e95d Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Wed, 31 Aug 2022 21:22:37 +0200 Subject: [PATCH 1/4] Add ESM plugins support --- lib/processor.js | 3 +++ test/processor.test.ts | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/lib/processor.js b/lib/processor.js index cbbf12d78..5150d4065 100644 --- a/lib/processor.js +++ b/lib/processor.js @@ -32,6 +32,9 @@ class Processor { normalize(plugins) { let normalized = [] for (let i of plugins) { + if (i.__esModule && i.default) { + i = i.default + } if (i.postcss === true) { i = i() } else if (i.postcss) { diff --git a/test/processor.test.ts b/test/processor.test.ts index 09a579c2d..79aac67dc 100755 --- a/test/processor.test.ts +++ b/test/processor.test.ts @@ -578,6 +578,14 @@ test('supports plugin creators returning processors', () => { equal(processor.plugins, [a]) }) +test('supports default ESM export wrap for plugins', () => { + let a = (): void => {} + let mod = { __esModule: true, default: a } as any + let processor = new Processor() + processor.use(mod) + equal(processor.plugins, [a]) +}) + test('uses custom syntax for document', async () => { let customParser: Parser = () => { return new Document({ From 0b5728372bf57d39335e18eec09583ff34d55c74 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 3 Sep 2022 09:46:23 +0200 Subject: [PATCH 2/4] Update plugin examples to make ESM API more clear --- docs/guidelines/plugin.md | 25 +++++++++++++------------ docs/writing-a-plugin.md | 13 ++++++++----- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/docs/guidelines/plugin.md b/docs/guidelines/plugin.md index 88a0ed497..cfb2d20cf 100644 --- a/docs/guidelines/plugin.md +++ b/docs/guidelines/plugin.md @@ -72,14 +72,15 @@ It is better even not to import `postcss`. ```diff - const { list, decl } = require('postcss') - module.exports = opts => { + const plugin = opts => { postcssPlugin: 'postcss-name', - Once (root) { + Once (root, { list, decl }) { // Plugin code } } - module.exports.postcss = true + plugin.postcss = true + module.exports = plugin ``` @@ -88,7 +89,7 @@ It is better even not to import `postcss`. Plugin name will be used in error messages and warnings. ```js -module.exports = opts => { +const plugin = opts => { return { postcssPlugin: 'postcss-name', Once (root) { @@ -96,7 +97,7 @@ module.exports = opts => { } } } -module.exports.postcss = true +plugin.postcss = true ``` @@ -117,7 +118,7 @@ For example, use `fs.writeFile` instead of `fs.writeFileSync`: ```js let { readFile } = require('fs').promises -module.exports = opts => { +const plugin = opts => { return { postcssPlugin: 'plugin-inline', async Decl (decl) { @@ -129,7 +130,7 @@ module.exports = opts => { } } } -module.exports.postcss = true +plugin.postcss = true ``` ### 2.3. Use fast node’s scanning @@ -137,7 +138,7 @@ module.exports.postcss = true Subscribing for specific node type is much faster, than calling `walk*` method: ```diff - module.exports = { + const plugin = () => ({ postcssPlugin: 'postcss-example', - Once (root) { - root.walkDecls(decl => { @@ -147,15 +148,15 @@ Subscribing for specific node type is much faster, than calling `walk*` method: + Declaration (decl) { + // Faster + } - } - module.exports.postcss = true + }) + plugin.postcss = true ``` But you can make scanning even faster, if you know, what declaration’s property or at-rule’s name do you need: ```diff - module.exports = { + const plugin = () => ({ postcssPlugin: 'postcss-example', - Declaration (decl) { - if (decl.prop === 'color') { @@ -167,8 +168,8 @@ or at-rule’s name do you need: + // The fastest + } + } - } - module.exports.postcss = true + }) + plugin.postcss = true ``` diff --git a/docs/writing-a-plugin.md b/docs/writing-a-plugin.md index 8afa7f279..8fc1acc0a 100644 --- a/docs/writing-a-plugin.md +++ b/docs/writing-a-plugin.md @@ -85,14 +85,16 @@ Every time when you will update the config, it will update development configs and development tools. ```js -module.exports = (opts = {}) => { +const plugin = (opts = {}) => { // Plugin creator to check options or prepare caches return { postcssPlugin: 'PLUGIN NAME' // Plugin listeners } } -module.exports.postcss = true +plugin.postcss = true + +module.exports = plugin ``` [PostCSS plugin boilerplate]: https://github.com/postcss/postcss-plugin-boilerplate/ @@ -128,7 +130,7 @@ how PostCSS convert different CSS to AST. You can find all nodes with specific types by adding method to plugin object: ```js -module.exports = (opts = {}) => { +const plugin = (opts = {}) => { return { postcssPlugin: 'PLUGIN NAME', Once (root) { @@ -139,7 +141,7 @@ module.exports = (opts = {}) => { } } } -module.exports.postcss = true +plugin.postcss = true ``` Here is the full list of [plugin’s events](https://postcss.org/api/#plugin). @@ -199,7 +201,7 @@ You may want to re-use some data between listeners. You can do with runtime-defined listeners: ```js -module.exports = (opts = {}) => { +const plugin = (opts = {}) => { return { postcssPlugin: 'vars-collector', prepare (result) { @@ -217,6 +219,7 @@ module.exports = (opts = {}) => { } } } +plugin.postcss = true ``` You can use `prepare()` to generate listeners dynamically. For instance, From 21cfa7ea1990c847a8f1d475e6b18e068f4fefe7 Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 3 Sep 2022 09:46:45 +0200 Subject: [PATCH 3/4] Remove Sharec config --- docs/writing-a-plugin.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/writing-a-plugin.md b/docs/writing-a-plugin.md index 8fc1acc0a..63cc12127 100644 --- a/docs/writing-a-plugin.md +++ b/docs/writing-a-plugin.md @@ -80,10 +80,6 @@ For public plugins: 2. Create a repository on GitHub or GitLab. 3. Publish your code there. -You can also use [our Sharec config] to keep the best practices up to date. -Every time when you will update the config, it will update development configs -and development tools. - ```js const plugin = (opts = {}) => { // Plugin creator to check options or prepare caches @@ -98,7 +94,6 @@ module.exports = plugin ``` [PostCSS plugin boilerplate]: https://github.com/postcss/postcss-plugin-boilerplate/ -[our Sharec config]: https://github.com/postcss/postcss-sharec-config [plugin template]: https://github.com/postcss/postcss-plugin-boilerplate/blob/main/template/index.t.js From e3a67482b1a5a7d42e8739343be8c540f5b75b9e Mon Sep 17 00:00:00 2001 From: Andrey Sitnik Date: Sat, 3 Sep 2022 09:49:06 +0200 Subject: [PATCH 4/4] Add ESM example --- docs/writing-a-plugin.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/writing-a-plugin.md b/docs/writing-a-plugin.md index 63cc12127..ba076c8e6 100644 --- a/docs/writing-a-plugin.md +++ b/docs/writing-a-plugin.md @@ -93,6 +93,12 @@ plugin.postcss = true module.exports = plugin ``` +For ESM project replace last line with: + +```js +export default plugin +``` + [PostCSS plugin boilerplate]: https://github.com/postcss/postcss-plugin-boilerplate/ [plugin template]: https://github.com/postcss/postcss-plugin-boilerplate/blob/main/template/index.t.js