Skip to content

[Proposal] Add supportedDependencyTypes documentation#1585

Closed
bradlc wants to merge 1 commit intopostcss:mainfrom
bradlc:supported-dependency-types
Closed

[Proposal] Add supportedDependencyTypes documentation#1585
bradlc wants to merge 1 commit intopostcss:mainfrom
bradlc:supported-dependency-types

Conversation

@bradlc
Copy link
Copy Markdown
Contributor

@bradlc bradlc commented May 18, 2021

This pull request adds documentation for a way that PostCSS runners can specify which dependency types they support. Now that we have more than one dependency type, I think it is important that plugins are aware of which dependency types are available to them, and which aren't.

My proposal is for runners to define a supportedDependencyTypes option when running PostCSS:

processor.process({
  from: file.path,
  to: file.path,
  supportedDependencyTypes: ['dependency', 'dir-dependency']
})

Then, plugins can read this from result.opts:

if (result.opts.supportedDependencyTypes.includes('dir-dependency')) {
  // register directory dependency
} else {
  throw Error('Runner does not support the required dependency types.')
}

This provides a better experience for PostCSS users, because plugins can present clear errors when required dependency types are not available. It also allows plugins to register dependencies with confidence, knowing that they will be handled by the runner. Currently there is no way to know that a dir-dependency message has been handled. This can lead to plugins silently not working correctly and frustrated users.

Here's another concrete example: if we added a new glob-dependency type (as discussed over on the Parcel repo) plugins could make a decision about which dependencies to register, based on which types the runner supports:

let pattern = '/src/**/*.html'
let supportsGlobDependencies = result.opts.supportedDependencyTypes?.includes('glob-dependency')
let supportsDirectoryDependencies = result.opts.supportedDependencyTypes?.includes('dir-dependency')

if (supportsGlobDependencies) {
  messages.push({ type: 'glob-dependency', glob: pattern })
} else if (supportsDirectoryDependencies) {
  messages.push({ type: 'dir-dependency', dir: getBase(pattern) })
} else {
  throw Error('Runner does not support the required dependency types.')
}

Some runners may not be able to support glob dependencies at all, and this would allow plugins to maximise compatibility.

This is just one idea and I am curious to hear what you think of it. Feedback and suggestions welcome, thanks!

@ai
Copy link
Copy Markdown
Member

ai commented May 18, 2021

I do not like the idea that a plugin should throw an error. There are a lot of use case, when we do not have watch mode and dir-dependencies support mean nothing.

I can accept it only if we will find a better UX for plugins. But I am not sure that we need it.

@bradlc
Copy link
Copy Markdown
Contributor Author

bradlc commented May 18, 2021

I do not like the idea that a plugin should throw an error.

What do you recommend a plugin do if it can't run in the user's environment?

[...] when we do not have watch mode and dir-dependencies support mean nothing.

I do not think that is the case when a runner has persistent caching like webpack 5 does. The cache is maintained across separate builds so the dependencies are taken into account.

@ai
Copy link
Copy Markdown
Member

ai commented May 18, 2021

What do you recommend a plugin do if it can't run in the user's environment?

What plugin requires dependency messages to work not in watch mode?

I do not think that is the case when a runner has persistent caching like webpack 5 does. The cache is maintained across separate builds so the dependencies are taken into account.

Don’t forget about postcss-cli and gulp-postcss runners. They do not have caches and watch mode is rarely used.

@bradlc
Copy link
Copy Markdown
Contributor Author

bradlc commented May 18, 2021

What plugin requires dependency messages to work not in watch mode?

Any plugin, when using a runner that uses persistent caching, like webpack 5 (with opt-in). Here's an example with instructions: https://github.com/bradlc/postcss-webpack5

@ai
Copy link
Copy Markdown
Member

ai commented May 18, 2021

Any plugin, when using a runner that uses persistent caching, like webpack 5 (with opt-in). Here's an example with instructions: https://github.com/bradlc/postcss-webpack5

I am asking about the opposite question. If we run PostCSS plugin with dir-dependency messages in gulp-postcss (which has no any dependency messages support), what will be the problem?

@bradlc
Copy link
Copy Markdown
Contributor Author

bradlc commented May 18, 2021

Ah sorry. So the problem would be that if my plugin reads the content from files in the example directory, it needs to re-run when files in that directory change. If a runner doesn't support dir-dependency then this won't happen, and my plugin won't work as expected.

@ai
Copy link
Copy Markdown
Member

ai commented May 18, 2021

But gulp-postcss is often build CSS from the scratch without any caches. If you throw an error on no dir-dependency, plugin will not work in postcss-cli and gulp-postcss.

})
```

### 3.2. Detect available dependency types
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to not do it mandatory and only add supportedDependencyTypes to types

@bradlc
Copy link
Copy Markdown
Contributor Author

bradlc commented May 18, 2021

But gulp-postcss is often build CSS from the scratch without any caches. If you throw an error on no dir-dependency, plugin will not work in postcss-cli and gulp-postcss.

Ooh I see what you mean now I think! So gulp-postcss will say "I don't support any dependency types" because it doesn't actually do anything with the messages (because it doesn't need to). Got it. That is a good point. What if gulp-postcss declared that it supports them even though it doesn't actually do anything with them? Not a very elegant solution though.

@devongovett
Copy link
Copy Markdown

Would it make sense to not throw when no dependency types are supported but just not emit anything? In that case, there's no watcher anyway, so there's no reason it should break.

@ai
Copy link
Copy Markdown
Member

ai commented May 30, 2021

Yeap, let's be remove the error from examples. I think we should not add any rules to plugin guidelines. Only to runner guidelines.

@DeMoorJasper
Copy link
Copy Markdown

Mentioned an alternative to the glob/dir dependency in the Parcel PR that might remove the need for the functionality proposed in this PR

@bradlc Maybe you could merge the glob and dir dependency message into a singular dir-dependency message? This would probably simplify the logic quite a bit and not require any type of registering which dependency types are supported:

Currently

{ "type": "dir-dependency", "dir": "/src/" }

with glob (glob is relative to dir) - the glob would be optional so plugins can choose to add it or leave it out

{ "type": "dir-dependency", "dir": "/src/", "glob": "**/*.html" }

@ai
Copy link
Copy Markdown
Member

ai commented May 31, 2021

I like glob as an extension!

@bradlc
Copy link
Copy Markdown
Contributor Author

bradlc commented Jun 1, 2021

@DeMoorJasper I like it! 🙌 Opened a new pull request for that as an alternative to this one 👍

@ai ai closed this Nov 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants