前回の「GitHub Actionsへの移行」はいかがだったでしょうか、CircleCIも非常に優れたサービスですが、GitHubとGitHub Actionsのシナジーはやはり素晴らしいものがあるなと常々思っています。
すっかり秋になり、お鍋が恋しい季節になりました。どうもお久しぶりです、GMOアドマーケティング GMOSSP開発担当の@KazuakiMです。 GMOSSPでは最近、CircleCIからGitHub Actionsに移行した事から、その情報をお伝えできたらと思います。 GMOSSPでは配信をPHP、集計などをGo言語で実装している事から、 今回はPHPのGitHub Actionsの実装例となります。そもそもGitHub Actionsとは?継続的インテグレーション/継続的デリバリー(CI/CD)をGitHubが提供する環境内で実行できるサービスとなります。GitHub Actionsを使用すると、ワールドクラ...
2022年から本格的にTypeScriptに触りはじめましたので、
今回はTypeScriptの入門記事を書きたいと思います。
TypeScirptとはAltJS(Alternative JavaScript)の一つで、
Microsoftによって開発されたOSSとなります。
TypeScriptはNode.jsをサポートしている事から
今回はNode.jsのインストール手順からご紹介します。
nvm
Node.jsのインストール手順のご紹介とご紹介しましたが、最初にインストールするのはNode.jsのバージョン管理ツールのインストールとなります。
nvmは65,300 Star超えのNode.jsのバージョン管理ツールとして有名です。
nvm インストール
1 |
brew install nvm |
nvm 設定
常に利用できるように.zshrcに設定を追加します。
1 |
[ -s "$(brew --prefix nvm)/nvm.sh" ] && \. "$(brew --prefix nvm)/nvm.sh" >> .zshrc |
nvm バージョン確認
nvmの設定ができましたら、バージョン確認を行います。
1 2 |
nvm --version 0.39.3 |
Node.js
nvmがインストールできましたので、次にNode.jsをインストールします。Node.js インストール
.nvmrcでバージョンを指定します。今回はLTSの18を採用しました。
1 2 3 |
cat .nvmrc 18.14.2 |
インストールバージョンに問題ない事を確認した上でインストールを実行します。
1 |
nvm install |
Node.js バージョン確認
Node.jsのバージョン確認を行います。
1 2 |
node --version v18.14.2 |
TypeScript
本記事メインであるTypeScriptの設定を行います。TypeScript インストール
まずはTypeScript インストールです。
1 |
npm install --save-dev typescript |
TypeScriptがインストールできたら各種セットアップをしていきます。
私がTypeScriptを学んでいた際にはコードを書きつつ、よりよい設定を見つけたタイミングで都度、追加をしていったため、多少手順が違う部分があるかもしれません。
TypeScript 設定ファイル作成
tsconfig.jsonでTypeScriptの設定を行います。今回はTypeScriptに設定できるルールにおいて、公式が提供する厳格な設定を採用します。厳格な設定にする事でTypeScriptの期待したコードでない場合にはエラーとなるため、TypeScriptのコードの書き方について、学びが深まります。
1 |
npm install --save-dev @tsconfig/strictest |
1 2 3 4 5 |
cat tsconfig.json { "extends": "@tsconfig/strictest/tsconfig.json" } |
TypeScript ビルド実行
GMOSSPではWebpackを利用したビルド環境を構築していますが、今回はtscを利用したコンパイルを実施します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
cat src/sample.ts "use strict"; const test: number = 1; console.log(test); const test2: number = 1; //eslint-disable-line @typescript-eslint/no-inferrable-types console.log(test2); /* eslint-disable @typescript-eslint/no-inferrable-types */ const test3: number = 1; console.log(test3); /* eslint-enable */ const test4: number = 1; console.log(test4); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
tsc src/* cat src/sample.js "use strict"; var test = 1; console.log(test); var test2 = 1; //eslint-disable-line @typescript-eslint/no-inferrable-types console.log(test2); /* eslint-disable @typescript-eslint/no-inferrable-types */ var test3 = 1; console.log(test3); /* eslint-enable */ var test4 = 1; console.log(test4); |
TypetScript alias 設定
コマンドのオプションなどを覚えておくのは大変なため、必要に応じてaliasを設定します。
1 2 3 |
"scripts": { + "ts": "tsc src/*" }, |
ESLint
TypeScriptの設定を終えましたら、Lintツールによるコードのチェックの設定を行っていきます。ESLint インストール
1 |
npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint |
ESLint 設定
ESLintの設定は公式おすすめの設定とします。個人的にはpackage.jsonに設定するのが好きなため、packege.jsonに設定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
"devDependencies": { "eslint": "8.34.0", "typescript": "4.9.5" + }, + "eslintConfig": { + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "root": true + } |
ESLint 実行
サンプルコードにESLintを適用してみます。ESLintを適用したくないコードにはdisableコメントアウトを追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
cat src/sample.ts "use strict"; const test: number = 1; console.log(test); const test2: number = 1; //eslint-disable-line @typescript-eslint/no-inferrable-types console.log(test2); /* eslint-disable @typescript-eslint/no-inferrable-types */ const test3: number = 1; console.log(test3); /* eslint-enable */ const test4: number = 1; console.log(test4); |
1 2 3 4 5 6 7 8 |
npx eslint . /blogsample/src/sample.ts 3:7 error Type number trivially inferred from a number literal, remove type annotation @typescript-eslint/no-inferrable-types 14:7 error Type number trivially inferred from a number literal, remove type annotation @typescript-eslint/no-inferrable-types ✖ 2 problems (2 errors, 0 warnings) 2 errors and 0 warnings potentially fixable with the `--fix` option. |
続いて、今回は –fix で解決する問題だとアラート文にありますので、再度実行してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
npx eslint --fix . cat src/sample.ts const test = 1; console.log(test); const test2: number = 1; //eslint-disable-line @typescript-eslint/no-inferrable-types console.log(test2); /* eslint-disable @typescript-eslint/no-inferrable-types */ const test3: number = 1; console.log(test3); /* eslint-enable */ const test4 = 1; console.log(test4); |
ESLint alias 設定
コマンドのオプションなどを覚えておくのは大変なため、必要に応じてaliasを設定します。
1 2 3 4 |
"scripts": { + "lintdry": "eslint ./src/", + "lint": "eslint --fix ./src/" }, |
1 2 3 |
npm run lint > blogsample@1.0.0 lintfix > eslint --fix ./src |
続いてESLintの設定が終わりましたので、Prettierの設定を進めていきます。
Prettier
コードの整形に特化したライブラリとなります。Prettier インストール
1 |
npm install --save-dev prettier |
Prettier 設定
.prettierignore の適用対象外指定ファイル生成
1 2 3 4 5 |
cat .prettierignore # Ignore artifacts: build coverage |
1 2 3 |
cat .prettierrc.json {} |
Prettier 実行
サンプルコードにPrettierを適用してみます。今回もPrettierを適用したくないコードにコメントアウトを追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
cat src/sample2.ts matrix( 1, 0, 0, 0, 1, 0, 0, 0, 1 ) // prettier-ignore matrix( 1, 0, 0, 0, 1, 0, 0, 0, 1 ) |
1 2 3 4 5 6 7 8 9 10 11 12 |
npx prettier --write . cat src/sample2.ts matrix(1, 0, 0, 0, 1, 0, 0, 0, 1); // prettier-ignore matrix( 1, 0, 0, 0, 1, 0, 0, 0, 1 ) |
Prettier alias 設定
コマンドのオプションなどを覚えておくのは大変なため、必要に応じてaliasを設定します。
1 2 3 4 5 |
"scripts": { "lintdry": "eslint ./src/", "lint": "eslint --fix ./src/", + "fmt": "prettier --write ." }, |
1 2 3 4 5 6 7 8 |
npm run fmt > blogsample@1.0.0 prettier > prettier --write . package-lock.json 90ms package.json 3ms src/sample.ts 158ms src/sample2.ts 7ms |
Jest
ここまでは一度設定する事で、ツールの再チューニングなどはほぼ発生しなくなるため、そこまでメンテナンスコストは発生しませんが、Jestによるテストコード構築はアプリを開発すると同時に常にメンテナンスし続けるものとなります。
まだまだ学んでいるさなかのため、お作法がイケてないかもしれません。
Jest インストール
1 |
npm install --save-dev @jest/globals @types/jest @types/jsdom jest-environment-jsdom ts-jest jest |
Jest 設定
Jestの設定を行っていきます。個人的にはpackage.jsonに設定するのが好きなため、packege.jsonに設定しています。
GitHub Actionsの実行結果をアノテーションで通知してくれます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
+ }, + "jest": { + "roots": [ + "src" + ], + "transform": { + "^.+\\.(ts|tsx)$": "ts-jest" + }, + "testEnvironment": "jsdom", + "reporters": [ + [ + "github-actions", + { + "silent": false + } + ], + "summary" + ] } |
Jest alias 設定
コマンドのオプションなどを覚えておくのは大変なため、必要に応じてaliasを設定します。
1 2 3 4 5 6 |
"scripts": { "lintdry": "eslint ./src/", "lint": "eslint --fix ./src/", "fmt": "prettier --write ." + "test": "jest --coverage --silent --watchAll", }, |
Jest 実行
Jestのテストコードについては絶賛学習中のため、今回は私が困っているコードについて1つ例をあげさせてもらいます。
ABTest()関数を実行した結果、”A Pattern”か”B Pattern”どちらかを出力する関数において、
いい感じのテストコードがかけず止むをえず、toContainを利用しています。
このコードのexpectとreceiveが感覚的には逆な印象です。分かる人は著者までご連絡をお待ちしています。
1 2 3 4 5 6 7 8 |
describe("sample", (): void => { test("sample AB test", (): void => { expect([ "A Pattern", "B Pattern" ]).toContain(ABTest()); }); }); |
GitHub Actions 環境構築
ここまでで入門したての私の環境構築は以上となります。続いて、GitHub Actionsの設定のご紹介となります。
GitHub Actionsは前回も記事にしましたが、非常に優れたCIツールとなります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# # Docs: https://github.com/marketplace/actions/setup-node-js-environment # name: TypeScript on: pull_request: branches: - master paths: - '**.ts' push: branches: - master paths: - '**.ts' jobs: run: runs-on: ubuntu-latest strategy: fail-fast: true matrix: node-versions: [18] name: TypeScript ${{ matrix.node-versions }} steps: - name: Checkout uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-versions }} cache: 'npm' cache-dependency-path: tasks/package-lock.json - name: Install Package run: npm ci - name: TypeScript run: npm run ts - name: Jest run: npm run test - name: ESLint run: npm run lint - name: Prettier run: npm run fmt |
まとめ
TypeScriptは型付き言語で非常に扱いやすく、情報も充実している事から初学ではありましたが、滞りなく入門できました。
宣伝
『No.1サービスを目指して開発するフロントエンド』というテーマでGMO Developers Dayに登壇しました。チャンネル登録、いいねボタンお願いします。