nodejs(javascript)で書かれたプロジェクトに、typescriptを導入してjavascript(commonjs)とtypescriptを併用して運用できるようにする手順をまとめました。
段階的にtsに移行していくなどの用途で使えるなと思い、記事にしてみました。
プロジェクトはeslintやprettierなどが適用されていて、nodemonを使って開発をしているとします。
まずは必要なライブラリをインストールします。
1. ライブラリのインストール
typescript関係
$ npm i -D typescript ts-node tslib
node-devを使っている人は ts-node-dev
もインストールしなきゃいけないかもしれないです。
$ npm i -D ts-node-dev
ts-nodeも、環境ではグローバルでインストールした方がいいかもしれないです。
$ npm install -g ts-node typescript
eslint関係
$ npm i -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser
2. .eslint.jsの編集
parserをtypescriptに。 また、rulesでjavascript(commonjs)と併用できるようにする設定を追記します。
plugins: ["@typescript-eslint"],
extends: [
"eslint:recommended",
"plugin:prettier/recommended",
"plugin:@typescript-eslint/recommended",
],
parserOptions: {
parser: "@typescript-eslint/parser",
ecmaVersion: 2021,
sourceType: "module",
},
rules: {
// jsとts併用のため設定
"@typescript-eslint/no-var-requires": "off",
}
3. nodemon.jsonの編集
ts-nodeで実行するようにします。
{
"watch": ["src/*", "*.js"],
"ext": "ts,js",
"exec": "ts-node"
}
4. package.jsonのscriptsの編集
node
で動かしている部分をts-node
に変更します。
node-dev
を使っている人は、合わせてts-node-dev
に変更します。
"scripts": {
"start": "ts-node app.js",
"watch": "ts-node-dev app.js"
}
5. tsconfig.jsonの編集
こちらにも、javascriptと併用できるようにするための設定を追記します。 一例ですが、このような感じになります。
{
"compilerOptions": {
"target": "es6",
"module": "CommonJS",
"strict": true,
"moduleResolution": "node",
"skipLibCheck": true,
"sourceMap": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"types": [
"node"
],
"lib": [
"es6"
],
// jsと共存するために必要
"checkJs": false,
"allowJs": true,
"declaration": false,
// 型チェック
"noImplicitAny": false,
"noImplicitReturns": false,
"noImplicitThis": false,
"noUnusedLocals": true,
"strictNullChecks": false,
"strictFunctionTypes": false,
"strictBindCallApply": false,
"strictPropertyInitialization": false
},
"ts-node": {
"transpileOnly": true
},
"include": [
"**/*.js",
"**/*.json",
"src/**/*.ts",
"tests/**/*.ts",
],
"exclude": [
"node_modules"
]
}
動作確認
以下のようなファイルを作成します。 js, ts相互に参照して扱うことができるか試していきます。
.
├── js-module.js
├── js-test.js
├── ts-module.ts
└── ts-test.ts
ts-module.ts
export default class TsModule {
constructor() {
console.log('TsModule constructor()')
}
public readTsModule() {
console.log('TsModule readTsModule()')
return 'read ts module text'
}
}
module.exports.TsModule = TsModule
module.exports.TsModule = TsModule
の記載は、tsだけなら必要ないのですが、jsで扱えるようにするには必要となります。
js-module.js
module.exports.readTest = () => {
console.log('execute js-module.js readTest()')
return 'read text'
}
ts-test.ts
import TsModule from './ts-module'
const { readTest } = require('./js-module')
// tsの読み込みテスト
const tsModule = new TsModule()
tsModule.readTsModule()
// jsの読み込みテスト
console.log(readTest())
js-test.js
const { TsModule } = require('./ts-module')
const { readTest } = require('./js-module')
// tsの読み込みテスト
const tsModule = new TsModule()
console.log(tsModule.readTsModule())
// jsの読み込みテスト
console.log(readTest())
では、実際にコマンドを実行して確認します。
$ ts-node js-test.js
TsModule constructor()
TsModule readTsModule()
read ts module text
execute js-module.js readTest()
read text
$ ts-node ts-test.ts
TsModule constructor()
TsModule readTsModule()
execute js-module.js readTest()
read text
js, ts相互に参照しあえることが確認できました。