Skip to content

Commit

Permalink
feat!: support ESLint 9 flat config (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
haoqunjiang authored Sep 24, 2024
1 parent e0bf9da commit f30a678
Show file tree
Hide file tree
Showing 337 changed files with 16,259 additions and 3,887 deletions.
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

21 changes: 0 additions & 21 deletions .eslintrc.js

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
package-lock.json
dist
5 changes: 5 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"arrowParens": "avoid"
}
127 changes: 86 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,120 @@
# @vue/eslint-config-typescript

> eslint-config-typescript for Vue
ESLint configuration for Vue 3 + TypeScript projects.

See [@typescript-eslint/eslint-plugin](https://typescript-eslint.io/rules/) for available rules.

This config is specifically designed to be used by `@vue/cli` & `create-vue` setups
This config is specifically designed to be used by `create-vue` setups
and is not meant for outside use (it can be used but some adaptations
on the user side might be needed - for details see the config file).

A part of its design is that this config may implicitly depend on
other parts of `@vue/cli`/`create-vue` setups, such as `eslint-plugin-vue` being
other parts of `create-vue` setups, such as `eslint-plugin-vue` being
extended in the same resulting config.

## Installation
> [!NOTE]
> The current version doesn't support the legacy `.eslintrc*` configuraion format. For that you need to use version 13 or earlier. See the [corresponding README](https://www.npmjs.com/package/@vue/eslint-config-typescript/v/legacy-eslintrc) for more usage instructions.
In order to work around [a known limitation in ESLint](https://github.com/eslint/eslint/issues/3458), we recommend you to use this package alongside `@rushstack/eslint-patch`, so that you don't have to install too many dependencies:
## Installation

```sh
npm add --dev @vue/eslint-config-typescript @rushstack/eslint-patch
npm add --dev @vue/eslint-config-typescript
```

## Usage
Please also make sure that you have `typescript` and `eslint` installed.

This package comes with 2 rulesets.

### `@vue/eslint-config-typescript`
## Usage

This ruleset is the base configuration for Vue-TypeScript projects.
Besides setting the parser and plugin options, it also turns off several conflicting rules in the `eslint:recommended` ruleset.
So when used alongside other sharable configs, this config should be placed at the end of the `extends` array.
Because of the complexity of this config, it is exported as a factory function that takes an options object and returns an ESLint configuration object.

An example `.eslintrc.cjs`:
### Minimal Setup

```js
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution")

module.exports = {
extends: [
'eslint:recommended',
'plugin:vue/vue3-essential',
'@vue/eslint-config-typescript'
]
}
// eslint.config.mjs
import pluginVue from "eslint-plugin-vue";
import vueTsEslintConfig from "@vue/eslint-config-typescript";

export default [
...pluginVue.configs["flat/essential"],
...vueTsEslintConfig(),
]
```

### `@vue/eslint-config-typescript/recommended`
The above configuration enables [the essential rules for Vue 3](https://eslint.vuejs.org/rules/#priority-a-essential-error-prevention) and [the recommended rules for TypeScript](https://typescript-eslint.io/rules/?=recommended).

This is extended from the `@typescript-eslint/recommended` ruleset, which is an **_opinionated_** ruleset.
See the [original documentation](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin/src/configs#recommended) for more information.
All the `<script>` blocks in `.vue` files *MUST* be written in TypeScript (should be either `<script setup lang="ts">` or `<script lang="ts">`).

Some of its rules, however, might conflict with `prettier`.
So when used alongside other sharable configs, this config should be placed after all other configs except for the one from `@vue/eslint-config-prettier` or `eslint-plugin-prettier` in the `extends` array.

An example `.eslintrc.cjs`:
### Advanced Setup

```js
/* eslint-env node */
require("@rushstack/eslint-patch/modern-module-resolution")

module.exports = {
extends: [
'plugin:vue/vue3-essential',
'@vue/eslint-config-typescript/recommended',
'@vue/eslint-config-prettier'
]
}
// eslint.config.mjs
import pluginVue from "eslint-plugin-vue";
import vueTsEslintConfig from "@vue/eslint-config-typescript";

export default [
...pluginVue.configs["flat/essential"],

...vueTsEslintConfig({
// Optional: extend additional configurations from `typescript-eslint`.
// Supports all the configurations in https://typescript-eslint.io/users/configs#recommended-configurations
extends: [
// By default, only the recommended rules are enabled.
"recommended",
// You can also manually enable the stylistic rules.
// "stylistic",

// [!NOTE] The ones with `-type-checked` are not yet tested.

// Other utility configurations, such as `eslint-recommended`,
// are also extendable here. But we don't recommend using them directly.
],

// Optional: specify the script langs in `.vue` files
// Defaults to `{ ts: true, js: false, tsx: false, jsx: false }`
supportedScriptLangs: {
ts: true,

// [!DISCOURAGED]
// Set to `true` to allow plain `<script>` or `<script setup>` blocks.
// This might result-in false positive or negatives in some rules for `.vue` files.
// Note you also need to configure `allowJs: true` and `checkJs: true`
// in corresponding `tsconfig.json` files.
js: false,

// [!STRONGLY DISCOURAGED]
// Set to `true` to allow `<script lang="tsx">` blocks.
// This would be in conflict with all type-aware rules.
tsx: false,

// [!STRONGLY DISCOURAGED]
// Set to `true` to allow `<script lang="jsx">` blocks.
// This would be in conflict with all type-aware rules and may result in false positives.
jsx: false,
},

// [!NOT YET IMPLEMENTED]
// <https://github.com/vuejs/eslint-plugin-vue/issues/1910#issuecomment-1819993961>
// Optional: the root directory to resolve the `.vue` files, defaults to `process.cwd()`.
//
// This is useful when you allow any other languages than `ts` in `.vue` files.
// Our config helper would resolve and parse all the `.vue` files under `rootDir`,
// and only apply the loosened rules to the files that do need them.
//
// rootDir: __dirname,
})
]
```

## Further Reading

TODO

### With Other Community Configs

Work-In-Progress.

~~If you are following the [`standard`](https://standardjs.com/) or [`airbnb`](https://github.com/airbnb/javascript/) style guides, don't manually extend from this package. Please use `@vue/eslint-config-standard-with-typescript` or `@vue/eslint-config-airbnb-with-typescript` instead.~~

## Migrating from `.eslintrc.cjs`

TODO
30 changes: 30 additions & 0 deletions examples/allow-js/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
.DS_Store
dist
dist-ssr
coverage
*.local

/cypress/videos/
/cypress/screenshots/

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

*.tsbuildinfo
6 changes: 6 additions & 0 deletions examples/allow-js/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"Vue.volar",
"dbaeumer.vscode-eslint"
]
}
39 changes: 39 additions & 0 deletions examples/allow-js/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# allow-js

This template should help get you started developing with Vue 3 in Vite.

## Recommended IDE Setup

[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).

## Type Support for `.vue` Imports in TS

TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.

## Customize configuration

See [Vite Configuration Reference](https://vitejs.dev/config/).

## Project Setup

```sh
npm install
```

### Compile and Hot-Reload for Development

```sh
npm run dev
```

### Type-Check, Compile and Minify for Production

```sh
npm run build
```

### Lint with [ESLint](https://eslint.org/)

```sh
npm run lint
```
1 change: 1 addition & 0 deletions examples/allow-js/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
18 changes: 18 additions & 0 deletions examples/allow-js/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import pluginVue from "eslint-plugin-vue";
import vueTsEslintConfig from "@vue/eslint-config-typescript";

export default [
{
name: 'app/files-to-lint',
files: ['**/*.js', '**/*.mjs', '**/*.ts', '**/*.mts', '**/*.vue'],
ignores: ['**/dist/**'],
},

...pluginVue.configs["flat/essential"],
...vueTsEslintConfig({
supportedScriptLangs: {
ts: true,
js: true
}
}),
]
13 changes: 13 additions & 0 deletions examples/allow-js/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
30 changes: 30 additions & 0 deletions examples/allow-js/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "allow-js",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --fix"
},
"dependencies": {
"vue": "^3.5.6"
},
"devDependencies": {
"@tsconfig/node20": "^20.1.4",
"@types/node": "^20.16.5",
"@vitejs/plugin-vue": "^5.1.4",
"@vue/eslint-config-typescript": "workspace:*",
"@vue/tsconfig": "^0.5.1",
"eslint": "^9.10.0",
"eslint-plugin-vue": "^9.28.0",
"npm-run-all2": "^6.2.3",
"typescript": "~5.5.4",
"vite": "^5.4.6",
"vue-tsc": "^2.1.6"
}
}
Binary file added examples/allow-js/public/favicon.ico
Binary file not shown.
48 changes: 48 additions & 0 deletions examples/allow-js/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script setup>
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'
</script>

<template>
<header>
<img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />

<div class="wrapper">
<HelloWorld msg="You did it!" />
</div>
</header>

<main>
<TheWelcome />
</main>
</template>

<style scoped>
header {
line-height: 1.5;
}
.logo {
display: block;
margin: 0 auto 2rem;
}
@media (min-width: 1024px) {
header {
display: flex;
place-items: center;
padding-right: calc(var(--section-gap) / 2);
}
.logo {
margin: 0 2rem 0 0;
}
header .wrapper {
display: flex;
place-items: flex-start;
flex-wrap: wrap;
}
}
</style>
Loading

0 comments on commit f30a678

Please sign in to comment.