node index.ts したら `SyntaxError: Cannot use import statement outside a module` と怒られてハマった話

Webアプリ開発

環境

  • OS: Windows 10 Home
  • WSL2
    • ディストリビューション: Ubuntu20.04
  • node.js と npm はインストール済み
    • node.js: v16.15.1
    • npm: 8.12.1

はじめに

一応解決しましたが、話が長くなるので、もしかしたら蛇足な内容を含むかもしれません。ご了承下さい。

いろいろあった手順備忘録

起きたこと1

node + express + typescript で作ったチュートリアル的な HelloWorld プロジェクトを git からクローンして node index.ts を実行するとエラーになりました。

$ node index.ts
(node:883) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/home/xxxxxxx/index.ts:1
import express from 'express';
^^^^^^

SyntaxError: Cannot use import statement outside a module

やったこと1

ググってみた解決策したとして、 package.jsontype:module を追加しました。

{
  "type": "module", // ←これを追加 ★
  "name": "xxxx",
  "version": "1.0.0",
  "description": "",
  "main": "index.ts",
  "scripts": {
    ...
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    ...
  },
  "devDependencies": {
    ...
  }
}

起きたこと2

上記の対応をして、node index.ts を実行すると今度は別のエラーになりました。

$ node index.ts
node:internal/errors:465
    ErrorCaptureStackTrace(err);
    ^

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /home/xxxxxx/index.ts

よくわかりませんが、.ts ファイルが認識できていないっぽい・・・?

やったこと2

ts-nodeでESModulesのファイルを実行する

ググると、↑がヒットしましたので、こちらを参考にさせて頂きました。

yarn node --loader ts-node/esm sample.ts を実行せよとのことですが、 yarn も ts-node も入れてなかったので、まずその準備をしました。

# ts-node のインストール
$ sudo npm install -g ts-node

added 19 packages, and audited 20 packages in 4s

found 0 vulnerabilities

# これはやったけど、いらないかもしれない(ローカルに入れる必要はないはず)
$ npm install ts-node --save

added 18 packages, removed 12 packages, and audited 293 packages in 4s

26 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

# yarn のインストール
$ sudo npm i -g yarn

added 1 package, and audited 2 packages in 1s

found 0 vulnerabilities

起きたこと3

yarn node --loader ts-node/esm index.ts をやってみましたが、結果はうまくいきませんでした。

$ yarn node --loader ts-node/esm index.ts
yarn node v1.22.19
(node:3091) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
ReferenceError: exports is not defined in ES module scope

やったこと3

ググってみると、tsconfig.json"module": "commonjs" 犯人説が濃厚っぽかったのですが、
自分の環境には tsconfig.json がありませんでした。

そもそも typescript 自体インストールしていなかったので、インストールして tsconfig.json を作りました。

# typescript のインストール
$ sudo npm i -g typescript 

added 1 package, and audited 2 packages in 2s

found 0 vulnerabilities

# tsconfig.json の作成
$ tsc --init

Created a new tsconfig.json with:                                                                                       
                                                                                                                     TS 
  target: es2016
  module: commonjs
  strict: true
  esModuleInterop: true
  skipLibCheck: true
  forceConsistentCasingInFileNames: true

そして、tsconfig.json を以下のように変更しました。

{
  "compilerOptions": {
    /* 省略 */

    /* Modules */
    "module": "es2015",     // ←★ commonjs から es2015 に変更する

    /* 省略 */
  }
}

解決

これにて、以下のように実行できるようになりました。

$ yarn node --loader ts-node/esm index.ts
yarn node v1.22.19
(node:3528) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)

もう一回起きたら、次は解決できないかも・・・
トライアンドエラー感でツライ・・・

コメント

タイトルとURLをコピーしました