From: Haoqun Jiang Date: Thu, 25 Dec 2025 06:20:21 +0000 (+0900) Subject: feat: move all eslint-related stuff to main repo (#875) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;ds=inline;p=thirdparty%2Fvuejs%2Fcreate-vue.git feat: move all eslint-related stuff to main repo (#875) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Haoqun Jiang Co-authored-by: Zhousg Co-authored-by: Thorsten Lünborg Co-authored-by: Cédric Exbrayat Co-authored-by: Anton Lilleby Co-authored-by: Dmytro Tsysar <1106994+idmytro@users.noreply.github.com> Co-authored-by: btea <2356281422@qq.com> It's becoming harder and harder to maintain `@vue/create-eslint-config` separately as the tooling space evolves. So I decided to merge it back to the main repo. The functionality remains mostly the same, except that we now explicitly generate an oxlint config file instead of passing options via CLI args. Previously, I was adding `--ignore-path .gitignore` to oxlint commands, but it turns out `.gitignore` is automatically respected inside a git repo[^1]. So I skipped that part. The general idea of this refactoring is that each general feature should be self-contained inside its own template folder (`linting` and `formatting` in this PR, in parallel with `tsconfig` and other stuff), so that in the future we can test them independently or even publish them as separate packages again. Still a lot of work to do in that direction, but this is a start. [^1]: https://oxc.rs/docs/guide/usage/linter/cli.html#ignore-files --- diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..ecea360f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}] +charset = utf-8 +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/LICENSE b/LICENSE index b5a7c2b0..fea80e3d 100644 --- a/LICENSE +++ b/LICENSE @@ -447,33 +447,4 @@ Repository: git://github.com/mde/ejs.git > WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > See the License for the specific language governing permissions and > limitations under the License. -> - -## @vue/create-eslint-config - -License: MIT -By: Haoqun Jiang -Repository: git+https://github.com/vuejs/create-eslint-config.git - -> MIT License -> -> Copyright (c) 2022 vuejs -> -> Permission is hereby granted, free of charge, to any person obtaining a copy -> of this software and associated documentation files (the "Software"), to deal -> in the Software without restriction, including without limitation the rights -> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -> copies of the Software, and to permit persons to whom the Software is -> furnished to do so, subject to the following conditions: -> -> The above copyright notice and this permission notice shall be included in all -> copies or substantial portions of the Software. -> -> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -> SOFTWARE. > \ No newline at end of file diff --git a/__test__/renderEslint.spec.ts b/__test__/renderEslint.spec.ts deleted file mode 100644 index 4deaf6c6..00000000 --- a/__test__/renderEslint.spec.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { it, describe, expect } from 'vitest' -import { getAdditionalConfigs } from '../utils/renderEslint' - -describe('renderEslint', () => { - it('should get additional dependencies and config with no test flags', () => { - const additionalConfigs = getAdditionalConfigs({ - needsTypeScript: false, - needsVitest: false, - needsCypress: false, - needsCypressCT: false, - needsPlaywright: false, - }) - expect(additionalConfigs).toStrictEqual([]) - }) - - it('should get additional dependencies and config with for vitest', () => { - const additionalConfigs = getAdditionalConfigs({ - needsTypeScript: false, - needsVitest: true, - needsCypress: false, - needsCypressCT: false, - needsPlaywright: false, - }) - expect(additionalConfigs).toHaveLength(1) - const [additionalVitestConfig] = additionalConfigs - expect(additionalVitestConfig.devDependencies['@vitest/eslint-plugin']).not.toBeUndefined() - expect(additionalVitestConfig.afterVuePlugin).toHaveLength(1) - const [additionalVitestPlugin] = additionalVitestConfig.afterVuePlugin! - expect(additionalVitestPlugin.importer).toBe(`import pluginVitest from '@vitest/eslint-plugin'`) - expect(additionalVitestPlugin.content).toContain('...pluginVitest.configs.recommended') - expect(additionalVitestPlugin.content).toContain("files: ['src/**/__tests__/*']") - }) - - it('should get additional dependencies and config with for cypress', () => { - const additionalConfigs = getAdditionalConfigs({ - needsTypeScript: false, - needsVitest: false, - needsCypress: true, - needsCypressCT: false, - needsPlaywright: false, - }) - expect(additionalConfigs).toHaveLength(1) - const [additionalCypressConfig] = additionalConfigs - expect(additionalCypressConfig.devDependencies['eslint-plugin-cypress']).not.toBeUndefined() - expect(additionalCypressConfig.afterVuePlugin).toHaveLength(1) - const [additionalCypressPlugin] = additionalCypressConfig.afterVuePlugin! - expect(additionalCypressPlugin.importer).toBe( - "import pluginCypress from 'eslint-plugin-cypress'", - ) - expect(additionalCypressPlugin.content).toContain('...pluginCypress.configs.recommended') - expect(additionalCypressPlugin.content).toContain( - "'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}'", - ) - expect(additionalCypressPlugin.content).toContain("'cypress/support/**/*.{js,ts,jsx,tsx}'") - }) - - it('should get additional dependencies and config with for cypress with component testing', () => { - const additionalConfigs = getAdditionalConfigs({ - needsTypeScript: false, - needsVitest: false, - needsCypress: true, - needsCypressCT: true, - needsPlaywright: false, - }) - expect(additionalConfigs).toHaveLength(1) - const [additionalCypressConfig] = additionalConfigs - expect(additionalCypressConfig.devDependencies['eslint-plugin-cypress']).not.toBeUndefined() - expect(additionalCypressConfig.afterVuePlugin).toHaveLength(1) - const [additionalCypressPlugin] = additionalCypressConfig.afterVuePlugin! - expect(additionalCypressPlugin.importer).toBe( - "import pluginCypress from 'eslint-plugin-cypress'", - ) - expect(additionalCypressPlugin.content).toContain('...pluginCypress.configs.recommended') - expect(additionalCypressPlugin.content).toContain("'**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}'") - expect(additionalCypressPlugin.content).toContain( - "'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}'", - ) - expect(additionalCypressPlugin.content).toContain("'cypress/support/**/*.{js,ts,jsx,tsx}'") - }) - - it('should get additional dependencies and config with for playwright', () => { - const additionalConfigs = getAdditionalConfigs({ - needsTypeScript: false, - needsVitest: false, - needsCypress: false, - needsCypressCT: false, - needsPlaywright: true, - }) - expect(additionalConfigs).toHaveLength(1) - const [additionalPlaywrightConfig] = additionalConfigs - expect( - additionalPlaywrightConfig.devDependencies['eslint-plugin-playwright'], - ).not.toBeUndefined() - expect(additionalPlaywrightConfig.afterVuePlugin).toHaveLength(1) - const [additionalPlaywrightPlugin] = additionalPlaywrightConfig.afterVuePlugin! - expect(additionalPlaywrightPlugin.importer).toBe( - "import pluginPlaywright from 'eslint-plugin-playwright'", - ) - expect(additionalPlaywrightPlugin.content).toContain( - "...pluginPlaywright.configs['flat/recommended']", - ) - expect(additionalPlaywrightPlugin.content).toContain( - "files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}']", - ) - }) -}) diff --git a/index.ts b/index.ts index 4d77d090..a006f966 100755 --- a/index.ts +++ b/index.ts @@ -20,7 +20,6 @@ import { import generateReadme from './utils/generateReadme' import getCommand from './utils/getCommand' import getLanguage from './utils/getLanguage' -import renderEslint from './utils/renderEslint' import { trimBoilerplate, removeCSSImport, emptyRouterConfig } from './utils/trimBoilerplate' import cliPackageJson from './package.json' with { type: 'json' } @@ -511,25 +510,40 @@ async function init() { } // Render ESLint config - if (needsEslint || needsOxlint) { - renderEslint(root, { - needsTypeScript, - needsOxlint, - needsVitest, - needsCypress, - needsCypressCT, - needsPrettier, - needsPlaywright, - }) - render('config/eslint') - } + if (needsEslint) { + render('linting/base') - if (needsOxlint) { - render('config/oxlint') + if (needsTypeScript) { + render('linting/core/ts') + } else { + render('linting/core/js') + } + + if (needsCypress) { + render('linting/cypress') + } + if (needsCypressCT) { + render('linting/cypress-ct') + } + if (needsPlaywright) { + render('linting/playwright') + } + if (needsVitest) { + render('linting/vitest') + } + + // These configs only disable rules, so they should be applied last. + if (needsPrettier) { + render('linting/prettier') + } + if (needsOxlint) { + render('linting/oxlint') + } } if (needsPrettier) { - render('config/prettier') + render('formatting/prettier') + // TODO: add oxfmt option in the next PR } // use rolldown-vite if the feature is enabled @@ -615,7 +629,7 @@ async function init() { root, () => {}, (filepath) => { - if (filepath.endsWith('.js') && !filepath.endsWith('eslint.config.js')) { + if (filepath.endsWith('.js')) { const tsFilePath = filepath.replace(/\.js$/, '.ts') if (fs.existsSync(tsFilePath)) { fs.unlinkSync(filepath) @@ -694,7 +708,7 @@ async function init() { if (!dotGitDirectoryState.hasDotGitDirectory) { outroMessage += ` ${dim('|')} ${language.infos.optionalGitCommand} - + ${bold(green('git init && git add -A && git commit -m "initial commit"'))}` } diff --git a/package.json b/package.json index 9ada0673..58cc1fc3 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "@types/eslint": "^9.6.1", "@types/node": "^24.10.4", "@types/prompts": "^2.4.9", - "@vue/create-eslint-config": "^0.14.2", "@vue/tsconfig": "^0.8.1", "ejs": "^3.1.10", "husky": "^9.1.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95b98d68..a0f23041 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,12 +23,9 @@ importers: '@types/prompts': specifier: ^2.4.9 version: 2.4.9 - '@vue/create-eslint-config': - specifier: ^0.14.2 - version: 0.14.2 '@vue/tsconfig': specifier: ^0.8.1 - version: 0.8.1(typescript@5.9.2)(vue@3.5.26(typescript@5.9.2)) + version: 0.8.1(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3)) ejs: specifier: ^3.1.10 version: 3.1.10 @@ -61,17 +58,17 @@ importers: dependencies: vue: specifier: ^3.5.26 - version: 3.5.26(typescript@5.9.2) + version: 3.5.26(typescript@5.9.3) devDependencies: '@vitejs/plugin-vue': specifier: ^6.0.3 - version: 6.0.3(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2)) + version: 6.0.3(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3)) vite: specifier: ^7.3.0 version: 7.3.0(@types/node@24.10.4)(yaml@2.8.1) vite-plugin-vue-devtools: specifier: ^8.0.5 - version: 8.0.5(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2)) + version: 8.0.5(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3)) template/config/cypress: devDependencies: @@ -86,7 +83,7 @@ importers: dependencies: vue: specifier: ^3.5.26 - version: 3.5.26(typescript@5.9.2) + version: 3.5.26(typescript@5.9.3) devDependencies: cypress: specifier: ^15.8.1 @@ -96,11 +93,11 @@ importers: dependencies: vue: specifier: ^3.5.26 - version: 3.5.26(typescript@5.9.2) + version: 3.5.26(typescript@5.9.3) devDependencies: '@vitejs/plugin-vue-jsx': specifier: ^5.1.2 - version: 5.1.2(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2)) + version: 5.1.2(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3)) vite: specifier: ^7.3.0 version: 7.3.0(@types/node@24.10.4)(yaml@2.8.1) @@ -109,10 +106,10 @@ importers: devDependencies: '@nightwatch/vue': specifier: ^3.1.2 - version: 3.1.2(@types/node@24.10.4)(vue@3.5.26(typescript@5.9.2)) + version: 3.1.2(@types/node@24.10.4)(vue@3.5.26(typescript@5.9.3)) '@vitejs/plugin-vue': specifier: ^6.0.3 - version: 6.0.3(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2)) + version: 6.0.3(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3)) chromedriver: specifier: ^143.0.3 version: 143.0.3 @@ -124,7 +121,7 @@ importers: version: 3.13.0(chromedriver@143.0.3)(geckodriver@6.1.0) ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@24.10.4)(typescript@5.9.2) + version: 10.9.2(@types/node@24.10.4)(typescript@5.9.3) vite: specifier: ^7.3.0 version: 7.3.0(@types/node@24.10.4)(yaml@2.8.1) @@ -136,7 +133,7 @@ importers: dependencies: vue: specifier: ^3.5.26 - version: 3.5.26(typescript@5.9.2) + version: 3.5.26(typescript@5.9.3) devDependencies: '@vue/test-utils': specifier: ^2.4.6 @@ -146,10 +143,10 @@ importers: dependencies: pinia: specifier: ^3.0.4 - version: 3.0.4(typescript@5.9.2)(vue@3.5.26(typescript@5.9.2)) + version: 3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3)) vue: specifier: ^3.5.26 - version: 3.5.26(typescript@5.9.2) + version: 3.5.26(typescript@5.9.3) template/config/playwright: devDependencies: @@ -157,20 +154,14 @@ importers: specifier: ^1.57.0 version: 1.57.0 - template/config/prettier: - devDependencies: - prettier: - specifier: 3.7.4 - version: 3.7.4 - template/config/router: dependencies: vue: specifier: ^3.5.26 - version: 3.5.26(typescript@5.9.2) + version: 3.5.26(typescript@5.9.3) vue-router: specifier: ^4.6.4 - version: 4.6.4(vue@3.5.26(typescript@5.9.2)) + version: 4.6.4(vue@3.5.26(typescript@5.9.3)) template/config/typescript: devDependencies: @@ -181,17 +172,17 @@ importers: specifier: ^8.0.4 version: 8.0.4 typescript: - specifier: ~5.9.0 - version: 5.9.2 + specifier: ~5.9.3 + version: 5.9.3 vue-tsc: specifier: ^3.2.1 - version: 3.2.1(typescript@5.9.2) + version: 3.2.1(typescript@5.9.3) template/config/vitest: dependencies: vue: specifier: ^3.5.26 - version: 3.5.26(typescript@5.9.2) + version: 3.5.26(typescript@5.9.3) devDependencies: '@vue/test-utils': specifier: ^2.4.6 @@ -210,7 +201,7 @@ importers: version: 24.0.3 '@vue/tsconfig': specifier: ^0.8.1 - version: 0.8.1(typescript@5.9.2)(vue@3.5.26(typescript@5.9.2)) + version: 0.8.1(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3)) template/tsconfig/vitest: devDependencies: @@ -1379,11 +1370,6 @@ packages: '@vue/compiler-ssr@3.5.26': resolution: {integrity: sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==} - '@vue/create-eslint-config@0.14.2': - resolution: {integrity: sha512-Cut75X2zJzgYoI3l6yoQVLrYRTmuQMwW9lUtNlIbAFF+KweHb5txEQHMJMxNRCQXaURm8otVUQANhFoO/AvGGQ==} - engines: {node: ^16.14.0 || >= 18.0.0} - hasBin: true - '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} @@ -3805,8 +3791,8 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - typescript@5.9.2: - resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true @@ -4901,10 +4887,10 @@ snapshots: dependencies: archiver: 5.3.2 - '@nightwatch/vue@3.1.2(@types/node@24.10.4)(vue@3.5.26(typescript@5.9.2))': + '@nightwatch/vue@3.1.2(@types/node@24.10.4)(vue@3.5.26(typescript@5.9.3))': dependencies: '@nightwatch/esbuild-utils': 0.2.1 - '@vitejs/plugin-vue': 4.6.2(vite@4.5.14(@types/node@24.10.4))(vue@3.5.26(typescript@5.9.2)) + '@vitejs/plugin-vue': 4.6.2(vite@4.5.14(@types/node@24.10.4))(vue@3.5.26(typescript@5.9.3)) get-port: 5.1.1 vite: 4.5.14(@types/node@24.10.4) vite-plugin-nightwatch: 0.4.6 @@ -5145,7 +5131,7 @@ snapshots: '@types/node': 24.10.4 optional: true - '@vitejs/plugin-vue-jsx@5.1.2(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2))': + '@vitejs/plugin-vue-jsx@5.1.2(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) @@ -5153,20 +5139,20 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.50 '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.28.5) vite: 7.3.0(@types/node@24.10.4)(yaml@2.8.1) - vue: 3.5.26(typescript@5.9.2) + vue: 3.5.26(typescript@5.9.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@4.6.2(vite@4.5.14(@types/node@24.10.4))(vue@3.5.26(typescript@5.9.2))': + '@vitejs/plugin-vue@4.6.2(vite@4.5.14(@types/node@24.10.4))(vue@3.5.26(typescript@5.9.3))': dependencies: vite: 4.5.14(@types/node@24.10.4) - vue: 3.5.26(typescript@5.9.2) + vue: 3.5.26(typescript@5.9.3) - '@vitejs/plugin-vue@6.0.3(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2))': + '@vitejs/plugin-vue@6.0.3(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.53 vite: 7.3.0(@types/node@24.10.4)(yaml@2.8.1) - vue: 3.5.26(typescript@5.9.2) + vue: 3.5.26(typescript@5.9.3) '@vitest/expect@4.0.16': dependencies: @@ -5350,19 +5336,13 @@ snapshots: '@vue/compiler-dom': 3.5.26 '@vue/shared': 3.5.26 - '@vue/create-eslint-config@0.14.2': - dependencies: - ejs: 3.1.10 - enquirer: 2.4.1 - kolorist: 1.8.0 - '@vue/devtools-api@6.6.4': {} '@vue/devtools-api@7.7.8': dependencies: '@vue/devtools-kit': 7.7.8 - '@vue/devtools-core@8.0.5(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2))': + '@vue/devtools-core@8.0.5(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3))': dependencies: '@vue/devtools-kit': 8.0.5 '@vue/devtools-shared': 8.0.5 @@ -5370,7 +5350,7 @@ snapshots: nanoid: 5.1.5 pathe: 2.0.3 vite-hot-client: 2.1.0(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1)) - vue: 3.5.26(typescript@5.9.2) + vue: 3.5.26(typescript@5.9.3) transitivePeerDependencies: - vite @@ -5428,11 +5408,11 @@ snapshots: '@vue/shared': 3.5.26 csstype: 3.2.3 - '@vue/server-renderer@3.5.26(vue@3.5.26(typescript@5.9.2))': + '@vue/server-renderer@3.5.26(vue@3.5.26(typescript@5.9.3))': dependencies: '@vue/compiler-ssr': 3.5.26 '@vue/shared': 3.5.26 - vue: 3.5.26(typescript@5.9.2) + vue: 3.5.26(typescript@5.9.3) '@vue/shared@3.5.24': {} @@ -5445,10 +5425,10 @@ snapshots: js-beautify: 1.15.1 vue-component-type-helpers: 2.1.6 - '@vue/tsconfig@0.8.1(typescript@5.9.2)(vue@3.5.26(typescript@5.9.2))': + '@vue/tsconfig@0.8.1(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3))': optionalDependencies: - typescript: 5.9.2 - vue: 3.5.26(typescript@5.9.2) + typescript: 5.9.3 + vue: 3.5.26(typescript@5.9.3) '@wdio/logger@9.18.0': dependencies: @@ -7333,12 +7313,12 @@ snapshots: pify@2.3.0: {} - pinia@3.0.4(typescript@5.9.2)(vue@3.5.26(typescript@5.9.2)): + pinia@3.0.4(typescript@5.9.3)(vue@3.5.26(typescript@5.9.3)): dependencies: '@vue/devtools-api': 7.7.8 - vue: 3.5.26(typescript@5.9.2) + vue: 3.5.26(typescript@5.9.3) optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 piscina@4.7.0: optionalDependencies: @@ -7906,7 +7886,7 @@ snapshots: tree-kill@1.2.2: {} - ts-node@10.9.2(@types/node@24.10.4)(typescript@5.9.2): + ts-node@10.9.2(@types/node@24.10.4)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -7920,7 +7900,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.9.2 + typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 @@ -7944,7 +7924,7 @@ snapshots: type-fest@0.8.1: {} - typescript@5.9.2: {} + typescript@5.9.3: {} undici-types@7.16.0: {} @@ -8021,9 +8001,9 @@ snapshots: - supports-color - utf-8-validate - vite-plugin-vue-devtools@8.0.5(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2)): + vite-plugin-vue-devtools@8.0.5(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3)): dependencies: - '@vue/devtools-core': 8.0.5(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.2)) + '@vue/devtools-core': 8.0.5(vite@7.3.0(@types/node@24.10.4)(yaml@2.8.1))(vue@3.5.26(typescript@5.9.3)) '@vue/devtools-kit': 8.0.5 '@vue/devtools-shared': 8.0.5 sirv: 3.0.2 @@ -8114,26 +8094,26 @@ snapshots: vue-component-type-helpers@2.1.6: {} - vue-router@4.6.4(vue@3.5.26(typescript@5.9.2)): + vue-router@4.6.4(vue@3.5.26(typescript@5.9.3)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.26(typescript@5.9.2) + vue: 3.5.26(typescript@5.9.3) - vue-tsc@3.2.1(typescript@5.9.2): + vue-tsc@3.2.1(typescript@5.9.3): dependencies: '@volar/typescript': 2.4.27 '@vue/language-core': 3.2.1 - typescript: 5.9.2 + typescript: 5.9.3 - vue@3.5.26(typescript@5.9.2): + vue@3.5.26(typescript@5.9.3): dependencies: '@vue/compiler-dom': 3.5.26 '@vue/compiler-sfc': 3.5.26 '@vue/runtime-dom': 3.5.26 - '@vue/server-renderer': 3.5.26(vue@3.5.26(typescript@5.9.2)) + '@vue/server-renderer': 3.5.26(vue@3.5.26(typescript@5.9.3)) '@vue/shared': 3.5.26 optionalDependencies: - typescript: 5.9.2 + typescript: 5.9.3 w3c-xmlserializer@5.0.0: dependencies: diff --git a/rolldown.config.ts b/rolldown.config.ts index 6ee4e497..b1c17e20 100644 --- a/rolldown.config.ts +++ b/rolldown.config.ts @@ -1,4 +1,3 @@ -import fs from 'node:fs' import path from 'node:path' import { defineConfig, RolldownPlugin } from 'rolldown' import license from 'rollup-plugin-license' @@ -200,34 +199,5 @@ export default defineConfig({ }, }, }) as RolldownPlugin, - - { - name: '@vue/create-eslint-config fix', - transform: { - filter: { - id: /@vue.create-eslint-config.renderEjsFile\.js$/, - }, - handler(_code, id) { - const pkgDir = path.dirname(id) - const templatesDir = path.resolve(pkgDir, './templates') - - const allTemplateFileNames = fs.readdirSync(templatesDir) - const templateFiles = Object.fromEntries( - allTemplateFileNames.map((fileName) => { - const content = fs.readFileSync(path.resolve(templatesDir, fileName), 'utf8') - return [`./templates/${fileName}`, content] - }), - ) - - return ` - import ejs from 'ejs' - const templates = ${JSON.stringify(templateFiles)} - export default function renderEjsFile(filePath, data) { - return ejs.render(templates[filePath], data, {}) - } - ` - }, - }, - }, ], }) diff --git a/template/config/typescript/package.json b/template/config/typescript/package.json index 2c755e61..157bc3d7 100644 --- a/template/config/typescript/package.json +++ b/template/config/typescript/package.json @@ -7,7 +7,7 @@ "devDependencies": { "@types/node": "^24.10.4", "npm-run-all2": "^8.0.4", - "typescript": "~5.9.0", + "typescript": "~5.9.3", "vue-tsc": "^3.2.1" } } diff --git a/template/eslint/package.json b/template/eslint/package.json deleted file mode 100644 index 7ca2de36..00000000 --- a/template/eslint/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "devDependencies": { - "@vitest/eslint-plugin": "^1.5.4", - "eslint-plugin-cypress": "^5.2.0", - "eslint-plugin-playwright": "^2.4.0" - } -} diff --git a/template/config/oxlint/.vscode/extensions.json b/template/formatting/oxfmt/.vscode/extensions.json similarity index 100% rename from template/config/oxlint/.vscode/extensions.json rename to template/formatting/oxfmt/.vscode/extensions.json diff --git a/template/formatting/oxfmt/.vscode/settings.json b/template/formatting/oxfmt/.vscode/settings.json new file mode 100644 index 00000000..16f965cf --- /dev/null +++ b/template/formatting/oxfmt/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "[javascript]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "oxc.oxc-vscode" + } +} diff --git a/template/formatting/oxfmt/_oxfmtrc.jsonc b/template/formatting/oxfmt/_oxfmtrc.jsonc new file mode 100644 index 00000000..2de1f92b --- /dev/null +++ b/template/formatting/oxfmt/_oxfmtrc.jsonc @@ -0,0 +1,5 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "semi": false, + "singleQuote": true, +} diff --git a/template/formatting/oxfmt/_prettierrc.json b/template/formatting/oxfmt/_prettierrc.json new file mode 100644 index 00000000..a84e0edf --- /dev/null +++ b/template/formatting/oxfmt/_prettierrc.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://json.schemastore.org/prettierrc", + "semi": false, + "singleQuote": true, + "printWidth": 100, + "plugins": ["@prettier/plugin-oxc"] +} diff --git a/template/formatting/oxfmt/package.json b/template/formatting/oxfmt/package.json new file mode 100644 index 00000000..49845de2 --- /dev/null +++ b/template/formatting/oxfmt/package.json @@ -0,0 +1,13 @@ +{ + "scripts": { + "format:oxfmt": "oxfmt src/", + "format:prettier": "prettier --write --experimental-cli src/ '!**/*.{js,jsx,ts,tsx}'", + "format": "run-p format:oxfmt format:prettier" + }, + "devDependencies": { + "@prettier/plugin-oxc": "^0.1.3", + "npm-run-all2": "^8.0.4", + "prettier": "3.7.4", + "oxfmt": "^0.18.0" + } +} diff --git a/template/config/prettier/.vscode/extensions.json b/template/formatting/prettier/.vscode/extensions.json similarity index 100% rename from template/config/prettier/.vscode/extensions.json rename to template/formatting/prettier/.vscode/extensions.json diff --git a/template/config/prettier/.vscode/settings.json b/template/formatting/prettier/.vscode/settings.json similarity index 100% rename from template/config/prettier/.vscode/settings.json rename to template/formatting/prettier/.vscode/settings.json diff --git a/template/config/prettier/_prettierrc.json b/template/formatting/prettier/_prettierrc.json similarity index 100% rename from template/config/prettier/_prettierrc.json rename to template/formatting/prettier/_prettierrc.json diff --git a/template/config/prettier/package.json b/template/formatting/prettier/package.json similarity index 100% rename from template/config/prettier/package.json rename to template/formatting/prettier/package.json diff --git a/template/config/eslint/.vscode/extensions.json b/template/linting/base/.vscode/extensions.json similarity index 100% rename from template/config/eslint/.vscode/extensions.json rename to template/linting/base/.vscode/extensions.json diff --git a/template/config/eslint/.vscode/settings.json b/template/linting/base/.vscode/settings.json similarity index 100% rename from template/config/eslint/.vscode/settings.json rename to template/linting/base/.vscode/settings.json diff --git a/template/linting/base/_editorconfig b/template/linting/base/_editorconfig new file mode 100644 index 00000000..3b510aa6 --- /dev/null +++ b/template/linting/base/_editorconfig @@ -0,0 +1,8 @@ +[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}] +charset = utf-8 +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true +end_of_line = lf +max_line_length = 100 diff --git a/template/config/prettier/_gitattributes b/template/linting/base/_gitattributes similarity index 100% rename from template/config/prettier/_gitattributes rename to template/linting/base/_gitattributes diff --git a/template/linting/base/package.json b/template/linting/base/package.json new file mode 100644 index 00000000..9f1b863f --- /dev/null +++ b/template/linting/base/package.json @@ -0,0 +1,9 @@ +{ + "scripts": { + "lint": "eslint . --fix --cache" + }, + "devDependencies": { + "eslint-plugin-vue": "~10.6.2", + "eslint": "^9.39.2" + } +} diff --git a/template/linting/core/js/eslint.config.js.data.mjs b/template/linting/core/js/eslint.config.js.data.mjs new file mode 100644 index 00000000..62e48a50 --- /dev/null +++ b/template/linting/core/js/eslint.config.js.data.mjs @@ -0,0 +1,15 @@ +export default function getData() { + return { + configs: [ + { + importer: `import js from '@eslint/js'`, + content: ` js.configs.recommended,`, + }, + + { + importer: `import pluginVue from 'eslint-plugin-vue'`, + content: ` ...pluginVue.configs['flat/essential'],`, + }, + ], + } +} diff --git a/template/linting/core/js/eslint.config.js.ejs b/template/linting/core/js/eslint.config.js.ejs new file mode 100644 index 00000000..8d9971cb --- /dev/null +++ b/template/linting/core/js/eslint.config.js.ejs @@ -0,0 +1,27 @@ +import { defineConfig, globalIgnores } from 'eslint/config' +import globals from 'globals' +<%_ for (const { importer } of configs) { _%> +<%_ if (importer) { _%><%- importer %> +<%_ } _%> +<%_ } _%> + +export default defineConfig([ + { + name: 'app/files-to-lint', + files: ['**/*.{vue,js,mjs,jsx}'], + }, + + globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']), + + { + languageOptions: { + globals: { + ...globals.browser, + }, + }, + }, + +<%_ for (const { content } of configs) { _%> +<%- content %> +<%_ } _%> +]) diff --git a/template/linting/core/js/package.json b/template/linting/core/js/package.json new file mode 100644 index 00000000..1bdd664b --- /dev/null +++ b/template/linting/core/js/package.json @@ -0,0 +1,8 @@ +{ + "devDependencies": { + "@eslint/js": "^9.39.2", + "eslint-plugin-vue": "~10.6.2", + "eslint": "^9.39.2", + "globals": "^16.5.0" + } +} diff --git a/template/linting/core/ts/eslint.config.js.data.mjs b/template/linting/core/ts/eslint.config.js.data.mjs new file mode 100644 index 00000000..486b1c72 --- /dev/null +++ b/template/linting/core/ts/eslint.config.js.data.mjs @@ -0,0 +1,15 @@ +export default function getData() { + return { + configs: [ + { + importer: `import pluginVue from 'eslint-plugin-vue'`, + content: ` ...pluginVue.configs['flat/essential'],`, + }, + + { + // skipped importer for this one because it was already there + content: ` vueTsConfigs.recommended,`, + }, + ], + } +} diff --git a/template/linting/core/ts/eslint.config.js.ejs b/template/linting/core/ts/eslint.config.js.ejs new file mode 100644 index 00000000..9378b68f --- /dev/null +++ b/template/linting/core/ts/eslint.config.js.ejs @@ -0,0 +1,24 @@ +import { globalIgnores } from 'eslint/config' +import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript' +<%_ for (const { importer } of configs) { _%> +<%_ if (importer) { _%><%- importer %> +<%_ } _%> +<%_ } _%> + +// To allow more languages other than `ts` in `.vue` files, uncomment the following lines: +// import { configureVueProject } from '@vue/eslint-config-typescript' +// configureVueProject({ scriptLangs: ['ts', 'tsx'] }) +// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup + +export default defineConfigWithVueTs( + { + name: 'app/files-to-lint', + files: ['**/*.{vue,ts,mts,tsx}'], + }, + + globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']), + +<%_ for (const { content } of configs) { _%> +<%- content %> +<%_ } _%> +) diff --git a/template/linting/core/ts/package.json b/template/linting/core/ts/package.json new file mode 100644 index 00000000..6dc0dfb3 --- /dev/null +++ b/template/linting/core/ts/package.json @@ -0,0 +1,9 @@ +{ + "devDependencies": { + "@vue/eslint-config-typescript": "^14.6.0", + "eslint": "^9.39.2", + "eslint-plugin-vue": "~10.6.2", + "jiti": "^2.6.1", + "typescript": "~5.9.3" + } +} diff --git a/template/linting/cypress-ct/eslint.config.js.data.mjs b/template/linting/cypress-ct/eslint.config.js.data.mjs new file mode 100644 index 00000000..2e4ccf2b --- /dev/null +++ b/template/linting/cypress-ct/eslint.config.js.data.mjs @@ -0,0 +1,25 @@ +export default function getData({ oldData }) { + return { + ...oldData, + configs: oldData.configs.map((c) => { + if (!c.content.includes('pluginCypress')) { + return c + } + + return { + ...c, + + // modify the files pattern to include component testing files + content: ` + { + ...pluginCypress.configs.recommended, + files: [ + '**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}', + 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', + 'cypress/support/**/*.{js,ts,jsx,tsx}', + ], + },`, + } + }), + } +} diff --git a/template/linting/cypress/eslint.config.js.data.mjs b/template/linting/cypress/eslint.config.js.data.mjs new file mode 100644 index 00000000..58b37de3 --- /dev/null +++ b/template/linting/cypress/eslint.config.js.data.mjs @@ -0,0 +1,19 @@ +export default function getData({ oldData }) { + return { + ...oldData, + configs: [ + ...oldData.configs, + { + importer: `import pluginCypress from 'eslint-plugin-cypress'`, + content: ` + { + ...pluginCypress.configs.recommended, + files: [ + 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', + 'cypress/support/**/*.{js,ts,jsx,tsx}', + ], + },`, + }, + ], + } +} diff --git a/template/linting/cypress/package.json b/template/linting/cypress/package.json new file mode 100644 index 00000000..f3638c93 --- /dev/null +++ b/template/linting/cypress/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "eslint-plugin-cypress": "^5.2.0" + } +} diff --git a/template/linting/oxlint/.vscode/extensions.json b/template/linting/oxlint/.vscode/extensions.json new file mode 100644 index 00000000..99e2f7dd --- /dev/null +++ b/template/linting/oxlint/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oxc.oxc-vscode"] +} diff --git a/template/linting/oxlint/_ oxlintrc.json b/template/linting/oxlint/_ oxlintrc.json new file mode 100644 index 00000000..d5648b96 --- /dev/null +++ b/template/linting/oxlint/_ oxlintrc.json @@ -0,0 +1,10 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["eslint", "typescript", "unicorn", "oxc", "vue"], + "env": { + "browser": true + }, + "categories": { + "correctness": "error" + } +} diff --git a/template/linting/oxlint/eslint.config.js.data.mjs b/template/linting/oxlint/eslint.config.js.data.mjs new file mode 100644 index 00000000..4601d74c --- /dev/null +++ b/template/linting/oxlint/eslint.config.js.data.mjs @@ -0,0 +1,12 @@ +export default function getData({ oldData }) { + return { + ...oldData, + configs: [ + ...oldData.configs, + { + importer: `import pluginOxlint from 'eslint-plugin-oxlint'`, + content: `\n ...pluginOxlint.configs['flat/recommended'],`, + }, + ], + } +} diff --git a/template/linting/oxlint/package.json b/template/linting/oxlint/package.json new file mode 100644 index 00000000..07c9542b --- /dev/null +++ b/template/linting/oxlint/package.json @@ -0,0 +1,12 @@ +{ + "scripts": { + "lint:oxlint": "oxlint . --fix", + "lint:eslint": "eslint . --fix --cache", + "lint": "run-s lint:*" + }, + "devDependencies": { + "eslint-plugin-oxlint": "~1.33.0", + "npm-run-all2": "^8.0.4", + "oxlint": "~1.33.0" + } +} diff --git a/template/linting/playwright/eslint.config.js.data.mjs b/template/linting/playwright/eslint.config.js.data.mjs new file mode 100644 index 00000000..1900c753 --- /dev/null +++ b/template/linting/playwright/eslint.config.js.data.mjs @@ -0,0 +1,16 @@ +export default function getData({ oldData }) { + return { + ...oldData, + configs: [ + ...oldData.configs, + { + importer: "import pluginPlaywright from 'eslint-plugin-playwright'", + content: ` + { + ...pluginPlaywright.configs['flat/recommended'], + files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'], + },`, + }, + ], + } +} diff --git a/template/linting/playwright/package.json b/template/linting/playwright/package.json new file mode 100644 index 00000000..6c3f127f --- /dev/null +++ b/template/linting/playwright/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "eslint-plugin-playwright": "^2.4.0" + } +} diff --git a/template/linting/prettier/eslint.config.js.data.mjs b/template/linting/prettier/eslint.config.js.data.mjs new file mode 100644 index 00000000..81db21fb --- /dev/null +++ b/template/linting/prettier/eslint.config.js.data.mjs @@ -0,0 +1,12 @@ +export default function getData({ oldData }) { + return { + ...oldData, + configs: [ + ...oldData.configs, + { + importer: `import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'`, + content: `\n skipFormatting,`, + }, + ], + } +} diff --git a/template/linting/prettier/package.json b/template/linting/prettier/package.json new file mode 100644 index 00000000..16577b37 --- /dev/null +++ b/template/linting/prettier/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "@vue/eslint-config-prettier": "^10.2.0", + "prettier": "3.7.4" + } +} diff --git a/template/linting/vitest/eslint.config.js.data.mjs b/template/linting/vitest/eslint.config.js.data.mjs new file mode 100644 index 00000000..95321768 --- /dev/null +++ b/template/linting/vitest/eslint.config.js.data.mjs @@ -0,0 +1,16 @@ +export default function getData({ oldData }) { + return { + ...oldData, + configs: [ + ...oldData.configs, + { + importer: `import pluginVitest from '@vitest/eslint-plugin'`, + content: ` + { + ...pluginVitest.configs.recommended, + files: ['src/**/__tests__/*'], + },`, + }, + ], + } +} diff --git a/template/linting/vitest/package.json b/template/linting/vitest/package.json new file mode 100644 index 00000000..91497575 --- /dev/null +++ b/template/linting/vitest/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "@vitest/eslint-plugin": "^1.5.2" + } +} diff --git a/utils/renderEslint.ts b/utils/renderEslint.ts deleted file mode 100644 index 82354385..00000000 --- a/utils/renderEslint.ts +++ /dev/null @@ -1,144 +0,0 @@ -import * as fs from 'node:fs' -import * as path from 'node:path' - -import createESLintConfig from '@vue/create-eslint-config' - -import sortDependencies from './sortDependencies' -import deepMerge from './deepMerge' - -import eslintTemplatePackage from '../template/eslint/package.json' with { type: 'json' } -const eslintDeps = eslintTemplatePackage.devDependencies - -export default function renderEslint( - rootDir, - { - needsTypeScript, - needsVitest, - needsCypress, - needsCypressCT, - needsOxlint, - needsPrettier, - needsPlaywright, - }, -) { - const additionalConfigs = getAdditionalConfigs({ - needsTypeScript, - needsVitest, - needsCypress, - needsCypressCT, - needsPlaywright, - }) - - const { pkg, files } = createESLintConfig({ - styleGuide: 'default', - hasTypeScript: needsTypeScript, - needsOxlint, - // Theoretically, we could add Prettier without requring ESLint. - // But it doesn't seem to be a good practice, so we just let createESLintConfig handle it. - needsPrettier, - additionalConfigs, - }) - - // update package.json - const packageJsonPath = path.resolve(rootDir, 'package.json') - const existingPkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) - const updatedPkg = sortDependencies(deepMerge(existingPkg, pkg)) - fs.writeFileSync(packageJsonPath, JSON.stringify(updatedPkg, null, 2) + '\n', 'utf8') - - // write to eslint.config.js, .prettierrc.json, .editorconfig, etc. - for (const [fileName, content] of Object.entries(files)) { - const fullPath = path.resolve(rootDir, fileName) - fs.writeFileSync(fullPath, content as string, 'utf8') - } -} - -type ConfigItemInESLintTemplate = { - importer: string - content: string -} -type AdditionalConfig = { - devDependencies: Record - beforeVuePlugin?: Array - afterVuePlugin?: Array -} -type AdditionalConfigArray = Array - -// visible for testing -export function getAdditionalConfigs({ - needsTypeScript, - needsVitest, - needsCypress, - needsCypressCT, - needsPlaywright, -}) { - const additionalConfigs: AdditionalConfigArray = [] - - if (needsVitest) { - additionalConfigs.push({ - devDependencies: { - '@vitest/eslint-plugin': eslintDeps['@vitest/eslint-plugin'], - }, - afterVuePlugin: [ - { - importer: `import pluginVitest from '@vitest/eslint-plugin'`, - content: ` - { - ...pluginVitest.configs.recommended, - files: ['src/**/__tests__/*'], - },`, - }, - ], - }) - } - - if (needsCypress) { - additionalConfigs.push({ - devDependencies: { - 'eslint-plugin-cypress': eslintDeps['eslint-plugin-cypress'], - }, - afterVuePlugin: [ - { - importer: - (needsTypeScript - ? `// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n` + - `// @ts-ignore\n` - : '') + "import pluginCypress from 'eslint-plugin-cypress'", - content: ` - { - ...pluginCypress.configs.recommended, - files: [ - ${[ - ...(needsCypressCT ? ['**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}'] : []), - 'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}', - 'cypress/support/**/*.{js,ts,jsx,tsx}', - ] - .map(JSON.stringify.bind(JSON)) - .join(',\n ') - .replace(/"/g, "'" /* use single quotes as in the other configs */)} - ], - },`, - }, - ], - }) - } - - if (needsPlaywright) { - additionalConfigs.push({ - devDependencies: { - 'eslint-plugin-playwright': eslintDeps['eslint-plugin-playwright'], - }, - afterVuePlugin: [ - { - importer: "import pluginPlaywright from 'eslint-plugin-playwright'", - content: ` - { - ...pluginPlaywright.configs['flat/recommended'], - files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'], - },`, - }, - ], - }) - } - - return additionalConfigs -}