1.1.0 • Published 3 days ago

eslint-plugin-astro v1.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
3 days ago

Introduction

eslint-plugin-astro is ESLint plugin for Astro components.
You can check on the Online DEMO.

sponsors

NPM license NPM version NPM downloads NPM downloads NPM downloads NPM downloads NPM downloads Build Status Coverage Status

This plugin is in the experimental stages of development.

At least it works fine with a withastro/docs repository.

📛 What is this plugin?

ESLint plugin for Astro components.

📖 Documentation

See documents.

💿 Installation

npm install --save-dev eslint eslint-plugin-astro

If you write TypeScript in Astro components, you also need to install the @typescript-eslint/parser:

npm install --save-dev @typescript-eslint/parser

If you want to use the rules for checking accessibility (A11Y), you also need to install eslint-plugin-jsx-a11y additionally:
(It is used internally in the rules for A11Y.)

npm install --save-dev eslint-plugin-jsx-a11y

Requirements

  • ESLint v7.0.0 and above
  • Node.js v18.18, v20.9, v21.1 and above

📖 Usage

Configuration

New Config (eslint.config.js)

Use eslint.config.js file to configure rules. See also: https://eslint.org/docs/latest/use/configure/configuration-files-new.

Example eslint.config.js:

import eslintPluginAstro from 'eslint-plugin-astro';
export default [
  // add more generic rule sets here, such as:
  // js.configs.recommended,
  ...eslintPluginAstro.configs.recommended,
  {
    rules: {
      // override/add rules settings here, such as:
      // "astro/no-set-html-directive": "error"
    }
  }
];

Example eslint.config.cjs:

const eslintPluginAstro = require('eslint-plugin-astro');
module.exports = [
  // add more generic rule sets here, such as:
  // js.configs.recommended,
  ...eslintPluginAstro.configs['flat/recommended'], // In CommonJS, the `flat/` prefix is required.
  {
    rules: {
      // override/add rules settings here, such as:
      // "astro/no-set-html-directive": "error"
    }
  }
];

This plugin provides configs:

  • *.configs['base'] ... Minimal configuration to enable correct Astro component linting.
  • *.configs['recommended'] ... Above, plus rules to prevent errors or unintended behavior.
  • *.configs['all'] ... Configuration enables all astro rules. It's meant for testing, not for production use because it changes with every minor and major version of the plugin. Use it at your own risk.
  • Extension of sharable configuration provided by eslint-plugin-jsx-a11y. You need to install eslint-plugin-jsx-a11y to use it.

See the rule list to get the rules that this plugin provides.

Legacy Config (.eslintrc)

Use .eslintrc.* file to configure rules. See also: https://eslint.org/docs/latest/use/configure.

Example .eslintrc.js. When using the shareable configuration provided by the plugin:

module.exports = {
  // ...
  extends: [
    // ...
    "plugin:astro/recommended",
  ],
  // ...
  overrides: [
    {
      // Define the configuration for `.astro` file.
      files: ["*.astro"],
      // Allows Astro components to be parsed.
      parser: "astro-eslint-parser",
      // Parse the script in `.astro` as TypeScript by adding the following configuration.
      // It's the setting you need when using TypeScript.
      parserOptions: {
        parser: "@typescript-eslint/parser",
        extraFileExtensions: [".astro"],
      },
      rules: {
        // override/add rules settings here, such as:
        // "astro/no-set-html-directive": "error"
      },
    },
    // ...
  ],
}

If you do not use a shareable configuration, it is the same as the following configuration:

