TL;DR
あまり綺麗ではないですが、これで解決しました。
typeorm
コマンドを使用せず、直接ts-node
でtypeorm
を呼び出します。
$ ts-node ./node_modules/typeorm/cli.js migration:generate -n 'User'
NestJSを使用しているときにこのエラーに遭遇した場合は、ページ下部のormconfig.jsonの書き換えを試してみてください。
よくみたらドキュメントに書いてあった...
ドキュメントの推奨している方法だと、、、
STEP 1
ts-nodeをグローバルにインストール
$ npm install -g ts-node
STEP 2
package.json
にスクリプトを書き加える
"scripts": {
...
"typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js"
}
STEP 3
そしたら、こんな感じで実行する
--
は必要なので注意!
$ npm run typeorm migration:generate -- -n UserMigration
遭遇したエラー内容
$ npx typeorm init
$ npm install
$ typeorm migration:generate -n UserMigration
Error during migration generation:
/Users/michinosuke/archive/web-app/typeorm-playground/src/entity/role.ts:1
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm'
^^^^^^
SyntaxError: Cannot use import statement outside a module
at wrapSafe (internal/modules/cjs/loader.js:984:16)
at Module._compile (internal/modules/cjs/loader.js:1032:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
at Module.load (internal/modules/cjs/loader.js:933:32)
at Function.Module._load (internal/modules/cjs/loader.js:774:14)
at Module.require (internal/modules/cjs/loader.js:957:19)
at require (internal/modules/cjs/helpers.js:88:18)
at /usr/local/lib/node_modules/typeorm/util/DirectoryExportedClassesLoader.js:42:39
at Array.map (<anonymous>)
at Object.importClassesFromDirectories (/usr/local/lib/node_modules/typeorm/util/DirectoryExportedClassesLoader.js:42:10)
上のやつで解決しないとき
一応、他の可能性も考えてみます。
ts-nodeも直接パスを指定する
ts-node
がグローバルにインストールされていない場合は、これで解決するかも。
$ ./node_modules/.bin/ts-node ./node_modules/typeorm/cli.js migration:generate -n 'User'
環境変数をつける
-
TS_NODE_PROJECT
でtsconfig.json
のパスを渡します。 -
TS_NODE_TRANSPILE_ONLY
にtrue
を指定して、TypeScriptのtranspileModule
を使ってみる。
transpileModuleについての参考
TS_NODE_PROJECT=tsconfig.json TS_NODE_TRANSPILE_ONLY=true ./node_modules/.bin/ts-node ./node_modules/typeorm/cli.js migration:generate -n 'User'
tsconfig.jsonを書き換える
compilerOptions
のmodule
がcommonjs
以外になっているときは、commonjs
に変更してみてください。
{
"compilerOptions": {
"module": "commonjs"
}
}
さらに他の解決法
一旦TypeScriptで.ts
ファイルを.js
にトランスパイルしちゃう方法です。綺麗な解決策ではありませんが、ほぼ確実に解決できると思います。
もしあなたがNestJSなどを使用してこのエラーに遭遇している場合、下の手順3
のormconfig.json
の書き換えだけで解決する可能性が高いです。
手順1
tsconfig.json
のcompilerOptions
のskipLibCheck
にtrue
を指定します。
あまりいい方法じゃないんですが、これを指定しないとトランスパイルにエラーが大量に出ます。
参考: ERROR TS1086: An accessor cannot be declared in an ambient context
{
"compilerOptions": {
"skipLibCheck": true
}
}
手順2
トランスパイルします。
$ tsc
上のコマンドが打てなかったら、TypeScriptをグローバルインストールしてください。
$ npm i -g typescript
実行できたら、プロジェクトルートに`build`ディレクトリが作成されて、`js`ファイルがたくさん入ってるはずです。
#### 手順3
`ormconfig.json`を以下のように書き換えます。
* `src/` → `build/`
* `.ts` → `.js`
Before
```json
{
"type": "sqlite",
"database": "database.sqlite",
"synchronize": true,
"logging": false,
"entities": [
"src/entity/**/*.ts"
],
"migrations": [
"src/migration/**/*.ts"
],
"subscribers": [
"src/subscriber/**/*.ts"
],
"cli": {
"entitiesDir": "src/entity",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}
After
{
"type": "sqlite",
"database": "database.sqlite",
"synchronize": true,
"logging": false,
"entities": [
"build/entity/**/*.js"
],
"migrations": [
"build/migration/**/*.js"
],
"subscribers": [
"build/subscriber/**/*.js"
],
"cli": {
"entitiesDir": "build/entity",
"migrationsDir": "build/migration",
"subscribersDir": "build/subscriber"
}
}
手順4
node
でtypeorm
を呼び出します。
$ node ./node_modules/typeorm/cli.js migration:generate -n 'User'