@mheob/eslint-config
Version:
My personal configuration for eslint.
59 lines (55 loc) • 6.32 kB
JavaScript
import e from"node:process";import*as t from"@clack/prompts";import n,{green as r}from"ansis";import{cac as i}from"cac";import a from"node:fs";import o from"node:path";import s from"node:fs/promises";import c from"parse-gitignore";import{execSync as l}from"node:child_process";var u=`9.1.0`;const d=`
// Disable the default formatter, use eslint instead
"prettier.enable": false,
"editor.formatOnSave": false,
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off", "fixable": true },
{ "rule": "format/*", "severity": "off", "fixable": true },
{ "rule": "*-indent", "severity": "off", "fixable": true },
{ "rule": "*-spacing", "severity": "off", "fixable": true },
{ "rule": "*-spaces", "severity": "off", "fixable": true },
{ "rule": "*-order", "severity": "off", "fixable": true },
{ "rule": "*-dangle", "severity": "off", "fixable": true },
{ "rule": "*-newline", "severity": "off", "fixable": true },
{ "rule": "*quotes", "severity": "off", "fixable": true },
{ "rule": "*semi", "severity": "off", "fixable": true }
],
// Enable eslint for all supported languages
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"json5",
"jsonc",
"yaml",
"toml",
"xml",
"gql",
"graphql",
"astro",
"svelte",
"css",
"less",
"scss",
"pcss",
"postcss"
]
`,f=[{label:n.magenta(`Astro`),value:`astro`},{label:n.cyan(`React`),value:`react`},{label:n.red(`Svelte`),value:`svelte`},{label:n.green(`Vue`),value:`vue`}],p=f.map(({value:e})=>e),m={astro:[`eslint-plugin-astro`,`astro-eslint-parser`],formatterAstro:[`prettier-plugin-astro`],nextjs:[`@next/eslint-plugin-next`],react:[`@eslint-react/eslint-plugin`,`eslint-plugin-react-hooks`,`eslint-plugin-react-refresh`],svelte:[`eslint-plugin-svelte`,`svelte-eslint-parser`],vue:[]};function h(){try{return l(`git diff-index --quiet HEAD --`),!0}catch{return!1}}function g(e,t){return`
import defaultConfig from '@mheob/eslint-config'
export default defaultConfig({
${e}
}${t?.map(e=>`,{\n${e}\n}`)})
`.trimStart()}async function _(r){let i=e.cwd(),l=o.join(i,`.eslintignore`),u=`eslint.config.mjs`,d=o.join(i,u),f=[];if(a.existsSync(l)){t.log.step(n.cyan`Migrating existing .eslintignore`);let e=c(await s.readFile(l,`utf8`)).globs();for(let t of e)t.type===`ignore`?f.push(...t.patterns):t.type===`unignore`&&f.push(...t.patterns.map(e=>`!${e}`))}let p=[];f.length>0&&p.push(`ignores: ${JSON.stringify(f)},`);for(let e of r.frameworks)p.push(`${e}: true,`);let m=g(p.map(e=>` ${e}`).join(`
`),[]);await s.writeFile(d,m),t.log.success(n.green`Created ${u}`);let h=a.readdirSync(i),_=[];for(let e of h)/eslint|prettier/.test(e)&&!/eslint\.config\./.test(e)&&_.push(e);_.length>0&&t.note(n.dim(_.join(`, `)),`You can now remove those files manually`)}const v={"@eslint-react/eslint-plugin":`^2.3.12`,"@next/eslint-plugin-next":`^16.0.7`,"astro-eslint-parser":`^1.2.2`,eslint:`^9.39.1`,"eslint-plugin-astro":`^1.5.0`,"eslint-plugin-react-hooks":`^7.0.1`,"eslint-plugin-react-refresh":`^0.4.24`,"eslint-plugin-svelte":`^3.13.1`,"prettier-plugin-astro":`^0.14.1`,"svelte-eslint-parser":`^1.4.1`};async function y(r){let i=e.cwd(),a=o.join(i,`package.json`);t.log.step(n.cyan`Bumping @mheob/eslint-config to v${u}`);let c=await s.readFile(a,`utf8`),l=JSON.parse(c);l.devDependencies??={},l.devDependencies[`@mheob/eslint-config`]=`^${u}`,l.devDependencies.eslint??=v.eslint;let d=[];for(let e of r.frameworks){let t=m[e];if(t)for(let e of t)l.devDependencies[e]=v[e],d.push(e)}d.length>0&&t.note(n.dim(d.join(`, `)),`Added packages`),await s.writeFile(a,JSON.stringify(l,null,2)),t.log.success(n.green`Changes wrote to package.json`)}async function b(n){let i=e.cwd();if(!n.updateVscodeSettings)return;let c=o.join(i,`.vscode`),l=o.join(c,`settings.json`);if(a.existsSync(c)||await s.mkdir(c,{recursive:!0}),!a.existsSync(l))await s.writeFile(l,`{${d}}\n`,`utf8`),t.log.success(r`Created .vscode/settings.json`);else{let e=await s.readFile(l,`utf8`);e=e.trim().replace(/\s*\}$/,``),e+=e.endsWith(`,`)||e.endsWith(`{`)?``:`,`,e+=`${d}}\n`,await s.writeFile(l,e,`utf8`),t.log.success(r`Updated .vscode/settings.json`)}}async function x(r={}){let i=!!e.env.SKIP_PROMPT||r.yes,s=r.frameworks?.map(e=>e?.trim()).filter(Boolean);if((t=>t.some(t=>a.existsSync(o.join(e.cwd(),t))))([`eslint.config.js`,`eslint.config.mjs`]))return t.log.warn(n.yellow`eslint.config.js already exists, migration wizard exited.`),e.exit(1);let c={frameworks:s??[],uncommittedConfirmed:!1,updateVscodeSettings:!0};if(!i&&(c=await t.group({uncommittedConfirmed:()=>h()?Promise.resolve(!0):t.confirm({initialValue:!1,message:`There are uncommitted changes in the current repository, are you sure to continue?`}),frameworks:({results:e})=>{let r=typeof s==`string`&&!!p.includes(s);if(!e.uncommittedConfirmed||r)return;let i=!r&&s?`"${s}" isn't a valid template. Please choose from below: `:`Select a framework:`;return t.multiselect({message:n.reset(i),options:f,required:!1})},updateVscodeSettings:({results:e})=>{if(e.uncommittedConfirmed)return t.confirm({initialValue:!0,message:`Update .vscode/settings.json for better VS Code experience?`})}},{onCancel:()=>{t.cancel(`Operation cancelled.`),e.exit(0)}}),!c.uncommittedConfirmed))return e.exit(1);await y(c),await _(c),await b(c),t.log.success(n.green`Setup completed`),t.outro(`Now you can update the dependencies by run ${n.blue(`pnpm install`)} and run ${n.blue(`eslint --fix`)}\n`)}const S=`@mheob/eslint-config`;function C(){console.log(`
`),t.intro(n.green`${S} `+n.dim`v${u}`)}const w=i(S);w.command(``,`Run the initialization or migration`).option(`--yes, -y`,`Skip prompts and use default values`,{default:!1}).option(`--template, -t <template>`,`Use the framework template for optimal customization: vue / react / svelte / astro`,{type:[]}).action(async r=>{C();try{await x(r)}catch(r){t.log.error(n.inverse.red(` Failed to migrate `)),t.log.error(n.red`✘ ${String(r)}`),e.exit(1)}}),w.help(),w.version(u),w.parse();export{};