module.exports = {
  // ...
  overrides: [
    {
      // Define the configuration for `.astro` file.
      files: ["*.astro"],
      // Enable this plugin
      plugins: ["astro"],
      env: {
        // Enables global variables available in Astro components.
        node: true,
        "astro/astro": true,
        es2020: true,
      },
      // Allows Astro components to be parsed.
      parser: "astro-eslint-parser",
      // Parse the script in `.astro` as TypeScript by adding the following configuration.
      // It's the setting you need when using TypeScript.
      parserOptions: {
        parser: "@typescript-eslint/parser",
        extraFileExtensions: [".astro"],
        // The script of Astro components uses ESM.
        sourceType: "module",
      },
      rules: {
        // Enable recommended rules
        "astro/no-conflict-set-directives": "error",
        "astro/no-unused-define-vars-in-style": "error",

        // override/add rules settings here, such as:
        // "astro/no-set-html-directive": "error"
      },
    },
    {
      // Define the configuration for `<script>` tag.
      // Script in `<script>` is assigned a virtual file name with the `.js` extension.
      files: ["**/*.astro/*.js", "*.astro/*.js"],
      env: {
        browser: true,
        es2020: true,
      },
      parserOptions: {
        sourceType: "module",
      },
      rules: {
        // override/add rules settings here, such as:
        // "no-unused-vars": "error"

        // If you are using "prettier/prettier" rule,
        // you don't need to format inside <script> as it will be formatted as a `.astro` file.
        "prettier/prettier": "off",
      },
    },
    {
      // Define the configuration for `<script>` tag when using `client-side-ts` processor.
      // Script in `<script>` is assigned a virtual file name with the `.ts` extension.
      files: ["**/*.astro/*.ts", "*.astro/*.ts"],
      env: {
        browser: true,
        es2020: true,
      },
      parser: "@typescript-eslint/parser",
      parserOptions: {
        sourceType: "module",
        project: null,
      },
      rules: {
        // override/add rules settings here, such as:
        // "no-unused-vars": "error"

        // If you are using "prettier/prettier" rule,
        // you don't need to format inside <script> as it will be formatted as a `.astro` file.
        "prettier/prettier": "off",
      },
    },
    // ...
  ],
}

If you are writing client-side scripts in TypeScript and want to use @typescript-eslint/parser as the TypeScript parser, you will need to use client-side-ts processor and configure it as follows.

module.exports = {
  // ...
  extends: [
    // ...
    "plugin:astro/recommended",
  ],
  // ...
  overrides: [
    {
      files: ["*.astro"],
      // ...
      processor: "astro/client-side-ts", // <- Uses the "client-side-ts" processor.
      rules: {
        // ...
      },
    },
    // ...
  ],
}

The pull request diff here is an example of introducing eslint-plugin-astro to the withastro/docs repository.

This plugin provides configs:

  • plugin:astro/base ... Minimal configuration to enable correct Astro component linting.
  • plugin:astro/recommended ... Above, plus rules to prevent errors or unintended behavior.
  • plugin:astro/all ... Configuration enables all astro rules. It's meant for testing, not for production use because it changes with every minor and major version of the plugin. Use it at your own risk.
  • Extension of sharable configuration provided by eslint-plugin-jsx-a11y. You need to install eslint-plugin-jsx-a11y to use it.

See the rule list to get the rules that this plugin provides.

Parser Configuration

See https://github.com/ota-meshi/astro-eslint-parser#readme.

Resolving Error in JSX: Unsafe return of an any typed value

Astro supports JSX from multiple frameworks such as React, Preact, and Solid.js by defining JSX Elements as HTMLElement | any;. When a framework with a JSX type definition is not present in your project this any can cause the ESLint error @typescript-eslint/no-unsafe-return.

This can be resolved by overriding the astroHTML.JSX.Element definition with a *.d.ts file such as jsx.d.ts in your project root directory:

import "astro/astro-jsx";

declare global {
  namespace JSX {
    // type Element = astroHTML.JSX.Element // We want to use this, but it is defined as any.
    type Element = HTMLElement;
  }
}

Add this *.d.ts to your tsconfig.eslint.json:

{
  "extends": "./tsconfig.json",
  "include": [
    // ...
    "jsx.d.ts"
  ]
}

Ensure that any necessary parserOptions in your .eslintrc.** have a project key also pointing to this config:

