8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【備忘録】Node.js×pnpm×TypeScript

Posted at

はじめに

Vue CLIやviteを利用すると設定ファイルを一通り用意してくれてしまうので、学習のためにイチから各種ライブラリを導入して作成してみた。
またpnpmも初めて使ってみた。

記事作成時点での最新情報を盛り込んだつもりだがNodeやTSまわりの技術は日進月歩なので古い(または古くなった)情報があったらすみません。

開発環境

  • macOS Ventura 13.1
  • Visual Studio Code 1.74.3
  • Node.js 18.13.0

事前準備

pnpm有効化

最近のNode.jsにはpnpmがバンドルされているので有効化だけすればよい。
※ドキュメントにはないが自分の環境ではsudoがないとPermission Deniedになった

sudo corepack enable

有効化確認&バージョン確認

pnpm -v

7.25.0

作成手順

プロジェクト定義

Nodeプロジェクト初期化

pnpm init

TypeScript導入

pnpm add typescript -D

有効化確認&バージョン確認

pnpm tsc -v

Version 4.9.4

tsconfig.json作成

雛形となるtsconfig.jsonを生成

pnpm tsc --init

参考サイトを参考に一部修正

tsconfig.json
  {
+   "include": ["src/**/*"],
    "compilerOptions": {
-     "target": "es2016",
+     "target": "es2022",

-     // "rootDir": "./",
+     "rootDir": "./src",

-     // "outDir": "./",
+     "outDir": "./dist",
    }
  }

この時点ではソースコードが見つからないためVSCodeがエラーを出してくるが気にしない。

Hello, world

Node標準ライブラリ型定義

確認のためNode標準ライブラリをimportしたいので型定義を落としておく。

pnpm add @types/node -D

サンプル実装

※後でコード整形する前提でちょっと汚く書いている

src/greet.ts
export const getHello = (name:string):string=>{
    return `Hello, ${name}!`
}
src/index.ts
import { version } from 'node:process' // Node標準ライブラリ
import { getHello } from './greet' // 自分のモジュール

console.log(version)
console.log(getHello('world'))

実行

コンパイル

tsconfig.jsonを利用してコンパイルを実行。

pnpm tsc --project ./tsconfig.json 

tsconfig.jsonに記述した通り、distディレクトリに出力される。

Node.js上で実行

node dist/index.js 

v18.13.0
Hello, world!

ts-node

いちいちコンパイル→実行の2段階は面倒なのでts-nodeを導入してtsファイルを直接実行する。

ts-node導入

pnpm add ts-node -D

導入確認&バージョン確認

pnpm ts-node -v

v10.9.1

スクリプト化

package.json
  {
    "scripts": {
+     "dev": "ts-node src/index.ts",
    }
  }

スクリプトを実行

pnpm run dev

> vsc-pnpm-ts-demo@1.0.0 dev /Users/kurukuruz/work/repo/vsc-pnpm-ts-demo
> ts-node src/index.ts

v18.13.0
Hello, world!

ESLint & Prettier

Prettier導入

pnpm add prettier -D

空の設定ファイルも作っておく。

echo {}> .prettierrc.json

ESLint導入

pnpm add eslint -D

対話型CLIを利用して設定を定義する。

pnpm eslint --init

✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · none
✔ Does your project use TypeScript? · Yes
✔ Where does your code run? · node
✔ What format do you want your config file to be in? · JSON
The config that you've selected requires the following dependencies:

@typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
✔ Would you like to install them now? · Yes
✔ Which package manager do you want to use? · pnpm

ESLint-Prettier連携

(記事作成時点の)最新はconfigを使うのが推奨らしい。

pnpm add eslint-config-prettier -D

extends末尾に追加

.eslintrc.json
  {
    "extends": [
-     "plugin:@typescript-eslint/recommended"
+     "plugin:@typescript-eslint/recommended",
+     "prettier"
    ],
  }

スクリプト化

有無を言わさず書き換えを伴うストロングスタイル。

package.json
  {
    "scripts": {
+     "lint": "eslint --fix src/ && prettier --write src/",
    }
  }

スクリプトを実行

pnpm run lint

今回は下記のように修正された。

  • 適切なスペース文字挿入
  • インデント幅調整
  • 末尾にセミコロン
    src/greet.ts
    - export const getHello = (name:string):string=>{
    -     return `Hello, ${name}!`
    - }
    + export const getHello = (name: string): string => {
    +   return `Hello, ${name}!`;
    + };
    
  • 文字列の囲いをダブルクォーテーション化
    src/index.ts
    - import { version } from 'node:process' // Node標準ライブラリ
    - import { getHello } from './greet' // 自分のモジュール
    + import { version } from "node:process"; // Node標準ライブラリ
    + import { getHello } from "./greet"; // 自分のモジュール
    
    - console.log(version)
    - console.log(getHello('world'))
    + console.log(version);
    + console.log(getHello("world"));
    

宗派は色々あると思うが、ここでは深く考えずデフォルトのままにしておく。

Jest

Jest導入

Jest本体だけでなく、TypeScriptで使用するためのライブラリも同時に追加

pnpm add jest ts-jest @types/jest -D

CLIを利用して設定ファイルを生成

pnpm ts-jest config:init

テストコードを作成

Jestにデフォルトでテストコードとみなされる__tests__ディレクトリ配下に作成する。

__tests__/greet.ts
import { getHello } from "../src/greet";

// @types/jestによりJest関連の関数(testなど)はimportなしで利用できる
test("hello hoge", () =>{
  expect(getHello("hoge")).toBe("Hello,hoge!") // ここはわざと失敗するようにしてる
});

スクリプト化

package.json
  {
    "scripts": {
-     "test": "echo \"Error: no test specified\" && exit 1"
+     "test": "jest"
    }
  }

スクリプトを実行

pnpm run test

スクリーンショット 2023-01-16 18.17.51.png

テストコードが実行され、ご丁寧に失敗箇所・理由を出力してくれることが確認できる。

成果物

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?