-
Notifications
You must be signed in to change notification settings - Fork 56
Fix Bug That Skips doiuse When Used With An Empty Configuration #170
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
base: master
Are you sure you want to change the base?
Conversation
…tcss-load-config reads plugins
|
Thanks for the PR! I'd really hard to gauge what you're trying to accomplish. It would have been best to file an issue first targeting this. Rewriting the entire structure of the files and changing their imports does not sound necessary. It sounds like you can accomplish what you want with a static property or function, or just reframe the exports which is for use with CommonJS. Can you build a test that would fail on the current branch, but pass on the PR? It would better serve to fix the issue with more minimal changes. |
|
Hey there! I went ahead and implemented a new test that fails on the current branch but passes on the PR like you asked.
Do you mean something like this? I tried it but it failed the test. |
|
You don't have to rewrite the whole structure. Basically, the commonjs import expects You can just do this: import DoIUse from '../lib/DoIUse.js';
/**
* @param {ConstructorParameters<typeof DoIUse>} options
* @return {DoIUse}
*/
export default function index(...options) {
return new DoIUse(...options);
}
+index.postcss = new DoIUse().postcss;I should probably rewrite the |
clshortfuse
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only modify the exports/index.js file match the old 5.x export (see PR comment).
… how postcss-load-config reads plugins" This reverts commit 72577bb.
|
Done! Sorry for the delay |
BUG: postcss will skip
doiuseif the configuration is in object format and the options fordoiuseis set as an empty object.Minimal repro: https://stackblitz.com/edit/vitejs-vite-f8xwph
A few things to note:
Plugin author (
doiuse) -> exports plugin with options as the only parameterpostcss-load-config-> responsible for loading the configuration and returning a config object with apluginsfieldpostcss -> responsible for executing the transformation by using the result of
postcss-load-config(config.plugins);THE FOLLOWING HAPPENS IN
postcss-load-config:options = the postcss config file (e.g.: postcss.config.js)
if options.plugin is an array:
1. store the plugins as is (plugins in arrays are stored as a require call, meaning the result is an import).
2. if
plugin.postcssis exactly true, store the plugin as the result of calling the default import of the plugin without any options.3. if
plugin.postcssis not true but is still a truthy value, store the plugin asplugin.postcss(I think this is for old plugin shapes).else if options.plugins is an object:
if
options.plugins[plugin](the options for a plugin, where plugin is the name of the plugin) is an empty object:postcss-load-configwill store the plugin as a default import of the plugin. (KEEP THIS IN MIND)else:
postcss-load-configwill store the plugin as the result of calling the default import of the plugin with the optionsAfter all this, store the results in an array.
THE FOLLOWING HAPPENS IN postcss:
if the array containing the plugins is inside a one-element array, flatten it.
if the property
postcssexists in the top-level of the plugin and is a function, let it be the plugin itselfThis is a loop from postcss that loops through every plugin:
Basically all you need to know about the code above is that
doiusecurrently fails the first if-else-if block and gets pushed as the unwrapped function tonormalized(your local array of plugins).This is solely because you wrapped
DoIUsein an index function, and if you follow the code flow above, you'll notice thatDoIUsewill arrive at the loop as a reference to the the wrapper function, since it doesn't actually contain the members of
DoIUsebecause it hasn't been instantiated,i.postcsswill be undefined, and the reference will just be a regular function.So the result is: probably somewhere down the chain,
postcsswill execute your plugin but, since it's wrapped, an instance of the plugin will be returned and nothing will actually get executed leading to your plugin getting sneakily skipped, without even a warning!WHY THIS (PROBABLY) SHOULDN'T BE FIXED IN POSTCSS OR POSTCSS-LOAD-CONFIG
I took a better look at the source code for both of these projects and realized that
postcss-load-configwill not execute plugins with an empty configuration because that's the way it identifies plugins that take the shape of TransformCallback, Plugin, and Processor which are all valid plugin types that can't be executed bypostcss-load-configWhy can't they be executed?
TransformCallback: This is the most simple type, being just a function without any wrappers, if executed by
postcss-load-configit will just execute the plugin beforepostcsshas a chance to.Plugin: It's a simple object without a
[[call]]slot, can't be called.Processor: Also a simple object.
When compared to PluginCreator for example, we can see why
postcss-load-configchose this strategy.It's because
PluginCreatoraccepts options and can be safely called bypostcss-load-configto return either aPluginor aProcessorwhich will then be passed topostcss.Unfortunately, by choosing to identify objects this way, we can't differentiate objects without configuration from wrapped objects without configuration, and thus, we can't unwrap it, leaving
postcsswith an invalid plugin type.Other solutions:
postcss, check if it returned another plugin by creating anotherProcessorbut ignoring any errors thrown because that'd just mean the plugin isn't wrapped.I will also be opening an issue on the
postcss-load-configrepo to know why this distinction between empty configurations is a thing and if we can change it.TLDR:
doiuseis being skipped when used with empty options while in an object configuration becausepostcss-load-configcan't reliably unwrapdoiuseand the result makes postcss confusedPossibly related to #152
Fixes this comment
Fixes this comment
Fixes this comment