{
  // ...
  "overrides": [
    {
      "files": ["*.astro"],
      "parser": "astro-eslint-parser",
      "parserOptions": {
        "parser": "@typescript-eslint/parser",
        "extraFileExtensions": [".astro"],
        // add this line
        "project": "./tsconfig.eslint.json"
      },
      // ...
    }
    // ...
  ]}

Running ESLint from the command line

If you want to run eslint from the command line, make sure you include the .astro extension using the --ext option or a glob pattern, because ESLint targets only .js files by default.

Examples:

eslint --ext .js,.astro src
eslint "src/**/*.{js,astro}"

💻 Editor Integrations

Visual Studio Code

Use the dbaeumer.vscode-eslint extension that Microsoft provides officially.

You have to configure the eslint.validate option of the extension to check .astro files, because the extension targets only *.js or *.jsx files by default.

Example .vscode/settings.json:

{
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "astro", // Enable .astro
    "typescript", // Enable .ts
    "typescriptreact" // Enable .tsx
  ]
}

✅ Rules

The --fix option on the command line automatically fixes problems reported by rules which have a wrench 🔧 below.
The rules with the following star ⭐ are included in the plugin:astro/recommended configs.

Doesn't the rule you want exist? Share your idea of that rule with us.

Possible Errors

These rules relate to possible syntax or logic errors in Astro component code:

Rule IDDescription
astro/missing-client-only-directive-valuethe client:only directive is missing the correct component's framework value
astro/no-conflict-set-directivesdisallow conflicting set directives and child contents
astro/no-deprecated-astro-canonicalurldisallow using deprecated Astro.canonicalURL
astro/no-deprecated-astro-fetchcontentdisallow using deprecated Astro.fetchContent()⭐🔧
astro/no-deprecated-astro-resolvedisallow using deprecated Astro.resolve()
astro/no-deprecated-getentrybyslugdisallow using deprecated getEntryBySlug()
astro/no-exports-from-componentsdisallow value export
astro/no-unused-define-vars-in-styledisallow unused define:vars={...} in style tag
astro/valid-compiledisallow warnings when compiling.

Security Vulnerability

These rules relate to security vulnerabilities in Astro component code:

Rule IDDescription
astro/no-set-html-directivedisallow use of set:html to prevent XSS attack

Best Practices

These rules relate to better ways of doing things to help you avoid problems:

Rule IDDescription
astro/no-set-text-directivedisallow use of set:text🔧
astro/no-unused-css-selectordisallow selectors defined in style tag that don't use in HTML

Stylistic Issues

These rules relate to style guidelines, and are therefore quite subjective:

Rule IDDescription
astro/prefer-class-list-directiverequire class:list directives instead of class with expressions🔧
astro/prefer-object-class-listrequire use object instead of ternary expression in class:list🔧
astro/prefer-split-class-listrequire use split array elements in class:list🔧

A11Y Extension Rules

These rules extend the rules provided by eslint-plugin-jsx-a11y to work well in Astro component:
(You need to install eslint-plugin-jsx-a11y to use the rules.)

