ss環境構築
まっさらな状態からcurlを叩いて「Hello World」を表示する
src > app.ts
import express from "express"
const app = express()
app.use(express.json())
app.get("/", async (_req, res) => {
res.end("Hello World")
})
const port = 8080
app.listen(port, () => {
// eslintでconsoleのエラーが出ないよう下記を追加
// eslint-disable-next-line no-console
console.log(`Listening on port ${port}`)
})
dependencies
コマンド
yarn add express
:サーバーサイド Javascript の実行環境
yarn add dotenv
:見せれない情報を.env ファイルで管理することで公開させない
yarn add winston
:複数のトランスポート(出力先)をサポートするロギングライブラリ
devDependencies
コマンド
yarn add -D @types/express
:expressの開発にtsを利用する
yarn add -D @types/node
:ts を使う時、node_modules の型定義ファイル
yarn add -D cspell
:スペルチェック → cspell.json 手書き、cspell.txt 作成
yarn add -D eslint
:単純な構文エラーやプロジェクト固有のコーディング規約を定義することができる
→ 自由にルールを設定できる、rules で上書きすることでルールを緩くできる(.eslintrc.js)
yarn add -D eslint-config-prettier
:Prettierと競合する可能性のあるルールをすべてオフにする
yarn add -D fixpack
:package.json内を並び替え
yarn add -D prettier
:ソースコードを整形してくれるツール(コードフォーマッター)
→ eslint では整形できないコードを整形できる
yarn add -D ts-node
:ts を毎回 tsc コマンドを叩いて js にコンパイルことをしなくてもよくするやつ
yarn add -D ts-node-dev
:ts ファイルを js ファイルにコンパイルすることなく、起動することができ、 さらに監視モードで素早く再起動が使用できる
yarn add -D typescript
:Typescriptの使用
tsconfig.json
yarn run tsc --init
でjsonを作成
{
"compilerOptions": {
"target": "ES2021",
"lib": ["ES2021"],
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"outDir": "./dist",
"noEmit": true,
"downlevelIteration": true,
"isolatedModules": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"useUnknownInCatchVariables": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"allowUnusedLabels": true,
"allowUnreachableCode": true
},
"exclude": ["node_modules"],
"include": ["**/*.ts"]
}
cspell.json
{
"version": "0.2",
"language": "en",
"dictionaries": ["en", "typescript"],
"dictionaryDefinitions": [
{
"name": "en",
"path": "./cspell.txt"
}
],
"ignorePaths": ["node_modules/**"]
}
.eslintrc.js
const OFF = 0; // eslint-disable-line no-unused-vars
const WARN = 1; // eslint-disable-line no-unused-vars
const ERROR = 2; // eslint-disable-line no-unused-vars
module.exports = {
root: true,
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier",
],
env: {
node: true,
es2021: true,
},
rules: {
camelcase: OFF,
"no-console": ERROR,
"import/prefer-default-export": OFF,
"no-underscore-dangle": OFF,
"@typescript-eslint/camelcase": OFF,
},
settings: {
"import/resolver": {
node: {
extensions: [".ts", ".js"],
},
},
},
};
.eslintignore
.eslintrc.js
/node_modules
.cache/*
dist/*
.fixpackrc
{
"sortToTop": [
"name",
"version",
"author",
"private",
"main",
"scripts",
"dependencies",
"devDependencies",
"browser"
]
}
prettier.config.js
module.exports = {
printWidth: 120,
semi: false,
trailingComma: "all",
};
.gitignore
gitで管理するためignore入れてます。
.env
/node_modules
.DS_Store
credential.json
/.vscode
ロガーのディレクトリ名 > index.ts, type.ts
index.ts
import { createLogger, format, transports } from "winston"
import { CreateCustomLoggerData, CustomInfoLogger, CustomErrorLogger, InitLoggerReturn } from "./type"
const displayFormat = format.printf(({ level, message }) => {
return `${level}: ${message}`
})
const color = format.colorize({ all: true })
/**
* @typedef InitLogger
* @description ロガーのインスタンス生成
* @param filePath ログ実行時ファイルパス
* @returns InitLoggerReturn
*/
type InitLogger = (filePath: string) => InitLoggerReturn
export const initLogger: InitLogger = (filePath) => {
const createCustomLoggerData: CreateCustomLoggerData = (logLevel, message, data) => {
const logger = createLogger({
level: logLevel,
format: format.combine(color, displayFormat),
transports: [new transports.Console()],
})
return {
logger,
msg: JSON.stringify({
message,
data,
filePath,
}),
}
}
const infoLogger: CustomInfoLogger = (message, data) => {
const { logger, msg } = createCustomLoggerData("info", message, data)
logger.info(msg)
}
const errorLogger: CustomErrorLogger = (message, error) => {
const stringError = JSON.stringify(error, Object.getOwnPropertyNames(error))
const { logger, msg } = createCustomLoggerData("error", message, { error: stringError })
logger.error(msg)
}
return { infoLogger, errorLogger }
}
type.ts
import { Logger } from "winston"
/**
* @typedef CustomLogger
* @description カスタムロガーの型定義
* @param message ログメッセージ
* @param data ログ出力データ
*/
export type CustomInfoLogger = (message: string, data?: Record<string, unknown>) => void
export type CustomErrorLogger = (message: string, error: unknown) => void
/**
* @typedef InitLoggerReturn
* @description InitLoggerの戻り値の型
*/
export type InitLoggerReturn = {
infoLogger: CustomInfoLogger
errorLogger: CustomErrorLogger
}
/**
* @typedef CreateCustomLoggerDataReturn
* @description CreateCustomLoggerDataの戻り値の型
*/
export type CreateCustomLoggerDataReturn = { logger: Logger; msg: string }
/**
* winston準拠のログレベル
*/
type LogLevel = "error" | "warn" | "info" | "http" | "verbose" | "debug" | "silly"
/**
* @typedef CreateCustomLoggerData
* @description カスタムロガーと文字列化された出力メッセージ
* @param logLevel ログレベル
* @param message メインメッセージ
* @param data オプショナルデータ
*/
export type CreateCustomLoggerData = (
logLevel: LogLevel,
message: string,
data?: Record<string, unknown>,
) => CreateCustomLoggerDataReturn
使う時
下記のようにimportして使うことができる。(console使うとeslintエラー出るのでwinstonを使用)
import { initLogger } from "./shared/initLogger"
const { infoLogger, errorLogger } = initLogger("src/index.ts")
infoLogger("infoLoggerです")
errorLogger("errorLoggerです", { error: "失敗" })
最後に
yarn run ts-node-dev src/app.ts
でサーバーが立ち上がる。
package.jsonのscriptに下記の設定をすることでyarn dev
のコマンドで上記と同じように起動する。
"dev": "ts-node-dev src/app.ts"
Listening on port 8080
が表示されたら、別のターミナルで
curl http://localhost:8080
を叩くと「Hello World」が表示されます!
これで最低限の設定が完了し、実装に進められます。