Skip to content
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

Add ESM plugins support #1773

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 13 additions & 12 deletions docs/guidelines/plugin.md
Expand Up @@ -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
```


Expand All @@ -88,15 +89,15 @@ 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) {
// Plugin code
}
}
}
module.exports.postcss = true
plugin.postcss = true
```


Expand All @@ -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) {
Expand All @@ -129,15 +130,15 @@ module.exports = opts => {
}
}
}
module.exports.postcss = true
plugin.postcss = true
```

### 2.3. Use fast node’s scanning

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 => {
Expand All @@ -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') {
Expand All @@ -167,8 +168,8 @@ or at-rule’s name do you need:
+ // The fastest
+ }
+ }
}
module.exports.postcss = true
})
plugin.postcss = true
```


Expand Down
24 changes: 14 additions & 10 deletions docs/writing-a-plugin.md
Expand Up @@ -80,23 +80,26 @@ 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
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
```

For ESM project replace last line with:

```js
export default 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


Expand Down Expand Up @@ -128,7 +131,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) {
Expand All @@ -139,7 +142,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).
Expand Down Expand Up @@ -199,7 +202,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) {
Expand All @@ -217,6 +220,7 @@ module.exports = (opts = {}) => {
}
}
}
plugin.postcss = true
```

You can use `prepare()` to generate listeners dynamically. For instance,
Expand Down
3 changes: 3 additions & 0 deletions lib/processor.js
Expand Up @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions test/processor.test.ts
Expand Up @@ -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<Document> = () => {
return new Document({
Expand Down