Rule IDDescription
astro/jsx-a11y/alt-textapply jsx-a11y/alt-text rule to Astro components
astro/jsx-a11y/anchor-ambiguous-textapply jsx-a11y/anchor-ambiguous-text rule to Astro components
astro/jsx-a11y/anchor-has-contentapply jsx-a11y/anchor-has-content rule to Astro components
astro/jsx-a11y/anchor-is-validapply jsx-a11y/anchor-is-valid rule to Astro components
astro/jsx-a11y/aria-activedescendant-has-tabindexapply jsx-a11y/aria-activedescendant-has-tabindex rule to Astro components
astro/jsx-a11y/aria-propsapply jsx-a11y/aria-props rule to Astro components
astro/jsx-a11y/aria-proptypesapply jsx-a11y/aria-proptypes rule to Astro components
astro/jsx-a11y/aria-roleapply jsx-a11y/aria-role rule to Astro components
astro/jsx-a11y/aria-unsupported-elementsapply jsx-a11y/aria-unsupported-elements rule to Astro components
astro/jsx-a11y/autocomplete-validapply jsx-a11y/autocomplete-valid rule to Astro components
astro/jsx-a11y/click-events-have-key-eventsapply jsx-a11y/click-events-have-key-events rule to Astro components
astro/jsx-a11y/control-has-associated-labelapply jsx-a11y/control-has-associated-label rule to Astro components
astro/jsx-a11y/heading-has-contentapply jsx-a11y/heading-has-content rule to Astro components
astro/jsx-a11y/html-has-langapply jsx-a11y/html-has-lang rule to Astro components
astro/jsx-a11y/iframe-has-titleapply jsx-a11y/iframe-has-title rule to Astro components
astro/jsx-a11y/img-redundant-altapply jsx-a11y/img-redundant-alt rule to Astro components
astro/jsx-a11y/interactive-supports-focusapply jsx-a11y/interactive-supports-focus rule to Astro components
astro/jsx-a11y/label-has-associated-controlapply jsx-a11y/label-has-associated-control rule to Astro components
astro/jsx-a11y/langapply jsx-a11y/lang rule to Astro components
astro/jsx-a11y/media-has-captionapply jsx-a11y/media-has-caption rule to Astro components
astro/jsx-a11y/mouse-events-have-key-eventsapply jsx-a11y/mouse-events-have-key-events rule to Astro components
astro/jsx-a11y/no-access-keyapply jsx-a11y/no-access-key rule to Astro components
astro/jsx-a11y/no-aria-hidden-on-focusableapply jsx-a11y/no-aria-hidden-on-focusable rule to Astro components
astro/jsx-a11y/no-autofocusapply jsx-a11y/no-autofocus rule to Astro components
astro/jsx-a11y/no-distracting-elementsapply jsx-a11y/no-distracting-elements rule to Astro components
astro/jsx-a11y/no-interactive-element-to-noninteractive-roleapply jsx-a11y/no-interactive-element-to-noninteractive-role rule to Astro components
astro/jsx-a11y/no-noninteractive-element-interactionsapply jsx-a11y/no-noninteractive-element-interactions rule to Astro components
astro/jsx-a11y/no-noninteractive-element-to-interactive-roleapply jsx-a11y/no-noninteractive-element-to-interactive-role rule to Astro components
astro/jsx-a11y/no-noninteractive-tabindexapply jsx-a11y/no-noninteractive-tabindex rule to Astro components
astro/jsx-a11y/no-redundant-rolesapply jsx-a11y/no-redundant-roles rule to Astro components
astro/jsx-a11y/no-static-element-interactionsapply jsx-a11y/no-static-element-interactions rule to Astro components
astro/jsx-a11y/prefer-tag-over-roleapply jsx-a11y/prefer-tag-over-role rule to Astro components
astro/jsx-a11y/role-has-required-aria-propsapply jsx-a11y/role-has-required-aria-props rule to Astro components
astro/jsx-a11y/role-supports-aria-propsapply jsx-a11y/role-supports-aria-props rule to Astro components
astro/jsx-a11y/scopeapply jsx-a11y/scope rule to Astro components
astro/jsx-a11y/tabindex-no-positiveapply jsx-a11y/tabindex-no-positive rule to Astro components

Extension Rules

These rules extend the rules provided by ESLint itself to work well in Astro component:

Rule IDDescription
astro/semiRequire or disallow semicolons instead of ASI🔧

🍻 Contributing

Welcome contributing!

Please use GitHub's Issues/PRs.

Development Tools

  • npm test runs tests and measures coverage.
  • npm run update runs in order to update readme and recommended configuration.

Working With Rules

This plugin uses astro-eslint-parser for the parser. Check here to find out about AST.

❤️ Supporting

If you are willing to see that this package continues to be maintained, please consider sponsoring me.

sponsors

🔒 License

See the LICENSE file for license rights and limitations (MIT).

