Open6
TypeScriptプロジェクトの最強初期設定

毎回最新最強構成を調べるの飽きた!!!!!
プリセット使うにしても結局中身が気になる!!!!!!!

TypeScript
npm install -D typescript better-typescript-lib
早くTypeScriptデフォルトの型定義が正気になってbetter-typescript-libが不要になる時代が来てほしい。
Pretter + ESLint
# 基本
npm install -D prettier eslint eslint-config-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser
npm install -D eslint-import-resolver-typescript eslint-plugin-import eslint-plugin-n eslint-plugin-promise eslint-plugin-unicorn eslint-plugin-unused-imports
# CSS
npm install -D stylelint stylelint-prettier
# React
npm install -D eslint-plugin-react eslint-plugin-react-hooks

eslint.config.mjs
マジでこれ用意するわけ??? プロジェクト作るごとに???????
eslint実行時は ESLINT_USE_FLAT_CONFIG=true eslint -c eslint.config.mjs {args}
する
eslint.config.mjs
import {FlatCompat} from '@eslint/eslintrc'
import js from '@eslint/js'
import reactPlugin from 'eslint-plugin-import'
import importPlugin from 'eslint-plugin-import'
import nPlugin from 'eslint-plugin-n'
import unusedImportsPlugin from 'eslint-plugin-unused-imports'
import unicornPlugin from 'eslint-plugin-unicorn'
import parser from '@typescript-eslint/parser'
import path from 'node:path'
import {fileURLToPath} from 'node:url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
});
export default [
...compat.extends(
"eslint:recommended",
"plugin:n/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:@typescript-eslint/recommended-type-checked",
"plugin:@typescript-eslint/stylistic-type-checked",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:storybook/recommended",
"prettier",
),
{
files: ["src/**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
parser,
parserOptions: {
project: [
"tsconfig.json"
],
},
},
linterOptions: {
reportUnusedDisableDirectives: true,
},
plugins: {
"unused-imports": unusedImportsPlugin,
unicorn: unicornPlugin,
},
rules: {
"no-extra-semi": "off",
"@typescript-eslint/no-extra-semi": "error",
"@typescript-eslint/no-non-null-assertion": "warn",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "off",
"unused-imports/no-unused-imports": "warn",
"unused-imports/no-unused-vars": [
"warn",
{
vars: "all",
varsIgnorePattern: "^_",
args: "after-used",
argsIgnorePattern: "^_",
},
],
"react-hooks/exhaustive-deps": [
"warn",
{
additionalHooks: "(useRecoilCallback|useRecoilTransaction_UNSTABLE)",
},
],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "error",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/consistent-type-definitions": ["warn", "type"],
"import/order": ["error"],
"import/namespace": "off", // Not works with flat config for some reason
"unicorn/better-regex": ["error"],
"unicorn/escape-case": ["error"],
"unicorn/new-for-builtins": ["error"],
"unicorn/no-array-callback-reference": ["error"],
"unicorn/no-array-for-each": ["error"],
"unicorn/no-array-method-this-argument": ["error"],
"unicorn/no-for-loop": ["error"],
"unicorn/no-instanceof-array": ["error"],
"unicorn/no-invalid-remove-event-listener": ["error"],
"unicorn/no-unnecessary-await": ["error"],
"unicorn/no-unsafe-regex": ["error"],
"unicorn/numeric-separators-style": ["error"],
"unicorn/prefer-date-now": ["error"],
"unicorn/prefer-modern-dom-apis": ["error"],
"unicorn/prefer-modern-math-apis": ["error"],
"unicorn/prefer-node-protocol": ["error"],
"unicorn/throw-new-error": ["error"],
"unicorn/switch-case-braces": ["error"],
// Can't handle tsconfig by default
"n/no-missing-import": "off",
},
settings: {
react: {
version: "detect",
},
"import/resolver": {
typescript: {
alwaysTryTypes: true,
project: ["tsconfig.json"],
},
},
},
},
];

stylelintrc.yml
plugins:
- stylelint-prettier
rules:
"prettier/prettier": true

npm i @todesking/typescript-project-preset
で全て終わらせる仕組みを作るとよさそう

npm init @foo/bar
は npx @foo/create-bar
と解釈されるらしい!!