ionic-team / stencil-eslint Goto Github PK
View Code? Open in Web Editor NEWESLint rules specific to Stencil JS projects
License: MIT License
ESLint rules specific to Stencil JS projects
License: MIT License
When adding the plugin to my eslint extends:
"extends": [
"plugin:@stencil/recommended",
I started getting the following error:
Oops! Something went wrong! :(
ESLint: 7.11.0
TypeError: Cannot read property 'typeAnnotation' of undefined
Occurred while linting C:\MyOrg\MyProj\src\components\org-component\org-component.tsx:14
at getType (C:\MyOrg\MyProj\node_modules\@stencil\eslint-plugin\dist\index.js:65:32)
at ClassProperty > Decorator[expression.callee.name=Element] (C:\MyOrg\MyProj\node_modules\@stencil\eslint-plug
in\dist\index.js:439:37)
at C:\MyOrg\MyProj\node_modules\eslint\lib\linter\safe-emitter.js:45:58
at Array.forEach (<anonymous>)
at Object.emit (C:\MyOrg\MyProj\node_modules\eslint\lib\linter\safe-emitter.js:45:38)
at NodeEventGenerator.applySelector (C:\MyOrg\MyProj\node_modules\eslint\lib\linter\node-event-generator.js:254
:26)
at NodeEventGenerator.applySelectors (C:\MyOrg\MyProj\node_modules\eslint\lib\linter\node-event-generator.js:28
3:22)
at NodeEventGenerator.enterNode (C:\MyOrg\MyProj\node_modules\eslint\lib\linter\node-event-generator.js:297:14)
at CodePathAnalyzer.enterNode (C:\MyOrg\MyProj\node_modules\eslint\lib\linter\code-path-analysis\code-path-anal
yzer.js:711:23)
at C:\MyOrg\MyProj\node_modules\eslint\lib\linter\linter.js:952:32
error Command failed with exit code 2.
The stacktrace pointed to my component, where I had a property with no type annotation:
@Component({
tag: 'org-component',
shadow: true,
})
export class OrgComponent implements ComponentWillLoad {
@Element() host;
Enabling TypeScript's noImplicitAny
and then adding a type annotation fixes this issue and lets the linter continue:
@Component({
tag: 'org-component',
shadow: true,
})
export class OrgComponent implements ComponentWillLoad {
@Element() host: HTMLOrgComponentElement;
The own-props-must-be-private
persists even for private properties. E.g.
@Component(/* ... */)
class MyComponent {
#privateProperty = "secret"; // <-- false positive
}
0.4.0
We created a component with results
as property:
@Prop() results: ResultItem[];
Yet, in React we were unable to bind the correct data:
'{ ... }[]' is not assignable to type 'ResultItem[] & number'.
Type '{ ... }[]' is not assignable to type 'number'
Completely confused where the intersection type & number
was coming from.
After digging into Stencil we found that results
was already defined on HTMLAttributes
interface as a number: https://github.com/ionic-team/stencil/blob/main/src/declarations/stencil-public-runtime.ts#L1300
Stencil ESlinter missed this reserved property. It's not present in the reserved member rule, which should warn for these.
And we found more unusable / reserved properties by comparing HTMLAttributes
interface with the linting rule:
Set(29) {
'class',
'contextmenu',
'hidden',
'spellcheck',
'tabindex?',
'inputmode',
'enterkeyhint',
'is',
'radiogroup',
'role',
'about',
'datatype',
'inlist',
'property',
'resource',
'typeof',
'vocab',
'autocapitalize',
'autocorrect',
'autosave',
'color',
'itemprop',
'itemscope',
'itemtype',
'itemid',
'itemref',
'results',
'security',
'unselectable'
}
We verified this with a couple of these properties and got the same behavior as with results
The reserved member linting rule should match the reserved properties in Stencil: https://github.com/ionic-team/stencil/blob/main/src/declarations/stencil-public-runtime.ts#L1238.
Compare the reserved properties in Stencil with the reserved member linting rule. Or check the reproduce script.
Stencil:
export class Component {
@Prop() results: string;
render() {
return (
<div>
{results}
</div>
);
}
}
React: (with Stencil react output)
<Component results="123"></Component>
Results
ERROR in apps/react/src/app/app.tsx:40:49
TS2322: Type 'string' is not assignable to type 'undefined'.
> 40 | <Component results="123"></Component>
ESLint didn't complain.
With another, not reserved name, it works:
Stencil:
export class Component {
@Prop() foo: string;
render() {
return (
<div>
{foo}
</div>
);
}
}
React: (with Stencil react output)
<Component foo="123"></Component>
Results
webpack compiled successfully (37ebed430927f8d3)
https://gist.github.com/Ruben-E/091c96ea508ce8fb33eec59d324bdfab
No response
Pending rules:
@Element()
's type must be HTML{tag-name}ElementProp()
@State()
and @Prop()
<Host>
vs returning array in render()<Host>
@Watch
decorators listens to existing prop or stateNaming:
Code quality
0.7.2
I have a @Watch
for a native property in a component. It is showing me the following lint error:
According to the Stencil documentation, watching native properties is supported (and it works correctly in my code). Therefore, there should be no eslint error here.
Create a component and add a @Watch
that targets a native HTLM property.
N/A
No response
0.4.0
When running eslint with @stencil/eslint-plugin v0.4.0, I see a lot of " got “stencil-maintainers-put-an-invalid-version-intentionally-if-this-errors-please-raise-an-issue" messages
When running eslint with @stencil/eslint-plugin, I should not see any "stencil-maintainers-put-an-invalid-version-intentionally-if-this-errors-please-raise-an-issue" messages
Updated @stencil/eslint-plugin from ^0.3.1
to ^0.4.0
N/A
No response
0.7.1
https://github.com/stencil-community/stencil-eslint/pull/67/files introduced properties unrelated to HTMLElement
that are being flagged.
For example, a color
prop will produce a warning/error despite it not being defined in HTMLElement
:
126:28 error The @prop name "color conflicts with a key in the HTMLElement prototype. Please choose a different name @stencil-community/reserved-member-names
Only attributes/properties on HTMLElement.prototype
to be flagged by the rule.
The following should produce the error described above:
import { Component, Prop, h } from '@stencil/core';
@Component({
tag: 'my-component',
shadow: true,
})
export class MyComponent {
@Prop() color: string;
render() {
return <div>color is {this.color}</div>;
}
}
https://github.com/ionic-team/stencil-component-starter
No response
Hey there! I am opening this as a feature request since this is something which I think needs change, but is not a bug per se.
I noticed that the eslint plugin was moved to the stencil-community organization (#76 ), and with that there is a new name associated: @stencil-community/eslint-plugin
.
That makes sense, but in my mind its very confusing that the original package @stencil/eslint-plugin
(https://www.npmjs.com/package/@stencil/eslint-plugin) is still online, without any notice in its package info. The link is also still the ionic-team one, even though it automatically redirects to this repo.
I'm not very experienced with publishing NPM packages - so please forgive me if there is no easy solution for that - but is there a way we could add some kind of deprecation warning to the original package on npmjs.com? Otherwise you have to check the link to the GitHub repo to find out that the package has moved.
Add a deprecation warning to the original package.
Add a hint in the README of this repository, so that at least anyone visiting from npmjs.com immediately sees that the package has moved.
No response
No response
Forces the developer to document every <slot>
in the render()
function.
A slot is part of the public API of the component. Just as Prop()
and Event()
are enforced, slots are of equal importance.
No response
No response
No response
No response
Hi!
// Not critical at all, just annoying IDE highlighting
There is an error for stencil.config.ts
:
Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: stencil.config.ts.
The file must be included in at least one of the projects provided.eslint
.eslintrc:
...
"parserOptions": {
"project": "./tsconfig.json"
},
...
tsconfig.json:
...
"include": ["src"],
...
If adding stencil.config.ts
to tsconfig's include, a WARN at npm run start
:
tsconfig.json should not reference stencil.config.ts
stencil.config.ts is not part of the output build, it should not be included.
if adding *.ts
- all ok, but I not sure it is a good idea.
Just left a message in slack about @stencil/strict-boolean-conditions
was set to "error", but it's quite rare that you actually need to do that explicitly.
I think it'll fit the "strict" preset better.
This is also not mentioned in the readme.
Will start a PR for the readme, if anyone has other suggestions, I'd be happy to include them, too.
Is there any way to solve the unused variable "h" issue?:
'h' is defined but never used.eslint(@typescript-eslint/no-unused-vars)
Maybe stencil-eslint could implement a rule that would override the typescript-eslint one?
"@stencil/eslint-plugin": "0.3.1",
"@typescript-eslint/eslint-plugin": "5.1.0",
"@typescript-eslint/parser": "5.1.0",
"eslint": "8.0.1",
"eslint-plugin-react": "7.26.1",
The component:
@Component({
tag: 'signup',
scoped: false,
shadow: false,
})
export class Signup implements ComponentInterface {
@Prop() active: boolean = false;
render(): any {
return <Host />;
}
}
the error:
The @Prop decorator can only be applied to class properties @stencil/decorators-context
No error
npm init stencil
npx: installed 1 in 1.681s
√ Pick a starter » component
√ Project name » bug
Follow the steps https://github.com/ionic-team/stencil-eslint/blob/main/README.md
Run npm run lint
No response
No response
Hi all,
FYI
If you get this message after running the lint
script:
Error: Failed to load plugin '@stencil' declared in '.eslintrc.json': Cannot find module 'typescript'
In order to avoid this error message, you need to install Typescript as a dependency.
If you get this message after running the lint
script:
Warning: React version not specified in eslint-plugin-react settings.
In order to avoid this warning message you need to install React as a dependency and then update the file .eslintrc.json
with these lines:
"settings": {
"react": {
"version": "detect"
}
}
If you get this message on stencil.config.ts
Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: stencil.config.ts.
The file must be included in at least one of the projects provided.eslint
In order to avoid this message you need to create a new file called .eslintignore
and add with these lines:
stencil.config.ts
dist
loader
node_modules
www
v0.3.1
After updating eslint
to v8.x
I'm now getting lint errors on @stencil/no-unused-watch
with message: Watch decorator @Watch("xxx") is not matching with any @Prop() or @State()
.
This happens with all instances of @Watch
in my codebase.
There should only be a lint error when there is no matching @Prop
or @State
to correspond with the @Watch
.
Update eslint
to v8.x
, add @stencil/eslint-plugin
and create a component with a @Prop
and then add a @Watch
for it.
No response
No response
latest
here is my .eslintrc.js
module.exports = {
extends: ['../../.eslintrc.json'],
ignorePatterns: ['!**/*'],
overrides: [
{
files: ['*.ts', '*.tsx'],
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
extends: ['plugin:@stencil/recommended'],
rules: {
'@stencil/decorators-context': 'off',
'@stencil/no-unused-watch': 'off',
'@stencil/decorators-style': [
'error',
{
prop: 'inline',
state: 'inline',
element: 'inline',
event: 'inline',
method: 'multiline',
watch: 'multiline',
listen: 'multiline',
},
],
'@stencil/element-type': 'error',
'@stencil/host-data-deprecated': 'error',
'@stencil/methods-must-be-public': 'error',
'@stencil/own-methods-must-be-private': 'error',
'@stencil/own-props-must-be-private': 'error',
'@stencil/prefer-vdom-listener': 'error',
'@stencil/props-must-be-public': 'error',
'@stencil/props-must-be-readonly': 'error',
'@stencil/render-returns-host': 'error',
'@stencil/required-jsdoc': 'error',
'@stencil/reserved-member-names': 'error',
'@stencil/single-export': 'error',
'@stencil/strict-mutable': 'error',
},
},
],
};
rules like
prop: 'inline',
'@stencil/required-jsdoc': 'error',
// had to turn off these
'@stencil/decorators-context': 'off',
'@stencil/no-unused-watch': 'off',
Don't work!
I am using nx mono repo with eslint 8.0
all rules should work with this config
please check confile for this and run eslint command
just try with fresh nx repo + stencil
No response
Please update EsLint
I want to use stencil rules in conjunction with @nrwl/eslint-plugin-nx ^14
No response
No response
No response
No response
The core utilities used by rules for Stencil to be extracted into a separate module or repo.
Having a set of core utils would make it easier to create project-specific rules for Stencil-based projects.
A separate package with core rule utilities. I have created stencil-eslint-core
and have a fork of stencil-eslint
to demonstrate this in action. All tests are passing.
No response
No response
No response
I have a question regarding the new version of the plugin, any specific reason why the new version comes with:
props can’t be mutable and the jsdoc are required on props etc…, inline events can't be an arrow function?
Are this changes required because of the new outputs to react and angular?
Working with the latest version of this plugin:
"@stencil/eslint-plugin": "^0.3.1",
We discover is not behaving as expected, when we run eslint is throwing the following error:
error External @method() expandPopover() must return a Promise. Consider prefixing the method with async, such as @method() async expandPopover() @stencil/async-methods
But we have the async decorator in the method:
/**
* some comment
*/
@Method()
async expandPopover(): Promise<void> {
if(this.trigger === PopoverTooltipTrigger.Conditional){
this.openPopover();
}
}
What is worse is that if you run the eslint --fix command, it will generate this code:
/**
* some comment
*/
/**
* some comment
*/
/**
* some comment
*/
/**
* some comment
*/
@Method()
asyncasync async expandPopover(): Promise<void> {
if(this.trigger === PopoverTooltipTrigger.Conditional){
this.openPopover();
}
}
Is multiplying the comment by 4 and is adding multiple async words before the method declaration.
We couldn't figure it out how to fix this, can you help?
Thanks.
@typescript-eslint/eslint-plugin
has released a new version 6.0.0, but this plugin only support up to 5.x.x, which prevent projects from upgrading eslint-plugin
to the latest version.
See the eslint-plugin
6.0.0 release announcement for more details on the changes (some of which might impact plugins).
I want to be able to keep up-to-date dependencies.
No response
No response
No response
No response
props-must-be-readonly
rule is not a good idea because it will make a wrong generated components.d.ts
ionic-team/stencil#1896
@typescript-eslint/eslint-plugin has released a new version 7.0.0, but this plugin only support up to 6.x.x, which prevent projects from upgrading eslint-plugin to the latest version.
See the eslint-plugin 7.0.0 release announcement for more details on the changes (some of which might impact plugins):
I want to be able to keep up-to-date dependencies.
No response
No response
No response
No response
This RFC seeks input as to whether the Stencil decorators-style
rule should be removed. This RFC is in favor of removing the rule.
Within the last few years, the JavaScript ecosystem has rallied around splitting the responsibility of formatting code out of static analysis tools (linters) in favor of separate tools for formatting, such as Prettier. When lint rules such as decorators-style
are created with the intent of enforcing a particular formatting style, this may conflict with tools like Prettier. #27 is an example of such conflict. The primary motivator behind this RFC is refocus this library for checking the semantic correctness of code and to avoid chasing conflicts between external tools like Prettier.
The design is "simple" in that we'd be removing this rule from the codebase
This would be considered a breaking change. As of this writing, the library has not hit v1.0.0, which makes this a slightly more palatable consequence.
We're using default Prettier options and default @stencil/decorators-style
options.
Prettier formats code like this:
class AxsTreeViewItem {
@Event({ bubbles: true, composed: true })
axsTreeItemSelected: EventEmitter<any>;
}
but @stencil/decorators-style
says The @Event decorator can only be applied as inline
.
I expect @stencil/decorators-style
to work with Prettier and to not cause warnings.
Right now, the ESlint Compiler throws an exception when I define a union type for my element:
@Element() element: HTMLMyComponentElement | undefined;
To satisfy my "strict": true
Typescript config I have to define it like so. Pretending element!
exists is not the right solution since it will be undefined until it's rendered.
It's required when using Typescript strict mode.
No response
No response
No response
No response
First of all: brilliant work! These components are very lightweighted 💪
The issue:
If I use classnames
I get this warning 'classnames': Stencil can already render conditional classes:
But Stencil can't handle simple lists of classes: ['my-class1', 'my-class2', 'my-class3']
I know we can write it as:
{
['my-class1']: true,
['my-class2']: true,
['my-class3']: true,
}
but it looks particularely verbose if we have complex combinations.
Example:
I have a component that can receive a list of classes from the parent component:
<my-component arrow-left-classes="example1,example2,example3" arrow-right-classes="example1,example2" />
and then in the component I have something like a carousel:
<div>
<div class={['prev-arrow', ...this.arrowLeftClasses]}>...</div>
<div class={['next-arrow', ...this.arrowRightClasses]}>...</div>
</div>
This will NOT work because classes won't accept arrays and the transformation for those arrays is verbose and bad for the maintainability of the code, so I used classnames:
<div>
<div class={classnames(['prev-arrow', ...this.arrowLeftClasses])}>...</div>
<div class={classnames(['next-arrow', ...this.arrowRightClasses])}>...</div>
</div>
Everything works fine, except the annoying warning to not use classmates 😅
The Stencil team is looking for a maintainer for this package!
We recognize that we haven't been able to dedicate as much time/effort to this package as some might like. As such, we've decided the best course of action is to propose moving this package to the Stencil community org on GitHub and make it to a community-driven effort.
We’re looking for community members to take ownership of this project as a part of the move. If you are interested in becoming a maintainer, feel free to join the #eslint Channel in the Stencil Slack and we can discuss what being a maintainer might look like.
We’re really excited about giving the Stencil community greater ownership and all the amazing advancements that we know will come from it.
latest
╰─ npm i --save-dev @stencil/eslint-plugin
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: @typescript-eslint/[email protected]
npm ERR! node_modules/@typescript-eslint/eslint-plugin
npm ERR! dev @typescript-eslint/eslint-plugin@"~5.3.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @typescript-eslint/eslint-plugin@"<5 && ^4.0.0" from @stencil/[email protected]
npm ERR! node_modules/@stencil/eslint-plugin
npm ERR! dev @stencil/eslint-plugin@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/pranav.sarda/.npm/eresolve-report.txt for a full report.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/pranav.sarda/.npm/_logs/2021-12-28T11_18_35_507Z-debug.log
should install without conflicitng peer dependencies.
I have a monorepo setup with nx and nxeext/stenciljs. Nx setup with 5.3.0 version of eslint hence causing conflict when trying to install this as -D
just try with fresh nx repo + stencil
No response
The peer dependencies are currently hard-coded to a specific major version with a minimum minor and patch version to support. This means that currently if a project uses a newer typescript or the eslint parser and plugin for typescript, it will fail to install.
The first possible resolution is to say for example typescript: ">=3"
. This means as long as you are 3.0.0 or above, it will work. The caveat here is needing to test proactively and if a future version breaks either address it promptly and update the peer deps or restrict the version until it is fixed.
The carrot ranges could be kept and their updating automated. There was a tool called Greenkeeper (or something like that) which used to do this. Now I believe it is gone and something else is around to do the task for open source stuff. What they do is check for updates, if found alter the ranges as needed. Submit a PR, then your automated tests run. If it passes, you can merge and release (which can even get automated.) This means your deps are more fixed, but it's more reliable than being proactive about breakage after it happens from updates of other packages.
Does anyone in the community know of other ways to solve this issue? Dependencies are difficult to get right, but a solution should be found that doesn't prevent consumers from being unable to move forward due to linting rules blocking them.
I found https://semver.npmjs.com/ in trying to propose solutions within semver (of which there aren't many since TS at least doesn't use SemVer.) It could be useful to others exploring ways of getting good scoping down to maybe find an alternate path forward.
I recently tried to use an imported and renamed decorator like that:
import { Element as StencilElement } from '@stencil/core';
@Component({ /* ... */ })
class MyComponent {
// lint warning: "Own class properties cannot be public." eslint(@stencil/own-props-must-be-private)
@StencilElement() el: HTMLMyComponentElement;
}
After doing so I noticed that the usage of the renamed decorator triggers the lint rule eslint(@stencil/own-props-must-be-private).
I did not expect that to happen. Rather I should be able to use this renamed decorator without warnings as usual.
Noting this here so I don't forget later on down the line. No priority.
Update the required TypeScript version to 5
As of now, this plugin is not compatible to @stencil/core 3.3.x. @stencil/core 3.3.x. introduced a minimum requirement for TypeScript 5.
See: https://github.com/ionic-team/stencil/blob/main/package.json#L125
No response
No response
No response
No response
Noobie question — I’m using an example straight from the Stencil docs…
@Listen('keydown')
handleKeyDown(ev: KeyboardEvent){
if (ev.key === 'ArrowDown'){
console.log('down arrow pressed')
}
}
I get an error Use vDOM listener instead
, and I don’t exactly know how to resolve that… 😬
In other words, I don't exactly know how to "use a vDOM listener instead".
Also, according to the rule docs, this rule is meant to "Ensures that no vdom events are used in @Listen
decorator." Why is it bad to listen to vDOM events using the @Listen
decorator?
As per the recommendations on the stencil docs I use the binding/arrow function quite often on elements. What would be the best way to resolve the "react/jsx-no-bind" rule. I have seen their documentation but I can't seem to understand how the solutions could be applied in the context of Stencil components. This rule has been added intentionally to the stencil rules so I assume there is a solution to this, I just can't find it.
let item = "value";
<div onClick={() => self.select(item)}</div>
warning JSX props should not use arrow functions react/jsx-no-bind
Enforce the usage of the ComponentInterface
Some IDE's mark the lifecycle hooks as unused when the ComponentInterface is not implemented
No response
No response
No response
No response
^0.7.1
After installing eslint and the plugin for stencil lint then running on the files the console errors
Oops! Something went wrong! :(
ESLint: 8.56.0
TypeError: Error while loading rule '@stencil-community/async-methods': Cannot read properties of null (reading 'getTypeChecker')
The linter should run
Install a new eslint and eslint stencil into your project
n/a
No response
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.