@jiralite/eslint-config-neon@infinitebrahmanuniverse/nolb-eslint-plugin-a@everything-registry/sub-chunk-1610@kembec/eslint-config-ts-astro-vueeslint-config-elegant-codingeslint-config-muhqeslint-config-neoneslint-config-nirtamir2eslint-config-kseslint-config-braden1996eslint-config-astro-svelte-jsdoc-standardeslint-config-atomiceslint-config-anpeslint-config-supremeeslint-plugin-all-in-oneeslint-config-rxjseslint-config-tysoneslint-config-sheriffeslint-config-recastuieslint-config-vighnesh153eslint-preset-astroeslint-config-soybeanjsbundled-eslint-config@douglasneuroinformatics/eslint-config@lint-my-life/eslint-config-astro@mrcaidev/eslint-config-astro-preact@mrcaidev/eslint-config-astro-react@pengzhanbo/eslint-config-astro@phi.school/eslint-config@pospal/eslint-config@renovamen/eslint-config@renovamen/eslint-config-astro@ntnyq/eslint-config-astro@micheldever/eslint-config@mgcrea/eslint-config-astro@ibjs/eslint-config@lbenie/linting@morev/eslint-config@mouse_484/eslint-config-astro@minko-fe/eslint-config@lovelliu/eslint-config-astro@gpahal/eslint-config@j10c/eslint-config-astro@joshunrau/eslint-config@kdt310722/eslint-config@kecrily/eslint-config@kitschpatrol/eslint-config@gipo355/eslint-config-base@inc-dev/eslint-config-astro@hideoo/eslint-config@hideoo/eslint-config-astro@jimmy.codes/eslint-config@kodehort/eslint-config@acdh-oeaw/eslint-config-astro@adbayb/eslint-config@amiceli/eslint-config-astro@waspeer/config@waspeer/eslint-config@virtual-live-lab/eslint-config@u3u/eslint-config@stefanprobst/eslint-config-astro@weirddeer/eslint-config@taskylizard/eslint-config@vic1707/eslint-config@we-are-singular/eslint-config@will-stone/eslint-config@albanbl/eslint-config-astro@witheslint/preset-astro@wondergrove/eslint-config@blechlawine/eslint-config-base@wulfre/eslint-config@yeger/eslint-config@btbman/eslint-config-astro@xeraph-dev/eslint-config@tgs-guru/shared-es-config@solidjs-material/configuration@theurgi/eslint-config@shun-shobon/eslint-config@cloudcommerce/eslint
1.1.0

3 days ago

1.0.2

6 days ago

1.0.1

6 days ago

1.0.0

6 days ago

1.0.3

6 days ago

0.34.0

26 days ago

0.33.1

1 month ago

0.33.0

1 month ago

0.32.0

1 month ago

0.31.4

3 months ago

0.31.3

4 months ago

0.31.2

4 months ago

0.31.1

4 months ago

0.31.0

5 months ago

0.30.0

5 months ago

0.29.1

7 months ago

0.29.0

8 months ago

0.27.2

10 months ago

0.28.0

9 months ago

0.27.1

11 months ago

0.26.2

12 months ago

0.27.0

12 months ago

0.26.1

1 year ago

0.26.0

1 year ago

0.25.0

1 year ago

0.24.0

1 year ago

0.23.0

1 year ago

0.22.0

1 year ago

0.21.0

2 years ago

0.20.1

2 years ago

0.20.0

2 years ago

0.21.1

1 year ago

0.19.0

2 years ago

0.18.0

2 years ago

0.17.1

2 years ago

0.17.0

2 years ago

0.16.0

2 years ago

0.15.0

2 years ago

0.14.0

2 years ago

0.13.0

2 years ago

0.12.0

2 years ago

0.11.2

2 years ago

0.11.1

2 years ago

0.11.0

2 years ago

0.10.2

2 years ago

0.10.1

2 years ago

0.10.0

2 years ago

0.9.0

2 years ago

0.8.1

2 years ago

0.8.0

2 years ago

0.7.0

2 years ago

0.6.0

2 years ago

0.5.0

2 years ago

0.4.0

2 years ago

0.3.0

2 years ago

0.2.0

2 years ago

0.1.0

2 years ago

0.0.1

2 years ago