For now plugins are "all or nothing". In my case it Lit:
{
litelement: true,
}
Here's a case why it was not good enough for me, how I solved it and what I propose to make it more approachable:
What was not OK with defaults for me
I made a decision to amend my LitElements with an override of createProperty:
@customElement('my-element')
export class MyElement extends LitElement) {
static override createProperty(name, options) {
super.createProperty(name, kebabAttribute(name, options));
}
// quite a lot of properties which some are 2 or more words and
// I didn't fancy the default policy of "just lowercase the property"
// I also want not to express them all because it makes the bundle
// bigger and code harder to read
}
(BTW: I think there's a bug in reflect logic - it assumes that reflected attribute is given explicitly. I need to think about it some more before I can be sure)
So: I got what I wanted, but it's WAAAAY too much bound to the internal implementation.
It's not what I want to maintain or leave my colleagues to maintain, so...
Step 3: "Fix it later"
I wrote my own plugin to adjust what I don't like about the default one:
import kebabCase from 'just-kebab-case';
export default function kebabCaseAttributesPlugin() {
const name = 'kebabCase-attributes';
const is = expectedKind => ({kind}) => kind === expectedKind
const has = expectedProp => member => expectedProp in member;
const attributeMatches = regexp => memberWithAttribute => regexp.test(memberWithAttribute.attribute)
return {
name,
moduleLinkPhase({moduleDoc, context}) {
if (moduleDoc.kind !== 'javascript-module') {
return;
}
moduleDoc.declarations
.filter(is('class'))
.forEach(({members}) => members
.filter(is('field'))
.filter(has('attribute'))
.filter(attributeMatches(/[A-Z]/))
.forEach(member => {
const kebabCased = kebabCase(member.attribute);
if (context.dev) {
console.log(`[${name}] ${member.attribute} -> ${kebabCased}`);
}
member.attribute = kebabCased;
})
);
}
}
}
I'm leaving it in here for reference, maybe someone will benefit from it.
I'm a rookie in WebComponents and I started using the analyser 2h ago, but I'm a JS dev with 10y+ exp, so it was quite easy for me (btw - kudos for plugin architecture, It was that easy because I made use of terrific idea to allow moduleLinkPhase), but it's not exactly the greatest DX for people with less experience.
What I propose to discuss
define LitPluginOptions
allow passing it instead of true to litelement
distribute values from LitPluginOptions to plugins
Or maybe include some examples of how to adjust the output for one's needs as I did.
Either way discussing what might get configured is a first step for both.
Truth to be said: providing tips on how to adjust it with ones own plugin promotes building more plugins and building awareness that it's not that hard to build plugins on one's own, so maybe the latter is even better than allowing configuration. For sure it's less of a maintainer load.
For now plugins are "all or nothing". In my case it Lit:
Here's a case why it was not good enough for me, how I solved it and what I propose to make it more approachable:
What was not OK with defaults for me
I made a decision to amend my LitElements with an override of createProperty:
LitPlugin
(obviously) does not know about this decision because decision is executed in runtime.What I did
Step 1: Decompose
It gave the same result (even though I know it's at a cost of maintenance if internal structure would change), so
Step 2: Try configuring
propertyDecoratorPlugin
Aaaaaand... it's gone. Plugin is written in such way that it takes no config.
Step 2.1: Reimplement
propertyDecoratorPlugin
Shortening things up:
https://github.com/open-wc/custom-elements-manifest/blob/ce0262bb7d6baae89ec22c6dfce487e5eaf7bfed/packages/analyzer/src/features/framework-plugins/lit/property-decorator.js#L67-L78
(BTW: I think there's a bug in reflect logic - it assumes that reflected attribute is given explicitly. I need to think about it some more before I can be sure)
So: I got what I wanted, but it's WAAAAY too much bound to the internal implementation. It's not what I want to maintain or leave my colleagues to maintain, so...
Step 3: "Fix it later"
I wrote my own plugin to adjust what I don't like about the default one:
I'm leaving it in here for reference, maybe someone will benefit from it.
I'm a rookie in WebComponents and I started using the analyser 2h ago, but I'm a JS dev with 10y+ exp, so it was quite easy for me (btw - kudos for plugin architecture, It was that easy because I made use of terrific idea to allow
moduleLinkPhase
), but it's not exactly the greatest DX for people with less experience.What I propose to discuss
LitPluginOptions
true
tolitelement
LitPluginOptions
to pluginsOr maybe include some examples of how to adjust the output for one's needs as I did. Either way discussing what might get configured is a first step for both.
Truth to be said: providing tips on how to adjust it with ones own plugin promotes building more plugins and building awareness that it's not that hard to build plugins on one's own, so maybe the latter is even better than allowing configuration. For sure it's less of a maintainer load.