【NodeJS】TypeScriptでCSVを読み込んで処理する

Node.js

1. 概要

前回はCrawleeを使ってウェブページをスクレイピングする内容でした。今回はCSVを読み込んで処理する内容になります。

対象としては開発を1年程やってて自分で最初から開発してみたい方になります。そのため細かい用語などの説明はしません。

2. nodeのインストール

こちらを参考

3. プロジェクトを作成

mkdir testing
cd testing
npm init
npm i -D typescript @types/node ts-node nodemon dotenv
npx tsc --init

4. 必要なライブラリをインストール

npm i csv-parser

5. ソースコード

5-1. package.json

{
  "name": "testing",
  "version": "1.0.0",
  "description": "",
  "license": "ISC",
  "author": "",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "dev": "tsc && NODE_ENV=dev node dist/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "@types/node": "^22.15.3",
    "dotenv": "^16.5.0",
    "nodemon": "^3.1.10",
    "ts-node": "^10.9.2",
    "typescript": "^5.8.3"
  },
  "dependencies": {
    "csv-parser": "^3.2.0"
  }
}

5-2. tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "verbatimModuleSyntax": true,
    "esModuleInterop": true,
    "strict": true,
    "outDir": "dist"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

5-3. .env.local

MY_MSG=Hello

5-4. data/user_list.csv

id,name
123,hoge
456,fuga
789,piyo

5-5. src/env.ts

import dotenv from "dotenv";
import { fileURLToPath } from "url";
import path from "path";

export const __dirname = path.dirname(fileURLToPath(import.meta.url));

export const loadEnv = async () => {
  if (process.env.NODE_ENV === "dev") {
    console.log(`This is dev environment.`);
    dotenv.config({ path: [".env.local"] });
  }
};

5-6. src/definitions.ts

export type CsvData = {
  id: number;
  name: string;
};

5-7. src/utils.ts

import { promises, constants } from "fs";

const fileExists = async (filePath: string): Promise<boolean> => {
  try {
    await promises.access(filePath, constants.F_OK);
    return true;
  } catch (error) {
    return false;
  }
};

export { fileExists };

5-8. src/read-csv.ts

import fs from "fs";
import csv from "csv-parser";

const readCsv = async <T = any>(filePath: string): Promise<T[]> => {
  return new Promise((resolve, reject) => {
    const results: T[] = [];
    fs.createReadStream(filePath)
      .pipe(csv())
      .on("data", (data) => results.push(data as T))
      .on("end", () => resolve(results))
      .on("error", reject);
  });
};

export { readCsv };

5-9. src/handle-data.ts

import type { CsvData } from "./definitions.js";
import { readCsv } from "./read-csv.js";

const handleData = async ({ filePath }: { filePath: string }) => {
  const csvData: CsvData[] = await readCsv<CsvData>(filePath);
  for (const data of csvData) {
    const id: number = data.id;
    const name: string = data.name;
    console.log(`ID: ${id}, NAME: ${name}`);
  }
};

export { handleData };

5-10. src/index.ts

import { loadEnv, __dirname } from "./env.js";
import path from "path";
import { handleData } from "./handle-data.js";
import { fileExists } from "./utils.js";

const run = async () => {
  let filePath: string = "";
  try {
    filePath = path.join(__dirname, "../data/user_list.csv");
    if (!(await fileExists(filePath))) {
      console.error(`File Not Found:${filePath}`);
      return;
    }
  } catch (error) {
    console.error(`CSV Load Error: `, error);
    throw error;
  }
  try {
    await handleData({ filePath });
  } catch (error) {
    console.error(`CSV Handle Error: `, error);
    throw error;
  }
};

const main = async () => {
  await loadEnv();
  console.log(`MY_MSG: ${process.env.MY_MSG}`);
  await run();
};

await main().catch((err) => {
  console.error(err);
  process.exit(1);
});

6. 実行

npm run dev
> testing@1.0.0 dev
> tsc && NODE_ENV=dev node dist/index.js

This is dev environment.
MY_MSG: Hello
ID: 123, NAME: hoge
ID: 456, NAME: fuga
ID: 789, NAME: piyo

7. ディレクトリの構造

.
├── .env.local
├── data
│   └── user_list.csv
├── dist
│   ├── definitions.js
│   ├── env.js
│   ├── handle-data.js
│   ├── index.js
│   ├── read-csv.js
│   └── utils.js
├── package-lock.json
├── package.json
├── src
│   ├── definitions.ts
│   ├── env.ts
│   ├── handle-data.ts
│   ├── index.ts
│   ├── read-csv.ts
│   └── utils.ts
└── tsconfig.json

3 directories, 17 files

8. 備考

今回はCSVを読み込んで処理する内容でした。

9. 参考

投稿者プロフィール

Sondon
開発好きなシステムエンジニアです。
卓球にハマってます。

関連記事

  1. Node.jsバージョン管理ツールについて調べてみる

  2. Node.js

    【NodeJS】自作MCPサーバー with Gemini CLI

  3. Node.js

    【NodeJS】Geminiを使った画像生成(Nano Banana)…

  4. Node.js

    【NodeJS】Crawleeを使ってみる(Scraping with…

  5. Node.js

    【NodeJS】PrismaやTypeScript、MySQLを使って…

  6. 【新米エンジニア学習記録②】TypeScriptの導入

最近の記事

制作実績一覧

  1. Checkeys