#ts-nodeでESModulesを使う方法
NodeJSのバージョンが20で正常に動作しない場合はバージョン18を使う。 また、ts-nodeの代わりにswc-nodeを使うことができます。
#設定
下記の設定をします。
package.json
に"type": "module"
を加えます。tsconfig.json
のcompilerOptions.module
を"NodeNext"
にします。tsconfig.json
のts-node
を次のようにします。
{
...
"ts-node": {
"esm": true,
"require": ["tsconfig-paths/register"]
},
...
}
tsconfig-pathsをインストールします。 (しない場合、
CustomError: Cannot find module
のエラーが発生します。)importする際にpathに
.js
を付けます。 (例:import { createTitle } from './utils.js'
)package.json
に下記のような処理を実行する設定を追加します。
{
...
"scripts": {
"execute": "ts-node scripts/index.ts"
},
...
}
Native ECMAScript modules
paths and baseUrl
#tsconfig.jsonの例
{
"compilerOptions": {
"target": "ESNext",
"module": "NodeNext",
"allowJs": true,
"strict": true,
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"baseUrl": "./",
"skipLibCheck": true,
"typeRoots": ["node_modules/@types"],
"sourceMap": false
},
"ts-node": {
"esm": true,
"require": ["tsconfig-paths/register"]
},
"include": [
"./scripts/**/*"
]
}
#ESLint
typescript-eslintを使います。設定ファイルの拡張子を.cjs
にします。(例: .eslintrc.cjs
)
これをしない場合、Error [ERR_REQUIRE_ESM]
が発生します。
#Jest
package.jsonのscripts
を以下のようにします。
{
...
"scripts": {
"test": "NODE_OPTIONS=--experimental-vm-modules jest",
},
...
}
モックでのimport処理を以下のように変更します。
変更前
import { readFile } from 'node:fs/promises'
jest.mock('node:fs/promises')
import { createTitle } from './utils.js'
変更後
import { jest } from '@jest/globals'
jest.unstable_mockModule('node:fs/promises', () => ({ readFile: jest.fn() }))
const { readFile } = await import ('node:fs/promises')
const { createTitle } = await import('./utils.js')
#@swc/jest
jest、@types/jest、@swc/core、@swc/jestをインストールします。
設定ファイルの拡張子を.cjs
にします。(例: jest.config.cjs
)
#jest.config.cjsの例
module.exports = {
roots: ['<rootDir>/scripts'],
testMatch: ['**/*.test.ts'],
extensionsToTreatAsEsm: ['.ts', '.tsx'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
transform: {
'^.+\\.ts$': [
'@swc/jest',
],
},
}
#ts-jest
jest、@types/jest、ts-jestをインストールします。
設定ファイルはこれを参考にします。
設定ファイルの拡張子を.cjs
にします。(例: jest.config.cjs
)
#jest.config.cjsの例
module.exports = {
roots: ['<rootDir>/scripts'],
testMatch: ['**/*.test.ts'],
extensionsToTreatAsEsm: ['.ts', '.tsx'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
transform: {
'^.+\\.tsx?$': [
'ts-jest',
{
useESM: true,
},
],
},
}
#VSCode
VSCodeでdebugするには.vscode/launch.json
のruntimeExecutableに${workspaceFolder}/node_modules/.bin/ts-node
をセットします。
#.vscode/launch.jsonの例
{
"version": "2.0.0",
"configurations": [
{
"name": "ts-node",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/ts-node",
"args": [
"${workspaceFolder}/scripts/index.ts"
]
}
]
}