Skip to content

Instantly share code, notes, and snippets.

@cm-wada-yusuke
Last active February 8, 2022 23:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cm-wada-yusuke/2002a761a00015dc913ea9222ce11496 to your computer and use it in GitHub Desktop.
Save cm-wada-yusuke/2002a761a00015dc913ea9222ce11496 to your computer and use it in GitHub Desktop.
ESLint for TypeScript node
module.exports = {
env: {
node: true,
},
parser: '@typescript-eslint/parser',
plugins: ['node', '@typescript-eslint'],
parserOptions: {
sourceType: 'module',
project: [
'./tsconfig.json',
'./tsconfig.cdk.json',
'./tsconfig.src.json',
'./tsconfig.test.json'
],
},
rules: {
semi: 'off',
'@typescript-eslint/semi': ['error'],
// クラス定義は見通しの関係上外部公開メソッドを先に記載することもあるため無効にする
'@typescript-eslint/no-use-before-define': [
'error',
{ functions: true, classes: false, variables: true },
],
// 明らかに値を持っており、持っていないケースは想定外として process.env.TableName! など意図的に利用するため除外
'@typescript-eslint/no-non-null-assertion': 'off',
// prettier と競合しているためeslint側を無効にする
'@typescript-eslint/indent': 'off',
// モック化するときに、主に外部ライブラリを上書きする際にvarが必要
'@typescript-eslint/no-var-requires': 'off',
// パラメータとして渡す関数は自明なので明示しなくてよい
'@typescript-eslint/explicit-function-return-type': [
'error',
{
allowExpressions: true,
allowTypedFunctionExpressions: true,
allowHigherOrderFunctions: true,
},
],
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
],
};
*.js
!jest.config.*.js
!*/**/jest.sequencer.js
!.eslintrc.js
*.d.ts
node_modules
dist/
# CDK asset staging directory
.cdk.staging
cdk.out
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
.venv/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next
# IDE settings
.idea/
.vscode
# tsas
dist/
deploy/
# Report
report*
output*
# java
.gradle/
{
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "all",
"useTabs": false,
"tabWidth": 4,
"semi": true,
"bracketSpacing": true,
"arrowParens": "avoid"
}

Lambda Function 用のディレクトリとサンプルを作成する

> mkdir -p src/lambda/handlers
> curl -o src/lambda/handlers/apig-hello-world-handlers.ts  https://gist.githubusercontent.com/cm-wada-yusuke/2002a761a00015dc913ea9222ce11496/raw/apig-hello-world-handler.ts

CDK用と Lambda 用の tsconfig を作成する

tsconfig.json を上書きダウンロード

curl -O https://gist.githubusercontent.com/cm-wada-yusuke/2002a761a00015dc913ea9222ce11496/raw/tsconfig.json
補足
  • 型定義は不要なので "declaration": false,
  • commonjs ライブラリも require ではなく import from で使いたいので "esModuleInterop": true,

テストコードで ソースコードを絶対パスで読み込めるようにする

    "baseUrl": ".",
    "paths": {
      "@app/*": [
        "src/*"
      ]
    }

srcは個別に設定するためここでは除外

  "exclude": [
    "cdk.out",
    "dist",
    "node_modules",
    "src"
  ]

tsconfig.src.json

curl -O https://gist.githubusercontent.com/cm-wada-yusuke/2002a761a00015dc913ea9222ce11496/raw/tsconfig.src.json
  • ルートディレクトリと出力ディレクトリを指定

tsconfig.cdk.json

curl -O https://gist.githubusercontent.com/cm-wada-yusuke/2002a761a00015dc913ea9222ce11496/raw/tsconfig.cdk.json

tsconfig.test.json

curl -O https://gist.githubusercontent.com/cm-wada-yusuke/2002a761a00015dc913ea9222ce11496/raw/tsconfig.test.json

TypeScript のための ESLint をインストール&設定する

yarn add -D \
eslint \
eslint-config-prettier \
eslint-plugin-node \
prettier \
@typescript-eslint/eslint-plugin \
@typescript-eslint/parser 

curl -O https://gist.githubusercontent.com/cm-wada-yusuke/2002a761a00015dc913ea9222ce11496/raw/.eslintrc.js

curl -O https://gist.githubusercontent.com/cm-wada-yusuke/2002a761a00015dc913ea9222ce11496/raw/.prettierrc.json
yarn add -D \
husky \
lint-staged

package.json

husky と lint-staged はルートディレクトリの pakcage.json に設定する。リンターは各モノレポルートに設定する。単一プロジェクトのリポジトリの場合は、以下のように一緒に設定できる。

  "scripts": {
    "lint": "eslint --cache './**/*.{ts,tsx}' && prettier --check './**/*.{ts,tsx}'",
    "lint-fix": "eslint --cache --fix './**/*.{ts,tsx}' && prettier --write './**/*.{ts,tsx}'",
    "lint-staged": "lint-staged"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.ts": [
      "yarn run lint-fix",
      "yarn run lint",
      "git add"
    ]
  }  

.gitignore

curl -O https://gist.githubusercontent.com/cm-wada-yusuke/2002a761a00015dc913ea9222ce11496/raw/.gitignore
import 'source-map-support/register';
export async function apigHelloWorldHandler(event: Request): Promise<Response> {
const message = `Hello, ${event.name}!`;
return {
message
}
}
interface Request {
name: string;
}
interface Response {
message: string;
}
{
"extends": "./tsconfig",
"compilerOptions": {},
"include": [
"lib/**/*.ts",
"bin/**/*.ts"
]
}
{
"compilerOptions": {
"target":"ES2018",
"module": "commonjs",
"lib": ["es2018"],
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": false,
"inlineSourceMap": true,
"inlineSources": true,
"experimentalDecorators": true,
"strictPropertyInitialization":false,
"typeRoots": ["./node_modules/@types"],
"esModuleInterop": true,
"declaration": false,
"baseUrl": ".",
"paths": {
"@app/*": [
"src/*"
]
}
},
"exclude": [
"cdk.out",
"dist",
"node_modules",
"src"
]
}
{
"extends": "./tsconfig",
"compilerOptions": {
"rootDir": "src",
"outDir": "./dist/src"
},
"exclude": [
"cdk.out",
"dist",
"node_modules",
"test",
"lib"
],
"include": [
"./src/**/*.ts"
]
}
{
"extends": "./tsconfig",
"compilerOptions": {
"rootDir": "test",
"noEmit": true,
"baseUrl": ".",
"paths": {
"@app/*": [
"src/*"
]
}
},
"include": [
"./test/**/*.test.ts",
"./test/**/*.ts"
],
"exclude": [
"./test/**/*.js",
"jest.config.*.js"
]
}
@michael-guild-kgs
Copy link

nice 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment